Upload
dustin-flowers
View
69
Download
0
Embed Size (px)
DESCRIPTION
מכללת אורט כפר-סבא. תכנות מערכות בשפת C. מבנים ( struct ) מחרוזות. 26.10.14. אורי וולטמן. [email protected]. ברשותי שישה כדורים: שלושה שחורים ושלושה לבנים. כמו כן, ברשותי שלוש קופסאות, אשר על כל אחת מהן מודבקת תווית: על הקופסא הראשונה כתוב ' שחור-שחור '. - PowerPoint PPT Presentation
Citation preview
.ברשותי שישה כדורים: שלושה שחורים ושלושה לבנים:כמו כן, ברשותי שלוש קופסאות, אשר על כל אחת מהן מודבקת תווית
' שחור-שחורעל הקופסא הראשונה כתוב.'' שחור-לבןעל הקופסא השנייה כתוב.'' לבן-לבןועל הקופסא השלישית כתוב.'
הכנסתי שני כדורים בכל קופסא, כך שכעת כל התוויות מורות על )כלומר: בקופסא עליה כתוב 'שחור-שחור' אין שני תכולה שגויה
כדורים שחורים, בקופסא עליה כתוב 'שחור-לבן' אין כדור שחור אחד וכדור לבן אחד, ועל הקופסא עליה כתוב 'לבן-לבן' אין שני כדורים
לבנים(.
כיצד תוכלו, על-ידי הוצאת כדור אחד באקראי מתוך קופסא אחת לפיבחירתכם, ומבלי לראות את הכדורים האחרים, לזהות את תכולתן של
כל אחת מהקופסאות?
חידה לחימום
שתי הפונקציות התקניותsscanf-ו sprintf-מוגדרות ב stdio.h .printf ו-scanfומשמשות לקלט/פלט בדומה ל-
?מהו ההבדל בין הפונקציותprintf משמשת לפלט אל stdout הפלט הסטנדרטי; ברירת המחדל היא(
פלט למסך(.scanf-משמשת לקלט מ stdin הקלט הסטנדרטי; ברירת המחדל היא קלט(
מהמקלדת(. שתי הפונקציותsscanf-ו sprintf משמשות לקלט מתוך מחרוזת
מסוימת או לפלט אל תוך מחרוזת מסוימת. הכותרות של שתי הפונקציות זהות לכותרות שלscanf-ו printf ,הרגילות
אלא שהן מקבלות פרמטר אחד נוסף )הפרמטר הראשון( שהוא המחרוזת ממנה יש לקלוט או אליה יש לפלוט.
sscanf, sprintf
:לדוגמאchar mystr[] = "makom 3 ze beseder";
char s1[6];
int num;
sscanf(mystr, "%s %d", s1, &num);
puts(s1);
printf ("%d", num);
כלומר, הפונקציהsscanf קלטה ערכים לתוך s1-ו num מתוך המחרוזת mystr במקום מתוך הקלט הסטנדרטי )המקלדת(. הפלט שיוצג למסך ,יהיה:
makom
3
sscanf, sprintf
-נראה עכשיו דוגמא לשימוש בsprintf:char mystr[100];
int a = 2, b = 3;
sprintf(mystr, "%d + %d = %d", a, b, a+b);
puts(mystr);
:הפלט יהיה2 + 3 = 5
שימו לב שאם נמחק את ההוראהputs)mystr( אז קטע הקוד לא יציג פלט ", mystr "מדפיסה לתוך המחרוזת sprintfלמסך. זאת מכיוון שההוראה
במקום להדפיס למסך.
sscanf, sprintf
.לעיתים יש בתכנית שלנו מספר משתנים הקשורים ביניהם בקשר לוגילדוגמא, בתכנית המטפלת במידע על עובדים ייתכן ויש לנו את
המשתנים 'שם עובד', 'מספר עובד' ו-'ותק במקצוע'. בשפתC( ניתן להגדיר מבנה structure בשם 'עובד', שיהיה מורכב )
ממשתנים אלו. הגדרת המבנה נעשית באופן הבא:
struct <שם סוג המבנה> {
< הגדרת המשתנים במבנה>
};
( 'לעיתים מכנים מבנה בשם 'רשומהrecord ואת )(.fieldsהמשתנים במבנה בשם 'שדות' )
מבנים
לדוגמא, נגדיר מבנה חדש הנקראstudent:struct student {
char name[15]; char address[20]; unsigned int age;};
,כאן עוד לא הצהרנו על אף משתנה, אלא רק הגדרנו טיפוס. כעת:struct studentנצהיר על שני משתנים מטיפוס
struct student talmid, std1;
שם רשומה . לדוגמא:. שדה–אל שדה ברשומה פונים בצורה הבאהtalmid.age = 27;strcpy(talmid.name,”Bob”);strcpy(talmid.address,”Abbey Road”);
מבנים
#include <stdio.h>#include <string.h>
struct student { char name[15]; char address[20]; unsigned int age;};
int main(){ struct student talmid; printf(“הקש שם \n”); gets(talmid.name); printf(“הקש כתובת \n”); gets(talmid.address); printf(“הקש גיל \n”); scanf(“%u”,&talmid.age);
return 0;}
מבנים:נדגים תכנית העושה שימוש במבנה יכולנו לתת למבנה שם מקוצר, באמצעות
.typedef ההוראה
כעת היינו יכולים להצהיר על משתניםבאמצעות השם המקוצר:
stud_rec talmid;
-יכולנו לרשום את הוראת הtypedef אף לפני . structשהגדרנו את ה-
'המשמעות היא שאנחנו מגדירים 'שם נרדףלטיפוס, עוד לפני שאמרנו מהו בעצם הטיפוס.
זה חוקי לגמרי. כמובן שעדיין ניתן להצהיר על משתנים בעזרת
(, על אף שיצרנו struct studentהשם הארוך ).typedef שם קצר באמצעות
typedef struct student stud_rec;?חשבו: מדוע שורה זו מיותרת
-במקום להגדיר קודם את הstruct ואח"כ לתת לו שם קצר באמצעות typedef או לחלופין – קודם לתת לו שם קצר באמצעות ,typedef ואח"כ
, ניתן לעשות את שני הדברים בבת אחת.structלהגדיר את ה-
typedef struct student {char name[15];char address[20];unsigned int age;
} stud_rec;
כאשר מגדירים טיפוס בצורה כזו, ניתן להשמיט את השם המופיע בין לבין הסוגריים המסולסלים )במקרה שלנו – את המילה structהמילה student.)
מבנה הוא טיפוס נתונים לכל דבר, ולכן כל מה שניתן לעשות עםמשתנה, ניתן לעשות גם איתו: להעביר אותו כפרמטר לפונקציה,
להגדיר מערך של מבנים, להגדיר מבנה שאחד מהשדות שלו הוא בעצמו מבנה, וכו'.
מבנים
#include <stdio.h>#include <string.h>
struct student { char name[15]; char address[20]; unsigned int age;
};
int main(){ struct student a, *std_ptr;
std_ptr = &a; (*std_ptr).age = 13; strcpy((*std_ptr).name,”Shaltiel”); printf (“%s %u”, a.name, a.age);
return 0;}
מבנים ישנה צורת כתיבה מקוצרת כאשר עובדים עם
מצביע למבנה. ,במקום לכתוב, למשל*(std_ptr.)age אפשר ,
.std_ptr -> age לכתוב
struct test {
int num; int *pnum;
};
struct test a;struct test *b;b = &a;
a.pnum *a.pnum(*a).pnum b.pnum *b.pnum(*b).pnum b->pnum
מבנים מצהירים על המבנהstruct testומגדירים ,
להיות מטיפוס המבנה,aאת המשתנה להיות מטיפוס מצביע למבנה הזה.bואת המשתנה
להלן מספר ביטויים, אשר חלקם נכונים תחבירית וחלקם לא. קבעו לגבי כל אחד מהם האם הוא תקין
או לא, ובמידה וכן – הסבירו מה משמעותו.
struct account { unsigned int num; char name[16]; int balance; };
typedef struct account acnt;
תרגיל .בבנק "תן-לי-כסף-תן-לי" שומרים מידע על חשבונות בנק של לקוח
המידע על כל לקוח נשמר במחרוזת תווים בצורה הבאה: במחרוזת יש תווים( ואת יתרת 15את מס' החשבון )מספר טבעי(, שם הלקוח )עד
החשבון שלו בשקלים )מספר שלם(." :115לדוגמא -Yossi 4235" מעוניינים להגדיר טיפוס נתונים חדש. במקום לשמור את פרטי כל
( מתאים. structחשבון במחרוזת, רוצים להגדיר מבנה ).הגדירו מבנה כזה
כתבו קטע קוד, המקבל מחרוזת תוויםs בצורה שתוארה שלעיל ומציב מהסוג שהגדרנו.aאת פרטי החשבון בתוך מבנה
הלקוחות של הבנק שמורים במערך של מחרוזות. 10000פרטי כל מעוניינים להעביר את כל פרטי הלקוחות הללו, למערך חדש של
מבנים.10000
char *accounts[10000];
acnt accounts_new[10000];
...
for (i=0 ; i<10000 ; i++) sscanf(accounts[i],"%u %s %d",&accounts_new[i].num, accounts_new[i].name, &accounts_new[i].balance(;
sscanf(s,"%u %s %d", &a.num, a.name, &a.balance);
תרגיל