typedef, struct, ¥ ® © ¹prog121/wiki.files/tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ '...

22
תכנות בשפתC תרגול9 typedef, struct, רשימות מקושרות

Upload: others

Post on 11-Jul-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

Cתכנות בשפת 9תרגול

typedef, struct, רשימות מקושרות

Page 2: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

ניתן להגדיר טיפוס חדש על ידי פקודתtypedef שתבניתה היא:

typedef existing_type new_type ;

המהדר יחליף את הטיפוסexisting_type בטיפוס החדשnew_type .

:לדוגמה

typedef int* pint;

pint p,q;

int* r;

r = p;

השימוש ב-typedef מאפשר להפוך את הקוד לקריא יותר מבחינת

.ההקשר

typedef -אופרטור ה

Page 3: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

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

:תחביר struct name_of_struct

{ field1; field2; etc. };

דומה למערך בכך ששניהם יכולים לאגד מספר נתונים , :במבנה יש חופש בבחירת טיפוסי הנתוניםאך

struct address { char city[20]; char street[20]; int num_house; long code_area; };

struct - מבנה

אין מניעה שאחד השדות יהיה בעצמו מבנה

Page 4: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

מ להכריז על משתנה מסוג מבנה"עaddress יש לכתוב:

struct address x;

איתחול :

struct address add = {"migdal Haemek", "Harazim", 5, 23028};

ניתן להשתמש ב- typedef כדי להקל על שימוש ב- struct :

typedef struct some_name

{ char alias[20]; char username [20]; char password[10]; int numberOfFriends;

} facebook_record;

struct תחביר

facebook_recordאפשר להחליף כל מופע של ולהיפך, struct some_name -בקוד ב

Page 5: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

דרך אחרת: struct some_name

{ char alias[20]; char username [20]; char password[10]; int numberOfFriends;

};

typedef struct some_name facebook_record;

struct ממש כמו כל ', או כערך החזרה של פו' ניתן לשימוש כפרמטר לפו

.טיפוס אחר

ניתן להגדיר מצביע למבנה :facebook_record* p;

;facebook_record records[10]: ניתן להגדיר מערך של רשומות

(המשך) struct תחביר

Page 6: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

