לדלג לתוכן

3.6 סטראקטים הרצאה

הStruct, Union ודומיהם – שמירה מסודרת של משתנים

מבוא

עד עכשיו שמרנו ערכים במשתנים בודדים – int, char, float וכו'.
אבל מה קורה אם נרצה לשמור כמה משתנים שקשורים זה לזה, ביחד?
למשל – אם נרצה לייצג תלמיד, שכולל:

  • שם (מחרוזת)
  • גיל (מספר)
  • ממוצע ציונים (שבר עשרוני)

לשמור את כל אלו במשתנים נפרדים זה מסורבל – אז שפת C נותנת לנו דרך לקבץ משתנים יחד תחת מבנה אחד:
קוראים לזה struct.


הStruct – מבנה נתונים מותאם אישית

איך מגדירים Struct?

struct Student {
    char* name;
    int age;
    float avg_grade;
};

הגדרנו טיפוס חדש בשם struct Student – שמכיל 3 שדות.

איך יוצרים משתנה מסוג Struct?

struct Student s1;

עכשיו s1 הוא משתנה שמכיל את כל השדות האלו – שם, גיל וממוצע.

איך ניגשים לשדות?

s1.name = "Amit";
s1.age = 21;
s1.avg_grade = 87.5;

איך מדפיסים את הערכים?

printf("Name: %s\n", s1.name);
printf("Age: %d\n", s1.age);
printf("Average: %.2f\n", s1.avg_grade);

קיצור שם struct

במקום כל פעם לכתוב struct Student, אפשר לקצר:

typedef struct Student {
    char* name;
    int age;
    float avg_grade;
} Student;

עכשיו נוכל פשוט לכתוב:

Student s1;

הStruct בתוך Struct

אפשר גם לשלב מבנים. לדוגמה:

typedef struct Date {
    int day;
    int month;
    int year;
} Date;

typedef struct Person {
    char* name;
    int age;
    Date birth_date;
} Person;

ככה נוכל לעשות:

Person p1;
p1.birth_date.day = 27;

העתקת struct

Student s1 = {"Amit", 20, 90.0};
Student s2 = s1; // העתקת כל השדות

printf("%s\n", s2.name); // מדפיס "Amit"

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


Union – זיכרון משותף

הunion זה כמו struct, אבל כל השדות משתמשים באותו מקום בזיכרון.

למה זה טוב?

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

union Data {
    int i;
    float f;
    char* str;
};

שימוש:

union Data d;
d.i = 42;
printf("%d\n", d.i);

d.f = 3.14; // עכשיו i כבר לא תקף
printf("%f\n", d.f);

הבדל מהותי:

Struct Union
כל שדה מקבל מקום נפרד כל השדות חולקים את אותו המקום
תופס סכום הזיכרון של כל השדות תופס גודל של השדה הכי גדול

הsizeof ו־Padding

ב־struct, הגודל הכולל הוא סכום של השדות – אבל עם ריווחים פנימיים (padding) כדי ליישר אותם לזיכרון.

typedef struct {
    char a;
    int b;
} Example;

יכול להיות שה־sizeof(Example) יהיה 8 ולא 5 – בגלל שה־int צריך להתחיל בכתובת זוגית או מיושרת.


דוגמה מלאה:

#include <stdio.h>

typedef struct {
    char* name;
    int age;
} Student;

int main() {
    Student s;
    s.name = "Shir";
    s.age = 23;

    printf("Student: %s, Age: %d\n", s.name, s.age);

    return 0;
}

סיכום

  • הstruct מאפשר לנו לארגן משתנים שקשורים זה לזה בתוך מבנה אחד
  • הunion שומר משתנים על אותו תא זיכרון – שימושי כשיש רק שדה אחד פעיל
  • אפשר להעתיק struct אחד לאחר
  • ניגשים לשדות עם .
  • ניתן לקנן struct-ים