PowerPoint Presentation

מסמכים קשורים
שאלהIgal : מערכים דו מימדיים רקורסיה:

שאלהIgal : מערכים דו מימדיים רקורסיה:

שאלהIgal : מערכים דו מימדיים רקורסיה:

פתרון מוצע לבחינת מה"ט ב_שפת c מועד ב אביב תשע"ט, אפריל 2019 מחברת: גב' זהבה לביא, מכללת אורט רחובות שאלה מספר 1 מוגדרת מחרוזת המורכבת מהספרות 0 עד 9.

Microsoft Word - c_SimA_MoedB2005.doc

סדנת תכנות ב C/C++

Microsoft Word B

מבוא למדעי המחשב - חובלים

PowerPoint Presentation

Slide 1

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

PowerPoint Presentation

הגשה תוך שבוע בשעת התרגול

משימה תכנית המתרגמת קטעי טקסט לשפה אחרת הקלט: קובץ המכיל את קטעי הטקסט וכן את השפה אליה רוצים לתרגם תרגול מס' 4: המתרגם שימוש במחלקות קיימות תכנות מתק

תרגול מס' 4: המתרגם שימוש במחלקות קיימות מחרוזות, קבצים, וקבלת קלט מהמשתמש

תרגול 1

אוניברסיטת בן גוריון בנגב תאריך המבחן: שקולניק אלכסנדר שם המרצה: מר בשפת JAVA מבוא לתכנות מבחן ב: מס' הקורס : הנדסת תעשיה וניהול מ

PowerPoint Presentation

Slide 1

PowerPoint Presentation

Microsoft PowerPoint - rec1.ppt

Slide 1

מבוא למדעי המחשב - חובלים

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

מספר מחברת: עמוד 1 מתוך 11 ת"ז: תשע"א מועד ב סמסטר א' תאריך: 00:11 שעה: 0 שעות הבחינה: משך כל חומר עזר אסור בשימוש בחינה בקורס: מבוא למדעי ה

Slide 1

מבוא לתכנות ב- JAVA תרגול 7

ex1-bash

הגשה תוך שבוע בשעת התרגול

PowerPoint Presentation

PowerPoint Presentation

Slide 1

מספר זהות: סמסטר ב' מועד א' תאריך: 11102/4// שעה: 9:22 משך הבחינה: 3 שעות חומר עזר: אין מותר השימוש במחשבון פשוט בחינה בקורס: מבני נתונים מרצה: הדר בי

מהוא לתכנות ב- JAVA מעבדה 3

אוניברסיטת חיפה החוג למדעי המחשב.5.6 מבוא למדעי המחשב סמסטר א' תשע"ז בחינה סופית מועד א', מרצה: שולי וינטנר מתרגלים: סמאח אידריס, ראמי עילבו

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

PowerPoint Presentation

PRESENTATION NAME

Microsoft PowerPoint - rec3.ppt

שקופית 1

המשימה תרגול מס' 5: קלט-פלט במערכות הפעלה שונות יש סימונים שונים עבור ירידת שורה :)newline( ב- UNIX/Linux )Line Feed( \n ב- Windows )Carriage Return +

מבוא למדעי המחשב

דוגמאות שהוצגו בהרצאה 10 בקורס יסודות מערכות פתוחות דוגמה 1 דוגמאות של פונקציות ב- awk שמראות שהעברת פרמטרים של משתנים פשוטים היא by value והעברת פרמט

תכנות מונחה עצמים א' – תש"ע

אוניברסיטת חיפה החוג למדעי המחשב מרצה: שולי וינטנר מתרגלים: נעמה טוויטו, מחמוד שריף מבוא למדעי המחשב סמסטר א' תשע"ב בחינת סיום, מועד א', הנחי

Microsoft PowerPoint - T-10.ppt [Compatibility Mode]

מבוא לתכנות ב- JAVA תרגול 11

מבחן סוף סמסטר מועד א 15/02/08 מרצה אחראית: דר שירלי הלוי גינסברג מתרגלים: גלעד קותיאל, דניאל גנקין הוראות: א. בטופס המבחן 7 עמודים ו 4 דפי נוסחאות. ב

