Menu
Coddy logo textTech

מצביעים למבנים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 20 מתוך 107.

בעבודה עם מבנים, לעיתים קרובות תשתמש במצביעים כדי להימנע מהעתקה של מבני נתונים גדולים וכדי לשנות את המבנה המקורי. מצביע למבנה מכיל את כתובת הזיכרון של מופע המבנה הזה.

אפשר ליצור מצביע למבנה באמצעות האופרטור & על מבנה קיים, או באמצעות שימוש ישיר באופרטור הכתובת עם מילולית של מבנה.

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Alice", Age: 30}
ptr := &p  // מצביע ל-struct קיים

// או ליצור ישירות
ptr2 := &Person{Name: "Bob", Age: 25}

Go מספקת קיצור דרך נוח לגישה לשדות של מבנה דרך מצביע. במקום לכתוב (*ptr).Name, אפשר פשוט לכתוב ptr.Name. Go מבטלת את ההפניה של המצביע באופן אוטומטי עבורך.

ptr := &Person{Name: "Alice", Age: 30}

// שניהם פועלים באותו אופן
fmt.Println((*ptr).Name)  // ביטול הפניה מפורש
fmt.Println(ptr.Name)     // ביטול הפניה אוטומטי

ביטול ההפניה האוטומטי הזה חל גם בעת שינוי שדות. שינויים דרך המצביע משפיעים על המבנה המקורי.

p := Person{Name: "Alice", Age: 30}
ptr := &p

ptr.Age = 31           // משנה את המקור
fmt.Println(p.Age)     // 31

מצביעים למבנים הם חיוניים בתבניות ה-OOP של Go. הם מאפשרים למתודות לשנות את מצב המקבל, מאפשרים להעביר מבנים גדולים לפונקציות ביעילות, ומהווים את הבסיס לבניית מבני נתונים מקושרים כמו עצים ורשימות.

challenge icon

אתגר

קל

בואו נבנה מערכת לניהול חשבונות בנק שתדגים כיצד מצביעים למבנים מאפשרים לך לשנות את הנתונים המקוריים ביעילות. תיצור חשבון שאפשר לעדכן באמצעות פעולות על מצביעים.

תארגן את הקוד שלך בשני קבצים:

  • account.go: הגדר מבנה BankAccount עם השדות Owner (מחרוזת), Balance (float64) ו-AccountNumber (מחרוזת). צור פונקציה בשם NewAccount שמקבלת שם של בעל החשבון ומספר חשבון כפרמטרים ומחזירה מצביע למבנה חדש מסוג BankAccount עם יתרת פתיחה של 0. צור גם פונקציה בשם Deposit שמקבלת מצביע *BankAccount וסכום, ואז מוסיפה את הסכום הזה ליתרת החשבון באמצעות המצביע.
  • main.go: קרא את פרטי החשבון מהקלט, צור חשבון באמצעות פונקציית הבנאי שלך (שמחזירה מצביע), בצע הפקדה באמצעות המצביע והצג את פרטי החשבון כדי לוודא שהיתרה השתנתה.

הקלטים הבאים יסופקו:

  • שורה 1: שם בעל החשבון
  • שורה 2: מספר חשבון
  • שורה 3: סכום ההפקדה (מספר עשרוני)

פורמט הפלט:

Account: [AccountNumber]
Owner: [Owner]
Balance: [Balance]

לדוגמה, עבור John Smith, ACC-12345 ו-500.50, הפלט שלך צריך להיות:

Account: ACC-12345
Owner: John Smith
Balance: 500.50

זכור שפונקציית NewAccount שלך צריכה להחזיר *BankAccount באמצעות האופרטור &, ושפונקציית Deposit יכולה לשנות את היתרה ישירות באמצעות המצביע, בעזרת ביטול ההפניה האוטומטי של Go (למשל, account.Balance במקום (*account).Balance).

נסו בעצמכם

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	
	// קרא את שם בעל החשבון
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)
	
	// קרא את מספר החשבון
	accountNumber, _ := reader.ReadString('\n')
	accountNumber = strings.TrimSpace(accountNumber)
	
	// קרא את סכום ההפקדה
	amountStr, _ := reader.ReadString('\n')
	amountStr = strings.TrimSpace(amountStr)
	amount, _ := strconv.ParseFloat(amountStr, 64)
	
	// TODO: צור חשבון חדש באמצעות הפונקציה NewAccount (מחזירה מצביע)
	
	// TODO: בצע הפקדה באמצעות הפונקציה Deposit עם המצביע לחשבון
	
	// TODO: הדפס את פרטי החשבון בפורמט הנדרש:
	// חשבון: [AccountNumber]
	// בעל החשבון: [Owner]
	// יתרה: [Balance]
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Go אונליין