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

Post on 24-Jan-2016

80 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

תכנות בשפת C תרגול 9 typedef, struct, רשימות מקושרות. typedef אופרטור ה-. ניתן להגדיר טיפוס חדש על ידי פקודת typedef שתבניתה היא: typedef existing_type new_type ; המהדר יחליף את הטיפוס existing_type בטיפוס החדש new_type . לדוגמה: typedef int* pint; pint p,q; int* r; r = p; - PowerPoint PPT Presentation

TRANSCRIPT

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

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

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

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

typedef int* pint;pint p,q;int* r;r = p;

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

typedefאופרטור ה-

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

struct name_of_struct {    field1; field2; etc.};

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

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

struct מבנה -

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

ע"מ להכריז על משתנה מסוג מבנה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בקוד ב-

:דרך אחרת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 תחביר

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

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

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גישה לשדות ב-

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

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 תחביר

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

typedef struct dyn{

int *data;int len; int used;

} DynArr;

נתונה פונקציהvoid dynamicInsert(DynArr* arr, int val)שמכניסה מספר שלם למקום הפנוי הבא במערך.

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

1תרגיל

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

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

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

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;

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;

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;

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;

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

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תרגיל

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

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

רשימה מקושרת – הגדרה ותכונות

רשימה מקושרת – שרשרת של רשומות. כל רשומה מכילה מצביע לרשומה הבאה אוNULL .)עבור הרשומה האחרונה(

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

:לדוגמהstruct dbase_rec {

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

typedef struct dbase_rec dbase;

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

1שאלה :להלן הגדרה

typedef struct node{

int val;struct node *next;

} node;

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

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

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

)המשך(1שאלה

:השלימו את קטע הקוד הבא void upper_list(node* first) {

node *temp;

if( ?? 1 ?? )return;

while(?? 2 ??){ if( ?? 3 ??>= ?? 4 ??){ temp = ?? 5 ??; ?? 6 ?? ; free(temp) ; } else ?? 7 ?? ;}

}

)פתרון(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) ;}elsefirst=first->next;

}}

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 ??;

}}

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

)פתרון(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;

}}

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בהתייחס את השלם ,המופעים כל את תמחק שהפונקציה כך הבא בקוד החסר רק )ותשאיר ממוינת מקושרת ברשימה ערכים של הכפולים

אחד מהם(.

)פתרון(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 ;}

}

top related