מבחן 7002 פרטים כלליים מועד הבחינה: בכל זמן מספר השאלון: 1 משך הבחינה: 3 שעות חומר עזר בשימוש: הכל )ספרים ומחברות( המלצות: קרא המלצות לפני הבחינה ובדי

אוניברסיטת חיפה החוג למדעי המחשב מרצה: שולי וינטנר מתרגלים: נעמה טוויטו, מחמוד שריף מבוא למדעי המחשב סמסטר א' תשע"ב בחינת סיום, מועד א', הנחי

PowerPoint Presentation

Slide 1

מבחן סוף סמסטר מועד ב 28/10/08 מרצה אחראית: דר שירלי הלוי גינסברג מתרגלים: גלעד קותיאל, גדי אלכסנדרוביץ הוראות: א. בטופס המבחן 6 עמודים (כולל דף זה) ו

2013/14 אוניברסיטת חיפה מבוא למדעי מחשב, מעבדה מטרת המעבדה: לתרגל את המעבר מאלגוריתם לקוד C כמה שיותר. הוראות:.1.2 ניתן לעבוד ביחידים או בזוגות. (יש מ

234114

Slide 1

מבוא למדעי המחשב

תשע"דד אביב תוכנה 1 תרגיל מספר 4 עיבוד מחרוזות וקריאה מקבצים הנחיות כלליות: קראו בעיון את קובץ נהלי הגשת התרגילים אשר נמצא באתר הקורס..(

Slide 1

Slide 1

Programming

תרגיל בית מספר 1#

Slide 1

מערכות הפעלה

úåëðä 1 - çæøä

שאלה 2. תכנות ב - CShell

Microsoft Word - Ass1Bgu2019b_java docx

Slide 1

Tutorial 11

מערכות הפעלה

פייתון

מבוא למדעי המחשב

Microsoft Word - דוגמאות ב

מבוא למדעי המחשב

מבוא למדעי המחשב

PowerPoint Presentation

Slide 1

שעור 6

ייבוא וייצוא של קבצי אקסל וטקסט

פתרון 2000 א. טבלת מעקב אחר ביצוע האלגוריתם הנתון עבור הערכים : פלט num = 37, sif = 7 r האם ספרת האחדות של sif שווה ל- num num 37 sif 7 שורה (1)-(2) (

Slide 1

PowerPoint Presentation

Microsoft Word - review-sol-Prog123.doc

מערכות הפעלה

הטכניון - מכון טכנולוגי לישראל

Microsoft Word - c_SimA_MoedA2006.doc

תורת הקומפילציה

Microsoft Word - pitaron222Java_2007.doc

Microsoft PowerPoint - lec10.ppt

תאריך פרסום: תאריך הגשה: מבנה נתונים תרגיל 5 )תיאורטי( מרצה ומתרגל אחראים: צחי רוזן, דינה סבטליצקי נהלי הגשת עבודה: -את העבודה יש לה

תוכנה 1 1 אביב תשע"ג תרגיל מספר 5 מערכים, מחרוזות, עיבוד טקסט ומבני בקרה הנחיות כלליות: קראו בעיון את קובץ נהלי הגשת התרגילים אשר נמצא באתר הקורס. הגש

Microsoft PowerPoint - lec2.ppt

Python 2.7 in Hebrew

תכנות דינמי פרק 6, סעיפים 1-6, ב- Kleinberg/Tardos סכום חלקי מרחק עריכה הרעיון: במקום להרחיב פתרון חלקי יחיד בכל צעד, נרחיב כמה פתרונות אפשריים וניקח

Microsoft Word - tutorial Dynamic Programming _Jun_-05.doc

תמליל:

רשימות מקושרות עבודה קבצים דוגמה

מבנים המצביעים לעצמם רשימות מקושרות 2

נסתכל על המבנה הבא: typedef struct node { int data; struct node* next; *Node; איך נראים המבנים בזיכרון לאחר ביצוע הקוד הבא: Node node1 = malloc(sizeof(*node1)); Node node2 = malloc(sizeof(*node2)); node1->data = 1; node1->next = node2; node2->data = 2; node2->data = NULL; node1 data=1 next=0xdff268 data=2 node2 next=0x0 3

data=17 next=0xdff268 data=200 next=0xdef4c4 data=-15 next=0x43ba12 data=8 next=0x0 רשימה מקושרת הינה שרשרת של משתנים בזיכרון כאשר כל משתנה מצביע למשתנה הבא בשרשרת סוף הרשימה מיוצג ע"י מצביע ל- NULL רשימה מקושרת הינה מבנה נתונים המאפשר שיטה מסוימת לשמירת ערכים בזיכרון מערך הוא דוגמה נוספת למבנה נתונים רשימה מקושרת מאפשרת: שמירה של מספר ערכים שאינו חסום על ידי קבוע הכנסה והוצאה של משתנים מאמצע הרשימה חיבור וחלוקת רשימות נוחה בקלות 4

data data data כתבו תכנית המקבלת רשימת תאריכים מהמשתמש ומדפיסה אותם בסדר הפוך newnode list next=0x0ffef6 day=9 month="jun" year=1962 פתרון: ניצור רשימה מקושרת של תאריכים לא ניתקל בבעיות בגלל חוסר ההגבלה על גודל הקלט בכל פעם שנקלוט תאריך חדש נוכל להוסיפו בקלות לתחילת הרשימה 0x0ffef6 next=0x0ffef6 day=9 next=0x0ffef6 day=9 month="jun" year=1962 month="jun" year=1962 5

typedef struct node { Date data; struct node* next; *Node; למה לא ניתן להשתמש ב- Node? Node createnode(date d) { Node ptr = malloc(sizeof(*ptr)); if(!ptr) { return NULL; ptr->data = d; ptr->next = NULL; return ptr; void destroylist(node ptr) { while(ptr) { Node tmp = ptr; ptr = ptr->next; free(tmp);?tmp למה חייבים להקצות דינאמית את כל העצמים ברשימה? למה צריך את כיצד ניתן לכתוב קוד זה עם רקורסיה? 6

int main() { Node head = NULL; Date input; while (dateread(&input)) { Node newnode = createnode(input); newnode->next = head; head = newnode; for(node ptr = head ; ptr!= NULL ; ptr=ptr->next) { dateprint(ptr->data); destroylist(head); return 0; 7

1 2 3 4 5 רשימה מקושרת יכולה להיות גם דו-כיוונית. במקרה כזה לכל צומת שני מצביעים: next ו- previous יתרונה של רשימה מקושרת דו-כיוונית הוא בסיבוכיות בלבד - לכן עדיף להתחיל בכתיבת רשימה חד-כיוונית מאחר והיא פשוטה יותר? 2 3 4 5 נוח להוסיף איבר דמה לתחילת הרשימה כיד לצמצם את מקרי הקצה שצריכים לטפל בהם בקוד 8

ניתן ליצור רשימות מקושרות ע"י הוספת מצביע למבנה a בתוך המבנה a רשימות מקושרות אינן מוגבלות בגודלן ומאפשרות הכנסה נוחה של איברים באמצע הרשימה את הצמתים ברשימה יש להקצות דינאמית ולזכור לשחררם כאשר מממשים רשימה מקושרת מומלץ להוסיף איבר דמה בתחילתה 9

FILE* פונקציות שימושיות דוגמה 10

קבצים הם משאב מערכת בדומה לזיכרון: יש לפתוח קובץ לפני השימוש בו יש לסגור קובץ בסוף השימוש בו אותן בעיות אשר צצות מניהול זיכרון לא נכון עלולות לצוץ מניהול קבצים לא נכון בכדי להשתמש בקבצים מתוך התכנית שלנו נשתמש בטיפוס הנתונים FILE המוגדר ב- stdio.h כמו כל טיפוס מורכב השימוש בו נעשה בעזרת מצביעים, כלומר נשתמש בטיפוס FILE* 11

פתיחת קובץ נעשית ע"י הפונקציה :fopen FILE* fopen (const char* filename, const char* mode); filename היא מחרוזת המתארת את שם הקובץ mode היא מחרוזת המתארת את מצב הפתיחה של הקובץ "r" עבור פתיחת הקובץ לקריאה "w" עבור פתיחת הקובץ לכתיבה "a" עבור פתיחת הקובץ לשרשור )כתיבה בהמשכו( במקרה של כשלון מוחזר NULL 12

סגירת הקובץ מתבצעת ע"י קריאה לפונקציה :fclose int fclose (FILE* stream); בניגוד ל- free שליחת מצביע שהינו NULL תגרום להתרסקות התכנית ככלל, לא ניתן לשלוח NULL לפונקציות קלט/פלט המקבלת FILE* ערך ההחזרה הוא 0 בהצלחה ו- EOF במקרה של כשלון :EOF קבוע שלילי המשמש לציון שגיאות בפונקציות קלט פלט, בדרך כלל כאלו שנובעות מהגעה לסוף הקובץ file) (End of גם במקרה של כשלון לא ניתן יותר להשתמש בקובץ שנשלח 13

ניתן לכתוב ולקרוא מקובץ בעזרת הפונקציות fprintf ו- fscanf : int fprintf (FILE* stream, const char* format,...); int fscanf (FILE* stream, const char* format,...); התנהגותן זהה לזו של printf ו- scanf הרגילות מלבד הוספת הפרמטר stream שהוא הקובץ אליו יש לכתוב או ממנו יש לקרוא stream חייב להיות פתוח במצב המתאים כדי שהפעולה תצליח מצב המאפשר כתיבה עבור fprintf מצב המאפשר קריאה עבור fscanf :hello.txt לקובץ בשם Hello world FILE* stream = fopen("hello.txt", "w"); fprintf(stream, "Hello world!\n"); fclose(stream); דוגמה - כתיבת המחרוזת מה חסר? 14

ואת גודלו, קוראת שורה מ- stream ומעתיקה אותה אל החוצץ fgets מקבלת חוצץ char* fgets (char* buffer, int size, FILE* stream); אם אין מספיק מקום בחוצץ לשורה היא תיחתך מחזירה את buffer אם הקריאה הצליחה ו- NULL אחרת. כותבת את המחרוזת str לתוך :stream int fputs (const char* str, FILE* stream); fputs char buffer[buffer_size] = ""; fgets(buffer, BUFFER_SIZE, stream); printf("line is: %s",buffer); דוגמה - קריאת שורה מקובץ: 15

כתבו תכנית המקבלת כפרמטרים שני שמות קבצים <file1> ומעתיקה את תוכנו של <file1> ל-< file2 > ו-< file2 > > cat file1.txt This is text in a file >./copy file1.txt file2.txt > cat file2.txt This is text in a file דוגמה: 16

#include <stdio.h> #include <stdlib.h> #define CHUNK_SIZE 256 void copy(file* input, FILE* output) { char buffer[chunk_size]; while (fgets(buffer, CHUNK_SIZE, input)!= NULL) { fputs(buffer, output); void error(char* message, char* filename) { printf("%s %s\n", message, filename? filename : ""); exit(1); 17

int main(int argc, char** argv) { if (argc!= 3) { error("usage: copy <file1> <file2>", NULL); FILE* input = fopen(argv[1], "r"); if (!input) { error("error: cannot open", argv[1]); FILE* output = fopen(argv[2], "w"); if (!output) { fclose(input); error("error: cannot open", argv[2]); copy(input, output); fclose(input); fclose(output); return 0; 18

הזכרנו בתרגול מספר 1 את שלושת ערוצי הקלט/פלט הסטנדרטיים: הקלט הסטנדרטי, הפלט הסטנדרטי וערוץ השגיאות הסטנדרטי. ערוצים אלו מיוצגים ב- C כמשתנים גלובליים מטיפוס :FILE* stdout ערוץ הקלט הסטנדרטי stdin ערוץ הקלט הסטנדרטי stderr ערוץ השגיאות הסטנדרטי הטיפוס FILE* משמש כהפשטה (abstraction) של ערוצי קלט/פלט מאפשר עבודה אחידה על דברים שונים ומקל על המשתמש בו 19

לרוב הפונקציות עבור קלט ופלט קיימות גרסאות נפרדות עבור שימוש בערוצים הסטנדרטיים: למשל עבור printf fprintf הפונקציה puts כותבת מחרוזת ל- stdout ומוסיפה ירידת שורה בסופה int puts (const char* str); הפונקציה gets קוראת שורה מקלט הסטנדרטי. המחרוזת אינה מכילה את ירידת השורה בתוכה מה חסר כאן? מה הופך את הפונקציה הזו למסוכנת? אסור להשתמש ב- gets ופונקציות דומות המאפשרות חריגה מהזיכרון לקלט זהו מקור לשגיאות זיכרון ובעיות אבטחה char* gets (char* buffer); 20

נשפר את התכנית :copy אם התכנית מקבלת שני שמות קבצים היא פועלת כמקודם אם התכנית מקבלת שם קובץ יחיד היא מדפיסה את תוכנו לפלט הסטנדרטי אם התכנית אינה מקבלת פרמטרים היא מדפיסה מהקלט הסטנדרטי אל הפלט הסטנדרטי כמו כן, הודעות השגיאה של התכנית יודפסו אל ערוץ השגיאות הסטנדרטי >./copy file1.txt This is text in a file >./copy Hello! Hello! 21

#include <stdio.h> #include <stdlib.h> #define CHUNK_SIZE 256 הפונקציה copy אינה משתנה מאחר והערוצים והיא מתאימה גם לערוצים הסטנדרטיים void copy(file* input, FILE* output) { char buffer[chunk_size]; while (fgets(buffer, CHUNK_SIZE, input)!= NULL) { fputs(buffer, output); הודעות שגיאה מומלץ להדפיס לערוץ השגיאות void error(char* message, char* filename) { fprintf(stderr,"%s %s\n", message, filename? filename : ""); exit(1); 22

FILE* initinput(int argc, char** argv) { if (argc < 2) { return stdin; return fopen(argv[1], "r"); FILE* initoutput(int argc, char** argv) { if (argc < 3) { return stdout; return fopen(argv[2], "w"); 23

int main(int argc, char** argv) { if (argc > 3) { error("usage: copy <file1> <file2>", NULL); FILE* input = initinput(argc, argv); if (!input) { error("error: cannot open", argv[1]); FILE* output = initoutput(argc, argv); if (!output) { fclose(input); error("error: cannot open", argv[2]); copy(input, output); fclose(input); fclose(output); return 0; איזו בעיה עלולה להיווצר כאן? 24

מה ההבדל בין שתי הפקודות הבאות? כיצד הוא מתבטא בתכנית? >./copy data1.txt data2.txt >./copy < data1.txt > data2.txt 25

כעת נוכל לשפר את טיפוס הנתונים Date כך שיתמוך גם בקלט ופלט לקבצים: void dateprint(date date, FILE* stream) { fprintf(stream, "%d %s %d\n", date.day, date.month, date.year); bool dateread(date* date, FILE* stream) { if (date == NULL) { return false; if (fscanf(stream, "%d %s %d", &(date->day), date->month, &(date->year))!= 3) { return false; return dateisvalid(*date); 26

קבצים הם משאב מערכת יש להקפיד על ניהול נכון שלהם קבצים והערוצים הסטנדרטיים מיוצגים ע"י הטיפוס FILE* ניתן לכתוב ולקרוא מקבצים בדומה לביצוע פעולות קלט ופלט רגילות הערוצים הסטנדרטיים מיוצגים ב- C כמשתנים הגלובליים stdin, stdout stderr הכוונות קלט ופלט ניתנות לביצוע בתוך הקוד ומחוצה לו ע"י שימוש ב-* FILE ניתן ליצור פונקציות קלט/פלט לטיפוסי נתונים כך שיתאימו גם לכתיבה לערוצים סטנדרטיים וגם לקבצים ו- 27

28

1 JAN 404 Last gladiator competition 6 MAY 1889 Eiffel tower completed 21 NOV 1794 Honolulu harbor discovered 1 JAN 1852 First public bath in NY 21 NOV 1971 First takeoff of the Concorde 6 MAY 1915 Orson Welles born 6 MAY 1626 Manhattan purchased for 24$ 21 NOV 1971 First landing of the Concorde נתון קובץ המכיל תאריכים ומאורעות אשר התרחשו בהם בפורמט הבא: > important_dates events Enter a date: 21 NOV 1971 First takeoff of the concorde First landing of the concorde Enter a date: 2 MAY 1971 Nothing special כתבו תכנית אשר קוראת קובץ המכיל תאריכים היסטוריים כמתואר ומאפשרת למשתמש לחפש את רשימת המאורעות שקרו בתאריך מסוים 29

בשלב הראשוני לפתרון התרגיל עלינו להחליט מאילו טיפוסי נתונים נרכיב את הפתרון כלל אצבע לזיהוי הטיפוסים כלל אצבע לזיהוי פונקציות של הטיפוסים שמות עצם המופיעים בתיאור התכנית פעלים המופיעים בתיאור התכנית כתבו תכנית אשר קוראת קובץ המכיל תאריכים היסטוריים כמתואר ומאפשרת למשתמש לחפש את רשימת המאורעות שקרו בתאריך מסוים כאשר התכן הבסיסי הושלם ניתן לגשת לשלב הקידוד נוח להתחיל מטיפוסי הנתונים הבסיסיים ביותר 30

Historical Dates List Event Description Description Date Events list Next Description Next Description Next Description Date Events list Next Description Next ניצור רשימה של תאריכים היסטוריים: כל תאריך היסטורי יכיל את רשימת המאורעות שקרו בו Date Events list Next Description Description Next כדי להדפיס את רשימת המאורעות של תאריך מסוים נחפש אותו ברשימה ונדפיס את המאורעות שלו אם מצאנו תאריך כזה 31

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #define MAX 256 char* stringcopy(const char* str) { char* copy = malloc(strlen(str) + 1); return copy? strcpy(copy, str) : NULL; 32

typedef struct Event_t { char* description; struct Event_t* next; *Event; Event eventcreate(const char* description) { Event event = malloc(sizeof(*event)); if (!event) { return NULL; event->description = stringcopy(description); if (!event->description) { free(event); // A better idea? return NULL; event->next = NULL; return event; 33

Event eventaddnext(event head, Event newevent) { if (!head) { return newevent; Event ptr = head; while (ptr->next) { ptr = ptr->next; ptr->next = newevent; return head; 34

void eventdestroy(event event) { while (event) { Event temp = event; event = event->next; free(temp->description); free(temp); 35

typedef struct Historical_Date_t { Date date; Event eventlist; struct Historical_Date_t* next; *HistoricalDate; HistoricalDate historicaldatecreate(date date, Event event) { HistoricalDate historicaldate = malloc(sizeof(*historicaldate)); if (!historicaldate) { return NULL; historicaldate->date = date; historicaldate->eventlist = event; historicaldate->next = NULL; return historicaldate; 36

void historicaldatedestroy(historicaldate historicaldate) { if (!historicaldate) { return; historicaldatedestroy(historicaldate->next); eventdestroy(historicaldate->eventlist); free(historicaldate); HistoricalDate historicaldatefind(historicaldate historicaldate, Date date) { for (HistoricalDate ptr = historicaldate; ptr!= NULL; ptr = ptr->next) { if (dateequals(ptr->date, date)) { return NULL; return ptr; 37

HistoricalDate historicaldateadd(historicaldate historicaldate, Date date, Event event) { HistoricalDate target = historicaldatefind(historicaldate, date); if (target) { target->eventlist = eventaddnext(target->eventlist, event); return historicaldate; HistoricalDate newdate = historicaldatecreate(date, event); newdate->next = historicaldate; return newdate; void historicaldateprintevents(historicaldate historicaldate) { for (Event ptr = historicaldate->eventlist; ptr!= NULL; ptr = ptr->next) { printf("%s", ptr->description); 38

HistoricalDate readevents(char* filename) { FILE* fd = fopen(filename, "r"); if (!fd) { return NULL; 39 HistoricalDate history = NULL; char buffer[max] = ""; Date tempdate; while (dateread(&tempdate, fd) && fgets(buffer, MAX, fd)!= NULL) { Event newevent = eventcreate(buffer); history = historicaldateadd(history, tempdate, newevent); fclose(fd); return history;

int main(int argc, char** argv) { if (argc!= 2) { printf("usage: search_history <events file>\n"); return 0; HistoricalDate history = readevents(argv[1]); if (!history) { printf("error loading events from %s\n",argv[1]); return 0; printf("enter a date: "); Date tempdate; while (dateread(&tempdate, stdin)) { HistoricalDate h = historicaldatefind(history, tempdate); if (h) { historicaldateprintevents(h); else { printf("nothing special\n"); printf("enter a date: "); historicaldatedestroy(history); return 0; 40

ניתן להשתמש ברשימות מקושרות כדרך נוחה לשמירת נתונים כדי לפתור בעיה גדולה ניתן לחלק אותה לפי טיפוסי הנתונים המעורבים בפתרון את הקוד נוח לכתוב "מלמטה למעלה" 41