690 likes | 951 Views
מל"מ, הרצאה מס' 11 מבנים. הרצאה מס' 11 – מבנים. הגדרה, דוגמאות, ארגון וגישה , אתחול, קלט ופלט, מערך מבנים, סיכום ביניים, מבנה מוכל במבנה, מצביע למבנה וגישה למבנה דרך מצביע, העברת מבנה כפרמטר לפונקציה, העברת מצביע למבנה כפרמטר לפונקציה, מבנים והקצאה דינאמית , סיכום Q&A.
E N D
הרצאה מס' 11 – מבנים • הגדרה, • דוגמאות, ארגון וגישה , • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית , • סיכום Q&A. מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
מבנה – לשם מה? • מערך הוא אוסף איברים הומוגני: double rates[3] = {1.1, 2.2, 3.3}; /* all doubles */ • מה אם נרצה לשמור מידע על 50 סטודנטים, כאשר לכל אחד אנו שומרים כמה נתונים שונים: char name[20]; char major[6]; char *pswd; int year; float gpa;/*Grade Point Average */ • האם נבנה 50 מערכים? 5 מערכים? מל"מ – מבוא למדעי המחשב
הגדרה ... • מבנה, structure, הוא טיפוס משתנה חדש,שמאגד תחת שם אחד, אוסף של משתנים(אחד או יותר, אפשרי מסוגים שונים), • הכרזה על מבנה היא הכרזה על טיפוס חדש ולא על משתנה חדש, • יצירת משתנה מהטיפוס החדש, נעשית ע"י הכרזה של משתנה מטיפוס המבנה שהגדרנו. מל"מ – מבוא למדעי המחשב
הגדרה (המשך)... • הגדרת המבנה נעשית ע"י הכרזה עליו ועל חלקיו, • ניתן להשתמש בכל טיפוס שמוכר ברגע ההגדרה, • הגדרת המבנה נעשית במיקום שכל חלקי התוכנה האמורים להשתמש בו – יכירו אותו, struct Std_Rec { char name[20]; char major[6]; char *pswd; int year; float gpa; }; שם הסוג החדש שם חדש: שם סוג המבנה מילה שמורה מל"מ – מבוא למדעי המחשב
הגדרה (המשך) ... • כל משתנה שמאוגד במבנה, נקרא "שדה",או "משתתף" במבנה, (באנגלית – member), • מבנה מאפשר לנו יצירת טיפוסים חדשים – לפי דרישה, • תחביר הגדרת המבנה: struct name { type_a name_a; … type_n name_n; }; מל"מ – מבוא למדעי המחשב
הגדרה (המשך) • הגדרת מבנה אינה מקצה מקום בזיכרון, • זו בעצם הגדרת סוג חדש של משתנה,ששמו הוא struct name , • מקום מסוג זה יוקצה רק עם הגדרת משתנה מסוג המבנה, • האם במבנה אפשר גם לשים קוד? • שאלה מצוינת! • לא. רק נתונים. מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה , • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
שם הסוג החדש student: 34 בתים דוגמא struct Std_Rec... • structStd_Rec{ • char name[20]; • char major[6]; char *pswd; • int year; • float gpa; • }; • הגדרת משתנה מסוג זה: • struct Std_Rec student; עכשיו נקבל משתנה מסוג Std_Recבשם student מל"מ – מבוא למדעי המחשב
std1: std2: 34 בתים 34 בתים דוגמא struct Std_Rec (המשך) ... • או: • struct Std_Rec { • char name[20]; • char major[6]; • char *pswd; • int year; • float gpa; • } std1, std2; הגדרת המבנה, ושני משתנים מהסוג שלו – כל זה במשפט אחד! מל"מ – מבוא למדעי המחשב
דוגמא struct Std_Rec (המשך) ... • או: • typedef struct Std_Rec { • char name[20]; • char major[6]; • char *pswd; • int year; • float gpa; • } std_rec; • std_rec std1, std2; ניצול משפט typedefלהגדרת המבנה... ושם קיצור אבל כדי להגדיר משתנים נצטרך משפט נוסף. מל"מ – מבוא למדעי המחשב
דוגמא struct Std_Rec (המשך) ... • או: • typedef struct{ • char name[20]; • char major[6]; • char *pswd; • int year; • float gpa; • } std_rec; • std_rec std1, std2; ניצול משפט typedefלהגדרת המבנה (ללא שם...) ושם קיצור אבל כדי להגדיר משתנים נצטרך משפט נוסף. מל"מ – מבוא למדעי המחשב
STUDENT’S – ארגון בזיכרון Std_Recמבנהמסוג 1stMEMBER: 2ndMEMBER: 3rdMEMBER: 4th MEMBER: 5thMEMBER:name[]major[]pswdyeargpa מל"מ – מבוא למדעי המחשב
גישה לשדה במבנה std1.year = 1;הצבה בשדה הרביעי p = std1.name; קבלת ערך השדה ראשון הצבת אות באיבר בשדה הראשון std1.name[i]=‘a‘; קליטת השדה החמישי scanf(“%f“, &std1.gpa); בקשת הקצאה באמצעות השדה השלישי: std1.pswd=(char*)malloc(10); כלומר, שדה במבנה הוא משתנה רגיל לכל דבר. • הגישה: struct_name.member מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
אתחול מבנה • הגדרה ואתחול ביחד: struct Std_Rec student = {”Jack”,”cs”, ”xYtt@z”, 1, 3.5}; • או בנפרד... struct Std_Rec student; student.year= 1; strcpy( student.name, ”Jack”); student.pswd = ”xYtt@z”; strcpy( student.major, ”cs”); student.gpa = 3.5; מה זה strcpy ולמה צריך אותו? מל"מ – מבוא למדעי המחשב
קליטת קלט למבנה: • scanf(”%s”, student.name); • scanf(”%s”, student.major); • scanf(”%s”, student.pswd); • scanf(”%d”, &student.year;scanf(”%f”, &student.gpa); • או • scanf (”%s %s %s %d %f”, student.name, student.major, student.pswd, &student.year, &student.gpa); למה ישנם שדות בהם צריך & וכאלו שלא? מל"מ – מבוא למדעי המחשב
הדפסת פלט ממבנה printf (”%s”, student.name ); printf (”%s”, student.major ); printf (”%s”, student.pswd ); printf (”%d”, student.year ); printf (”%f”, student.gpa ); • או: printf(”%s,%s,%s,%d,%f”, student.name, student.major, student.pswd, student.year, student.gpa); מל"מ – מבוא למדעי המחשב
דוגמא – מבנה מסוג Point ... struct Point{ double x; double y; char comment[20]} b; double a;b.x = 5.0; b.y = 3.1; strcpy(b.comment, ”First Point”); a = b.x; printf (”The elements of b object \ are: %lf, %lf, and %s\n”, b.x, b.y, b.comment); מל"מ – מבוא למדעי המחשב
התייחסות בתוכנה ... switch (student.year)} case 1: printf(”1st year”); break; case 2: printf(”2nd year”); break; case 3: printf(”3rd year”); break; case 4: printf(”4th year”); break; default: printf(“Warning!!”); { מל"מ – מבוא למדעי המחשב
הכללים לעבודה נקבעים לפי סוג השדה ... #include <string.h> … strcpy(student.name, ”jasmin gal”);strcpy(student.major, ”CIS”);student.pswd = (char*)malloc(20); student.year = 1;student.gpa = 4.0; … מל"מ – מבוא למדעי המחשב
השמה בין מבנים ... • מותרת השמה בין 2 משתנים מאותו סוג מבנה: struct Std_Rec std_1 = {”Ran”, ”CIS”, ”0*##VRT” 1, 4.2}; struct Std_Rec std_2; std_2 = std_1; • השמה בין 2 המשתנים הקודמים זהה ל: strcpy(std2_.name,std_1.name); strcpy(std_2.major,std_1.major); std2_.pswd = std_1.pswd; std2_.year = std_1.year; std_2.gpa = std_1.gpa; WOW!!! מל"מ – מבוא למדעי המחשב
השמה בין מבנים (המשך) • ב C אין לנו אפשרות הצבה בין שני מערכים , • אך ישנה אפשרות להציב בין שני מבנים מאותו סוג, הכוללים מערכים! • זו פעולה רבת עוצמה!! – המאפשרת העתקת מערך!אם המבנים כוללים מערכים... מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
מערך של משתנים מסוג מבנה ... #define MAX_STD 30 typedef struct}char name[20]; char major[6]; char *pswd; int year; float gpa; } Std_Rec; Std_Rec st_list[MAX_STD]; סוג המשתנה שם המערך וגודלו מל"מ – מבוא למדעי המחשב
st_listמערך של משתנים מסוג מבנה(המשך) ... st_list[1].year st_list[0].name st_list[0] st_list[1] st_list[2] ... st_list[MAX_STD-1] st_list[2].gpa st_list[MAX_STD-1].major מל"מ – מבוא למדעי המחשב
פניות לאיברי מערך המבנים [i]. [i]. [i]. [i]. [i]. st_list[i].name; st_list[i].major; st_list[i].pswd; st_list[i].year; st_list[i].gpa; כלומר, st_list[i]הוא איבר במערך st_list והוא מבנה. לאברי המבנה פונים באמצעות '.' . מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
סיכום ביניים • הגדרת מבנה: הגדרת סוג חדש של משתנה, • הגדרה זו אינה מקצה מקום בזיכרון, • מקום מסוג זה יוקצה רק עם הגדרת משתנה מסוג המבנה, • מבנה הוא משתנה מורכב – היכול לכלול משתנים אחרים שהשפה מכירה – כולל מערכים, • גישה לשדות המבנה מתבצעת ע"י האופרטור . , • ניתן להציב מבנה א' בתוך מבנה ב' מאותו הסוג, • נעזר ב typedef כדי לקבל הגדרה "קצרה יותר" , • ניתן להגדיר מערך מבנים. מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
מבנה מוכל במבנה ... • אפשר שמבנה K ישתמש במבנה L, • אפשר שמבנה L יהיה שדה של מבנה K , • התנאי: מבנה L חייב להיות מוגדר בזמן יצירת מבנה K. מל"מ – מבוא למדעי המחשב
מבנה מוכל במבנה (המשך)... typedef struct{ char state[20]; char city[20]; char street[20]; long int zip;} Addr; • נגדיר מבנהAddr: • ונשתמש בהגדרה זו: typedef struct { char name[20]; char phone[20];AddrhomeAddress;AddrbusinessAddress; }Customer ; מל"מ – מבוא למדעי המחשב
מבנה מוכל במבנה (המשך)... Customer C1; • איך נפנה לאיבר של מבנה פנימי? • נגדיר: • וכך נפנה: strcpy(C1.name,”Hulio”); strcpy(C1.phone,”077-74322567”); strcpy(C1.homeAddress.state, ”Texas”); strcpy(C1.homeAddress.city, ”Austin”); strcpy(C1.homeAddress.street,”Boulevard Avenue”); C1.homeAddress.zip = 20154; מל"מ – מבוא למדעי המחשב
מבנה מוכל במבנה (המשך)... • דוגמה נוספת, נגדיר: typedef struct{int month, day, year;} Date; typedefstruct{ char name[20]; Date birthday;} p_data; p_data p1; • נפנה: strcpy(p1.name, ”Zvulun”); p1.birthday.month = 10; p1.birthday.day = 28; p1.birthday.year = 1983; מל"מ – מבוא למדעי המחשב
מבנה בתוך מבנה - תמונת זיכרון p1.birthday.year p1.birthday.day p1.birthday.month ...... p1.name p1.birthday struct p1 מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
מצביע למבנה ... • typedef struct{ • long id; • int labs, homework; • float midterm, final;} Score; • Score s1={56778922, 81, 87 , 53.2, 78.9}, • s2={32445621, 87, 90 , 68.0, 85.0}; • Score *s_ptr_1 = &s1, • Score *s_ptr_2 = &s2; • המשתניםs_ptr_1ו s_ptr_2הם מצביעים למשתנה מטיפוסScore. הגדרת המבנה, ושם קיצור הגדרת שני מבנים - ואיתחולם הגדרת שני מצביעים ואיתחולם. מל"מ – מבוא למדעי המחשב
s_ptr_1: s_ptr_2: s2: s1: id id 56778922 32445621 labs labs homework homework 87 81 90 87 midterm midterm final final 68.0 53.2 78.9 85.0 מצביע למבנה (המשך) ... מל"מ – מבוא למדעי המחשב
s_ptr_1: s1: 56778922 81 87 53.2 78.9 87 80.1 גישה למבנה דרך מצביע ... • נניח כי הגדרנו:Score *s_ptr_1 = &s1, • *s_ptr_2 = &s2; • כיצד ניגש אל שדות המבנה: • s_ptr_1->labs = 92; • s1.labs = 92; /* Exactly the same!! */s_ptr_1->final = 80.1; 92 מל"מ – מבוא למדעי המחשב
גישה למבנה דרך מצביע (המשך) • כלומר, גישה אל שדה fx במבנה דרך מצביע stx • stx->fx • למשל, העתקת הערך id ממבנה אחד לשני, באמצעות הפוינטרים, תתבצע באופן הבא: s_ptr_2->id = s_ptr_1->id; • או, פקטור של 10% על ציוני בוחן אמצע: s_ptr_2-> midterm *= 1.1; מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
s1: s_local: העברת מבנה כפרמטר לפונקציה ... • אנו יכולים לשלוח אל פונקציה את שם המבנה,ואז זה יהא call by value, אולשלוח את כתובת המבנה, כלומר call by reference, • נניח כי הגדרנו משתנה מקומי של הפונקציה,עם העתק של כל הערכים! מל"מ – מבוא למדעי המחשב
העברת מבנהכפרמטר לפונקציה(המשך) #include <stdio.h> typedef struct {char name[20]; int energy; int IQ; float velocity;} Robot_s; void rob_info(Robot_s r); /* rob_info prototype */ void main(){ /* initialize 2 ROBOTs */ Robot_s r1 = {"Earthling Ed", 100, 231, 4.1}; Robot_s r2 = {"Toxic Tom", 150, 254, 2.5}; rob_info(r1); rob_info(r2); } מל"מ – מבוא למדעי המחשב
העברת מבנה כפרמטר לפונקציה (המשך) • הפונקציהrob_info: void rob_info(Robot_s r){ printf(”%s has %d energy units,\n \ an IQ of %d,”, r.name, r.energy, r.IQ); printf(”and a velocity of %0.1f m/s.\n”, r.velocity); { • הפלט: Earthling Ed has 100 energy units, an IQ of 231, and a velocity of 4.1 m/s. Toxic Tom has 150 units of energy, an IQ of 254,and a velocity of 2.5 m/s. - מל"מ – מבוא למדעי המחשב
העברת מבנה כפרמטר לפונקציה (המשך) • מה מועבר לפונקציה – ערכי המבנה או כתובתו? • כלומר, האם זהו call by value, או call by reference? • איך אפשר לבדוק? • אם ננסה לשנות ערכים של מבנה שהועבר לפונקציה, כשנחזור לתוכנית הקוראת – נגלה כי השינויים נעלמו! • כלומר, העברת מבנה לפונקציה זהcall by value !! מל"מ – מבוא למדעי המחשב
הגדרה, • דוגמאות, ארגון וגישה, • אתחול, קלט ופלט, • מערך מבנים, • סיכום ביניים, • מבנה מוכל במבנה, • מצביע למבנה וגישה למבנה דרך מצביע, • העברת מבנה כפרמטר לפונקציה, • העברת מצביע למבנה כפרמטר לפונקציה, • מבנים והקצאה דינאמית, • סיכום Q&A. מל"מ – מבוא למדעי המחשב
העברת מצביע-למבנהכפרמטר לפונקציה ... #include <stdio.h> typedef struct{ char name[20]; int energy; int IQ; float velocity; } Robot_S; void rob_info(Robot_S r); /* prototype */ void rob_harm(Robot_S *r);/* prototype */ מל"מ – מבוא למדעי המחשב
העברת מצביע-למבנהכפרמטר לפונקציה (המשך)... int main() { Robot_S r1 = {”Martian Martin”, 140, 213, 5.1}; Robot_S r2 = {”Planetary Pete”, 170, 309, 4.5}; printf(”Before damage: \n\n”); rob_info(r1); rob_info(r2); rob_harm(&r1); /* pass pointer-to-struct to function */ rob_harm(&r2); /* pass struct’s address to function */ printf(”\nAfter damage: \n\n”); rob_info(r1); rob_info(r2); return 0; } מל"מ – מבוא למדעי המחשב
העברת מצביע-למבנהכפרמטר לפונקציה (המשך)... Robot_S r void rob_info(Robot_S r) { printf(”%s: Energy: %d, IQ: %d,”,r.name, r.energy, r.IQ); printf(”Velocity: %0.1f\n", r.velocity); } void rob_harm(Robot_S *r) { r->energy = r->energy - 20; r->velocity = r->velocity - 1; { השוני מתבטא בגישה אל המבנה Robot_S *r מל"מ – מבוא למדעי המחשב