וחץ ).( נקודה : קיימים שני אופרטורים, כדי לגשת לשדות(->. )

אופרטור הנקודה מאפשר גישה לשדות בתוך משתנה מטיפוס המבנה.

facebook_record d;

strcpy(d.username, “david hasholet”);

d.numberOfFriends = 501;

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

facebook_record* d = (facebook_record*)malloc( sizeof(facebook_record) );

strcpy(d->username, “david hasholet”);

d->numberOfFriends = 501;

שימו לב ש :d->numberOfFriends = 501;

;numberoffriends=501.(d*)-שקול ל

struct -גישה לשדות ב

Page 7: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

מבנה מקונן:

:שדות המבנה יכולים להיות בעצמם מבנה לדוגמא

struct address { char city[15]; char street[15];

};

struct citizen{ struct address add; long id;

};

נניח כי אנו מצהירים על משתנה מסוגcitizen:

struct citizen ctzn;

כדי לגשת לשדהid נרשום :ctzn.id

כדי לגשת לשדהcity נרשוםctzn.add.city – ראשית ניגש לשדה , כלומרadd שהוא גם מטיפוס מבנה

.וממנו ניגש לשדות שלו שוב על ידי אופרטור הנקודה

(.'כלומר שדה של שדה של מבנה וכו)ניתן לבנות מבנים בעלי קינון מדרגה גבוהה יותר : הערה

(המשך) struct תחביר

Page 8: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

להלן הגדרה עבור מבנה המממש מערך דינאמי :בלתי מוגבל של ערכים' שניתן להוסיף לו מס

typedef struct dyn

{

int *data;

int len;

int used;

} DynArr;

נתונה פונקציהvoid dynamicInsert(DynArr* arr, int val)

. שמכניסה מספר שלם למקום הפנוי הבא במערך

את גודל המערך 2פי " מכפילה"הפונקציה , אם המערך מלא

.תוך שמירה על הערכים הישנים, ומוסיפה את הערך החדש

1תרגיל

dataי השדה "המערך מוצבע ע

הוא אורך המערך lenהשדה

used הוא אינדקס התא האחרון שבשימוש

Page 9: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

void dynamicInsert(DynArr* arr, int val)

{

int *newarr;

int i;

if (?? 1 ??)

{

newarr = ?? 2 ??;

for (i=0; i <= arr->used ; i++)

?? 3 ??;

free(?? 4 ??);

arr->data = ?? 5 ??;

arr->len = ?? 6 ??;

{

arr->data[?? 7 ??] = val;

}

(המשך) 1תרגיל

typedef struct dyn

{ int *data; int len; int used; } DynArr;

Page 10: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

void dynamicInsert(DynArr* arr, int val)

{

int *newarr;

int i;

if (arr->len-1 <= arr->used)

{

newarr = (int *)malloc(2*(arr->len)*sizeof(int));

for (i=0; i <= arr->used ; i++)

newarr[i]=arr->data[i];

free(arr->data);

arr->data = newarr;

arr->len = 2*(arr->len);

}

arr->data[++(arr->used)] = val;

}

(פתרון) 1תרגיל

typedef struct dyn

{ int *data; int len; int used; } DynArr;

Page 11: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

void main()

{

DynArr a; int i=0;

a.len=4;

a.used=3;

if(!(a.data=(int *)malloc(4*sizeof(int)))){

printf("Problem allocating memory, please try again!!!\n");

return;

}

for(;i<=a.used;++i)//Fill the array with the sqare of the indices:

*(a.data+i)=i*i;

printf("Array BEFORE dynamic insertion:\n");

for(i=0;i<=a.used;++i)//Print the array before dynamic insertion:

printf("%d\t",a.data[i]);

printf("\n");

(שימוש בפתרון) 1תרגיל

typedef struct dyn

{ int *data; int len; int used; } DynArr;

Page 12: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

dynamicInsert(&a, 16);

printf("Array AFTER dynamic insertion:\n");

for(i=0;i<=a.used;++i) //Print the array after dynamic insertion:

printf("%d\t",a.data[i]);

printf("\n");

free(a.data);

}

(המשך -שימוש בפתרון ) 1תרגיל

typedef struct dyn

{ int *data; int len; int used; } DynArr;

Page 13: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

struct record

{

char name[20];

int serial_num;

};

void readRecord(struct record r)

{

scanf("%s", r.name);

scanf("%d", &r.serial_num);

}

void main()

{

struct record r;

r.serial_num = 123;

strcpy(r.name, "abc");

readRecord(r);

printf("name: %s, serial: %d\n",r.name, r.serial_num);

}

(א) 2תרגיל

?מה תדפיס התוכנית הבאה

name: abc, serial: 123

Page 14: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

struct record

{

char name[20];

int serial_num;

};

void readRecord(struct record *r)

{

scanf("%s", r->name);

scanf("%d", &(r->serial_num));

}

void main()

{

record r;

readRecord(&r);

printf("name: %s, serial: %d\n",r.name, r.serial_num);

}

(ב) 2תרגיל

?מה תדפיס התוכנית הבאה

מה שיוזן כקלט על ידי המשתמש

Page 15: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

הגדרה ותכונות –רשימה מקושרת כל רשומה מכילה מצביע לרשומה הבאה או . שרשרת של רשומות –רשימה מקושרתNULL

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

.הוספה ומחיקה יעילה של איברים –היתרון לעומת מערך ; לאיבר המבוקשלדוגמה:

struct dbase_rec { char *record; /* --> data field */ struct dbase_rec *next; /* --> next field */ };

typedef struct dbase_rec dbase;

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

Page 16: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

1שאלה

להלן הגדרה: typedef struct node { int val; struct node *next; } node;

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

.(val השדה לפי) ממש עולה בסדראחרי הקריאה ל, לדוגמה- void upper_list(node* first) הרשימה

:העליונה תהפוך לתחתונה

Page 17: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

(המשך) 1שאלה

השלימו את קטע הקוד הבא:

void upper_list(node* first) { node *temp; if( ?? 1 ?? ) return; while(?? 2 ??){ if( ?? 3 ??>= ?? 4 ??){ temp = ?? 5 ??; ?? 6 ?? ; free(temp) ; } else ?? 7 ?? ; } }

Page 18: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

(פתרון) 1שאלה void upper_list(node* first) { node *temp; if( !first ) return; while(first->next){

if( first->val>=first->next->val){ temp = first->next; first->next=first->next->next ; free(temp) ;

} else

first=first->next; } }

Page 19: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

2שאלה השלם את החלק החסר בקוד הבא כך , 1' להגדרת הצומת משאלה מס בהתיחס

שלו ואז val -פעמים השווה לערכו של משתנה ה' שהפונקציה תשכפל כל צומת מס .תוסיף את הצמתים החדשים לרשימה ישר אחרי הצומת ממנו הם שוכפלו

void multiply(node* head) { node *temp; int i; while(head) { temp = head -> next; for(i=0; i< ?? 1 ??; i++) { head->next = ?? 2 ?? ; ?? 3 ?? = head -> val; head = ?? 4 ?? ; } ?? 5 ?? = ?? 6 ?? ; head = ?? 7 ??; } }

ל "אחרי הביצוע של הפונקציה הנ, לדוגמה:הרשימה העליונה תהפוך לתחתונה

Page 20: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

(פתרון) 2שאלה void multiply(node* head) { node *temp; int i; while(head) { temp = head -> next; for(i=0;i<head->val-1; i++) { head->next = (node*)malloc(sizeof(node)); head->next->val = head -> val; head = head->next ; } head->next = temp ; head = temp; } }

Page 21: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

3שאלה

void trim(node* lst) { node *aux; while( ?? 1 ?? && ?? 2 ??){

if(lst->val == ?? 3 ??){ aux = ?? 4 ?? ; lst->next = ?? 5 ?? ; free( ?? 6 ?? ); }

else lst = ?? 7 ?? ;

} }

החסר החלק את השלם ,1 'מס משאלה הצומת להגדרת בהתייחס

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

.(מהם אחד רק ותשאיר) ממוינת מקושרת ברשימה ערכים

Page 22: typedef, struct, ¥ ® © ¹prog121/wiki.files/Tirgul9.pdfª ¹ ® ® ® ¤ © « ¸ ² ¬ ¡ ' ¹ typedef struct dyn { int *data; int len; int used; } DynArr; void dynamicInsert(DynArr*

(פתרון) 3שאלה

void trim(node* lst) { node *aux; while(lst!=NULL && lst->next!=NULL){ if(lst->val == lst->next->val){ aux = lst->next ; lst->next = lst->next->next ; free(aux); } else lst = lst->next ; } }