Menu
Coddy logo textTech

העברת מצביעים למבנים

חלק מהיחידה לוגיקה וזרימת תוכנית במסלול ה-C של Coddy. שיעור 47 מתוך 63.

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

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

התחביר של פונקציה שמקבלת מצביע למבנה הוא:

void functionName(struct StructureName *ptr) {
    // גוף הפונקציה המשתמש ב-ptr->member
}

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

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

challenge icon

אתגר

קל

צרו תוכנית C שמדגימה העברת מצביעים למבנים לפונקציות כדי לשנות נתונים ביעילות. התוכנית שלכם צריכה:

  1. להגדיר struct בשם BankAccount עם השדות הבאים:
    • מספר שלם accountNumber לאחסון מספר החשבון
    • מערך תווים ownerName בגודל 30 לאחסון שם בעל החשבון
    • מספר ממשי מסוג float בשם balance לאחסון יתרת החשבון
    • מספר שלם transactionCount לאחסון מספר העסקאות
  2. לכתוב פונקציה בשם depositMoney ש:
    • מקבלת פרמטרים של מצביע למבנה BankAccount וסכום מסוג float
    • מוסיפה את הסכום ליתרת החשבון באמצעות אופרטור החץ
    • מגדילה את מספר העסקאות ב-1
    • מדפיסה Deposit successful. New balance: [balance]
  3. לכתוב פונקציה בשם withdrawMoney ש:
    • מקבלת פרמטרים של מצביע למבנה BankAccount וסכום מסוג float
    • בודקת אם סכום המשיכה גדול מהיתרה הנוכחית
    • אם אין מספיק כספים, מדפיסה Insufficient funds. Current balance: [balance]
    • אם יש מספיק כספים, מחסירה את הסכום מהיתרה, מגדילה את מספר העסקאות ומדפיסה Withdrawal successful. New balance: [balance]
  4. לכתוב פונקציה בשם displayAccount ש:
    • מקבלת פרמטר של מצביע למבנה BankAccount
    • מדפיסה את פרטי החשבון בדיוק בפורמט הבא:
      • Account Information:
      • Account Number: [accountNumber]
      • Owner: [ownerName]
      • Balance: [balance]
      • Transactions: [transactionCount]
  5. בפונקציה main:
    • ליצור משתנה מסוג BankAccount בשם account
    • לקרוא מהקלט את מספר החשבון, שם הבעלים והיתרה ההתחלתית
    • להגדיר את מספר העסקאות ל-0
    • לקרוא ל-displayAccount כדי להציג את מצב החשבון ההתחלתי
    • לקרוא סכום הפקדה ולקרוא ל-depositMoney
    • לקרוא סכום משיכה ולקרוא ל-withdrawMoney
    • לקרוא ל-displayAccount כדי להציג את מצב החשבון הסופי

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

נסו בעצמכם

#include <stdio.h>
#include <string.h>

// TODO: הגדירו כאן את המבנה BankAccount

// TODO: כתבו כאן את הפונקציה depositMoney

// TODO: כתבו כאן את הפונקציה withdrawMoney

// TODO: כתבו כאן את הפונקציה displayAccount

int main() {
    // קראו קלט
    int accountNum;
    char ownerName[30];
    float initialBalance;
    float depositAmount;
    float withdrawAmount;
    
    scanf("%d", &accountNum);
    scanf("%s", ownerName);
    scanf("%f", &initialBalance);
    scanf("%f", &depositAmount);
    scanf("%f", &withdrawAmount);
    
    // TODO: צרו משתנה מסוג BankAccount ואתחלו אותו
    
    // TODO: קראו ל-displayAccount כדי להציג את המצב ההתחלתי
    
    // TODO: קראו ל-depositMoney עם סכום ההפקדה
    
    // TODO: קראו ל-withdrawMoney עם סכום המשיכה
    
    // TODO: קראו ל-displayAccount כדי להציג את המצב הסופי
    
    return 0;
}
quiz iconבחנו את עצמכם

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

כל השיעורים ביחידה לוגיקה וזרימת תוכנית

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