41
ססססס סס' ססססס סס'4 4 - סססס ססססססס ס- סססס ססססססס סC C makefile makefile ADT-Abstract Data Type ADT-Abstract Data Type ססססס ססססס ס ססססס ססססס סADT ADT - - ססססס( ססססס( ( ( ססססססס ססססססססס ססססססס ססססססססססס סססס- סס[email protected]

תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח [email protected]

  • View
    231

  • Download
    7

Embed Size (px)

Citation preview

Page 1: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

44תרגול מס' תרגול מס'

-פתוח מודולרי ב-פתוח מודולרי בCCmakefilemakefileADT-Abstract Data TypeADT-Abstract Data Type דוגמא פשוטה לדוגמא פשוטה לADTADT--תאריך )תאריך( ((מצביעים לפונקציותמצביעים לפונקציות

[email protected]לי-טל משיח

Page 2: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

CCפיתוח מודולרי בפיתוח מודולרי ב- - :הבעיה:הבעיה

כתיבת תוכניות גדולות הינה קשהכתיבת תוכניות גדולות הינה קשהחלוקה לפונקיות איננה מספיקהחלוקה לפונקיות איננה מספיקהישנה קבוצה של פונקציות הקשורות זו לזוישנה קבוצה של פונקציות הקשורות זו לזו נירצה להפריד קבוצה זו מיתר התוכנית נירצה להפריד קבוצה זו מיתר התוכניתהדבר יאפשר שימוש חוזר בהןהדבר יאפשר שימוש חוזר בהן

– תכנות מודולריתכנות מודולריהפתרון – הפתרוןאפשרות לכתוב ולבדוק כל מודול לחודאפשרות לכתוב ולבדוק כל מודול לחוד אפשרות לעשות שימוש חוזר במודולים אפשרות לעשות שימוש חוזר במודולים

Page 3: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

עבודה עם מודולי תוכנהעבודה עם מודולי תוכנהכל מודול של התוכנה יורכב משני חלקים:כל מודול של התוכנה יורכב משני חלקים:

הממשק הממשקinterfaceinterface-מכונה גם ה-, מכונה גם ה ,headerheaderשל המודול של המודול יכיל את ההצהרות על הפונקציות אותן מממש המודול יכיל את ההצהרות על הפונקציות אותן מממש המודול •יכיל הגדרות של קבועים והגדרות של טיפוסים אשר מודולים אחרים יכיל הגדרות של קבועים והגדרות של טיפוסים אשר מודולים אחרים •

הנעזרים במודול זה צריכים להכיר )למשל ערכי שגיאות אפשריים של הנעזרים במודול זה צריכים להכיר )למשל ערכי שגיאות אפשריים של הפונקציות(הפונקציות(

המימוש המימושimplementationimplementation-מכונה גם ה-, מכונה גם ה ,sourcesource של של המודולהמודול

headerheaderיכיל את גוף הפונקציות אשר הוצהרו ב-יכיל את גוף הפונקציות אשר הוצהרו ב-•יכול להכיל פונקציות פנימיות למודול אשר לא נועדו לשימוש מחוץ יכול להכיל פונקציות פנימיות למודול אשר לא נועדו לשימוש מחוץ •

למודוללמודולמשתנים גלובלים שרק לפונקציות של המודול יש גישה אליהם וכד'משתנים גלובלים שרק לפונקציות של המודול יש גישה אליהם וכד'•

הפונקציות המוגדרות ב הפונקציות המוגדרות בheaderheader הינן השרותים אותם מספק הינן השרותים אותם מספק המודול לשאר התוכניתהמודול לשאר התוכנית

Page 4: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

דוגמא: מודול תאריךדוגמא: מודול תאריך

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

בכדי שנוכל לנצל את הפונקציות המטפלותבתאריכים במספר תוכניות נממשן במודול

dateנפרד בשם

Page 5: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

date.hdate.h: : headerheaderקובץ הקובץ ה--/* date.h - date module header file /* date.h - date module header file This module defines a date type and This module defines a date type and

implements some date manipulation functions. */implements some date manipulation functions. */#include#include <stdio.h> <stdio.h>

typedef structtypedef struct Date_t { Date_t { intint day; day; charchar month[4]; month[4]; intint year; year;} Date;} Date;

typedef enum {DateSuccess,DateFail,DateFailRead,typedef enum {DateSuccess,DateFail,DateFailRead,DateBadArg} DateResult;DateBadArg} DateResult;

/* reads a date from an open stream fd. Expects /* reads a date from an open stream fd. Expects the date dt points to allocated Date. */the date dt points to allocated Date. */

DateDateResult dateRead )FILE* ifd, Date* dt(; Result dateRead )FILE* ifd, Date* dt(; /* writes the date to the output stream ofd. *//* writes the date to the output stream ofd. */DateDateResult datePrint )FILE* ofd, Date dt(; Result datePrint )FILE* ofd, Date dt(; /* returns the date’s month number. –1 if fails *//* returns the date’s month number. –1 if fails */DateResult dateMonth)Date dt, DateResult dateMonth)Date dt, intint* month(* month(/* returns the number of days between dates. -1 if fails. *//* returns the number of days between dates. -1 if fails. */DateResult dateDiff)Date a, Date b, DateResult dateDiff)Date a, Date b, intint* diff(* diff(

Page 6: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

date.c date.c ::sourcesourceקובץ הקובץ ה--/* date.c - date module implementation *//* date.c - date module implementation */#include#include <string.h> <string.h>#include#include "date.h" "date.h"

static const charstatic const char* month[]= {"JAN", "FEB", "MAR", “APR”, "MAY", * month[]= {"JAN", "FEB", "MAR", “APR”, "MAY", "JUN", "JUL", "AUG", “SEP", "OCT", "JUN", "JUL", "AUG", “SEP", "OCT", "NOV", "DEC"}; "NOV", "DEC"};

Result dateRead)FILE* fd, Date dt(Result dateRead)FILE* fd, Date dt({{ int month =0;int month =0; ifif )fd == NULL || dt == NULL( )fd == NULL || dt == NULL( returnreturn DateBadArg; DateBadArg; ifif )fscanf )fd, "%d %s %d", &)dt->day(, dt->month, &)dt->year(( != 3( )fscanf )fd, "%d %s %d", &)dt->day(, dt->month, &)dt->year(( != 3( returnreturn DateFailRead; DateFailRead; ifif )dt->day < 1 || dt->day > 31 || )dt->day < 1 || dt->day > 31 ||

dateMonth)dt, &month( != DateSuccess || dt->year < 0(dateMonth)dt, &month( != DateSuccess || dt->year < 0( returnreturn DateFail; DateFail; returnreturn DateSuccess; DateSuccess;}}

Page 7: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

date.c date.c ::sourcesourceקובץ הקובץ ה--DateResult datePrint)FILE* fd, Date dt(DateResult datePrint)FILE* fd, Date dt({{

if if )fd == NULL || dt == NULL()fd == NULL || dt == NULL(return return DateBadArg;DateBadArg;

ifif )fprintf )fd, "%d %s %d ", dt->day, dt->month, dt->year( < 0( )fprintf )fd, "%d %s %d ", dt->day, dt->month, dt->year( < 0(returnreturn DateFail; DateFail;

returnreturn DateSuccess; DateSuccess;}}

DateResult dateMonth)Date dt, DateResult dateMonth)Date dt, intint* month(* month({{

intint j = 0; j = 0;if if )dt == NULL()dt == NULL(

returnreturn DateBadArg; DateBadArg;forfor )j = 0; j < 12; j++( )j = 0; j < 12; j++(

ifif )strcmp)dt->month, months[j]( == 0({ )strcmp)dt->month, months[j]( == 0({*month = j+1;*month = j+1;returnreturn DateSuccess; DateSuccess;

}}returnreturn DateFail; DateFail;

}}

Page 8: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

date.c date.c ::sourcesourceקובץ הקובץ ה--DateResult dateDiff)Date a, Date b, DateResult dateDiff)Date a, Date b, intint* diff(* diff({{

intint da, db, res; da, db, res;if if ))res = dateMonth)a,&da(( != DateSuccess())res = dateMonth)a,&da(( != DateSuccess(

returnreturn res; res;ifif ))res = dateMonth)b,&db(( != DateSuccess( ))res = dateMonth)b,&db(( != DateSuccess(

returnreturn res; res;da = a->day + 30 * da + 365 * a->year;da = a->day + 30 * da + 365 * a->year;db = b->day + 30 * db + 365 * b->year;db = b->day + 30 * db + 365 * b->year;*diff = ))da - db < 0( ? -)da - db( : da - db(;*diff = ))da - db < 0( ? -)da - db( : da - db(;returnreturn DateSuccess; DateSuccess;

}}

Page 9: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

proc.cproc.cקובץ האפליקציהקובץ האפליקציה: : #include#include <stdio.h> <stdio.h>#include#include "date.h" "date.h"

int int main)( main)( {{

Date d1,d2;Date d1,d2;intint month, diff; month, diff;ifif )dateRead)stdin,&d1( == DateFail || )dateRead)stdin,&d1( == DateFail ||

dateRead)stdin,&d2( == DateFail(dateRead)stdin,&d2( == DateFail(returnreturn 1; 1;

printf )"The month of "(;printf )"The month of "(;datePrint)stdout,d1(;datePrint)stdout,d1(;dateMonth)d1, &month(;dateMonth)d1, &month(;printf)"is %d.\n", month(;printf)"is %d.\n", month(;printf )"The difference between "(;printf )"The difference between "(;

datePrint)stdout,d1(;datePrint)stdout,d1(;printf)" and "(;printf)" and "(;datePrint)stdout,d2(;datePrint)stdout,d2(;dateDiff)d1, d2,&diff(;dateDiff)d1, d2,&diff(;printf)"is %d days.\n", diff(;printf)"is %d days.\n", diff(;returnreturn 0; 0;

}}

Page 10: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

תמיכת השפה בכתיבת מודוליםתמיכת השפה בכתיבת מודוליםמומלצת, הקומפייר כתיבת תוכניות במספר מודולים הנה טכניקה

של תומך באפשרות זו Cשפת

תהליך יצירת תוכנית מורכב משני שלבים: הידור הידור((compilationcompilation))

בנפרד)source ).cהקומפיילר מהדר כל קובץ •הקומפיילר אינו צריך לראות את המימוש של כל הפונקציות אשר אותו •

מודול נעזר בהן, אלא רק את הצהרותיהן source. פקודה זו מוסיפה לכל קובץ includeלשם כך קיימת פקודת ה •

include אשר בוצע לו headerאת ההגדרות הכתובות בקובץ ה- source. זהו קובץ אשר מכיל את קובץ ה object fileתוצאת שלב זה הנה •

מקומפל חלקית. כל הקוד אשר היה כתוב בקובץ מקומפל, אך קריאות לפונקציות אשר מימושן לא נמצא באותו קובץ עדיין לא מבוצעות

ונשמרות לשלב הבא קישור קישור((linkinglinking)) -של כל קבצי ה- של כל קבצי ה objectobject

object לתוכנית אחת. אם בקובץ object מחבר את כל קבצי ה linkerה • יצור linker אחר, ה objectאחד היתה קריאה לפונקציה הנמצאת בקובץ

קריאה זו.

Page 11: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

תמיכת השפה בכתיבת מודוליםתמיכת השפה בכתיבת מודוליםכאשר מבצעיםכאשר מבצעים

:ניתן להפריד את השלבים:ניתן להפריד את השלבים

gcc –c prog.c date.cgcc –c prog.c date.c objectobject יוצר את קבצי היוצר את קבצי ה

gcc prog.o date.ogcc prog.o date.o objectobject מקשר את קבצי המקשר את קבצי ה

gcc prog.c date.cgcc prog.c date.c מבוצעים שני השלבים ביחדמבוצעים שני השלבים ביחד

Page 12: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Compiling and LinkingCompiling and Linking

file1.c file2.c filen.c

file1.o file2.o filen.o

Compiler Compiler Compiler

Linker

runfile

Page 13: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Header Header שימוש בקבצישימוש בקבצי להצהרותלהצהרותקבצי כותרת משמשים קבצי כותרת משמשים

של קבועים, טיפוסי משתנים של קבועים, טיפוסי משתנים המשותפים בכל הקבצים, המשותפים בכל הקבצים,

משתנים ופונק'משתנים ופונק' כל קובץ שצריך את ההגדרות כל קובץ שצריך את ההגדרות

הנ"ל יכלול את השורה:הנ"ל יכלול את השורה:#include#include "defs.h" "defs.h"

מכיוון שהקובץ עשוי להיכלל מכיוון שהקובץ עשוי להיכללבמספר קבצים, יש שימוש במספר קבצים, יש שימוש

אשר בודק האם קבוע אשר בודק האם קבוע ,,##ifndefifndefב-ב-מסוים הוגדר מסוים הוגדר

רק בפעם הראשונה בה יתבצערק בפעם הראשונה בה יתבצע ##includeinclude "defs.h "defs.h"" יכללו יכללו

ההגדרות וההצהרות בפועלההגדרות וההצהרות בפועל

/* file : defs.h *//* file : defs.h */#ifndef#ifndef DEFS_HDEFS_H#define#define DEFS_HDEFS_H

#define#define TRUE 1 TRUE 1#define#define FALSE 0 FALSE 0

typedef structtypedef struct { {charchar name[20]; name[20];int int salary;salary;intint id; id;

} employee;} employee;

..

..

..#endif#endif

Page 14: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

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

עשוי לגרור צורך לעדכן כל תוכנית שעושה שימוש במודול עשוי לגרור צורך לעדכן כל תוכנית שעושה שימוש במודול הזה.הזה.

לכן, יש לחלק הגדרה של מודול לשני חלקים:לכן, יש לחלק הגדרה של מודול לשני חלקים:interfaceinterface- - הפעולות )פונקציות( המסופקות ע"י המודול הפעולות )פונקציות( המסופקות ע"י המודול implementationimplementation- - )אופן מימוש הפעולות )פונקציות( אופן מימוש הפעולות )פונקציות

אם השימוש במודול נעשה רק ע"י שימוש בפעולות אם השימוש במודול נעשה רק ע"י שימוש בפעולות המותרות,המותרות,

והשינוי נעשה רק באופן מימוש הפונקציות, אין צורך לשנות והשינוי נעשה רק באופן מימוש הפונקציות, אין צורך לשנות אתאת

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

שיטת העבודהשיטת העבודה הידור הידור((compilationcompilation))של כל קובץ לחוד של כל קובץ לחוד קישור קישור((linkinglinking)) -של כל קבצי ה- של כל קבצי ה objectobject

Page 15: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

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

calc.ccalc.ccontrol.ccontrol.cmain_prog.cmain_prog.c

התהליך יהיה כזה:התהליך יהיה כזה:

בכל פעם שמשנים קובץ מסוים, מספיק להדר שוב רק אותו בכל פעם שמשנים קובץ מסוים, מספיק להדר שוב רק אותו, מספיק , מספיק control.ccontrol.cולבצע קישור מחדש. לדוגמא, אם שונה ולבצע קישור מחדש. לדוגמא, אם שונה

לבצע:לבצע:

gcc -c calc.cgcc -c calc.cgcc -c control.cgcc -c control.cgcc -c main_prog.cgcc -c main_prog.cgcc calc.o control.o main_prog.o -o proggcc calc.o control.o main_prog.o -o prog

gcc -c control.cgcc -c control.cgcc calc.o control.o main_prog.o -o proggcc calc.o control.o main_prog.o -o prog

Page 16: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

פיתוח יעיל של תוכנה ממספר פיתוח יעיל של תוכנה ממספר קבציםקבצים ניתן להפוך את התהליך לאוטומטי ע"י שימוש בתוכנה ניתן להפוך את התהליך לאוטומטי ע"י שימוש בתוכנהmakemake , ,

( שאומר לה( שאומר להMakefileMakefileהמקבלת קובץ פקודות )המקבלת קובץ פקודות ) איך לקמפל כל קובץ איך לקמפל כל קובץ•מה התלויות הקיימות בין הקבציםמה התלויות הקיימות בין הקבצים•

קובץ ה קובץ ה MakefileMakefile:המתאים לדוגמא הנ"ל הוא: המתאים לדוגמא הנ"ל הוא

כאשר משנים קובץ, מריצים כאשר משנים קובץ, מריציםmakemakeומתבצעים רק הצעדים הדרושים ומתבצעים רק הצעדים הדרושים

prog:prog: main_prog.o calc.o control.o main_prog.o calc.o control.ogcc calc.o control.o main_prog.o -o proggcc calc.o control.o main_prog.o -o prog

calc.o:calc.o: calc.c calc.cgcc -c calc.cgcc -c calc.c

control.o:control.o: control.c control.cgcc -c control.cgcc -c control.c

main_prog.o:main_prog.o: main_prog.c main_prog.cgcc -c main_prog.cgcc -c main_prog.c

Page 17: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

makemake מאפשר הידור וקישור אוטומטיים של קבצי מאפשר הידור וקישור אוטומטיים של קבצי

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

Page 18: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

makemake

a.h b.h c.h

a.c b.c c.c

a.o b.o c.o

prog

#include "b.h"

#include "a.h" #include "b.h" #include "b.h"#include "c.h"

:לדוגמא, פרוייקט הניראה כך:לדוגמא, פרוייקט הניראה כך

Page 19: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

makemake קובץ ה קובץ הmakefilemakefile:המתאים לפרויקט זה: המתאים לפרויקט זה

הפעלת הפעלתmakemakeעל הפרויקט על הפרויקט

prog:a.o b.o c.ogcc a.o b.o c.o -o prog

a.o:a.c a.h b.hgcc -c a.c

b.o:b.c b.hgcc -c b.c

c.o:c.c c.h b.hgcc -c c.c

> make> make> make prog> make prog

Page 20: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

makemakeשימוש בשימוש ב--makemake [ -f [ -f filename filename ] [ ] [ targettarget ] ]

makemake:מחפש את קובץ התלויות שלו באופן הבא: מחפש את קובץ התלויות שלו באופן הבא makefilemakefile הוא מחפש קובץ בשם הוא מחפש קובץ בשם ff--אם לא משתמשים באופציה אם לא משתמשים באופציה ..11

במדריך הנוכחי.במדריך הנוכחי. MakefileMakefileאם לא נמצא הקובץ הנ"ל הוא מחפש קובץ בשם אם לא נמצא הקובץ הנ"ל הוא מחפש קובץ בשם ..22

במדריך הנוכחי.במדריך הנוכחי. filenamefilename הוא מחפש את הקובץ הוא מחפש את הקובץ ff--אם משתמשים באופציה אם משתמשים באופציה ..33

במדריך הנוכחי.במדריך הנוכחי., מבצע את רשימת הפקודות, מבצע את רשימת הפקודותmakemake מופיע בפקודה מופיע בפקודה targettarget אםאם

targettargetבקובץ התלויות. אחרת מבצע את ה בקובץ התלויות. אחרת מבצע את ה targettargetהמופיעות ב המופיעות ב הראשוןהראשון

makemakeאופן פעולת אופן פעולת makemake בודק את התלויות ב בודק את התלויות ב targettarget אותו רוצים לבצע. אם יש קובץ אותו רוצים לבצע. אם יש קובץ

יש לבצע את יש לבצע את targettargetברשימת התלויות שהוא חדש יותר מקובץ ה- ברשימת התלויות שהוא חדש יותר מקובץ ה- על מנת לעדכנו על מנת לעדכנוtargettargetהפקודה של ה-הפקודה של ה-

בדיקת התלויות נעשית באופן רקורסיבי, כך שיבוצעו כל בדיקת התלויות נעשית באופן רקורסיבי, כך שיבוצעו כל מעודכן מעודכןtargettargetתת-הפקודות בסדר הנכון, כדי ליצור תת-הפקודות בסדר הנכון, כדי ליצור

Page 21: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

makefilemakefileמבנה קובץמבנה קובץ קובץ קובץmakefilemakefile מורכב ממספר מורכב ממספר entry'sentry's.אחד אחרי השני. אחד אחרי השני המבנה של המבנה שלentryentry בקובץ בקובץ makefilemakefile::

<targets>: <files><targets>: <files><TAB> <compilation command for targets><TAB> <compilation command for targets>

makemakeכל מקום בשורה המתחילה ב # נחשבת כהערה עד סופה ו- כל מקום בשורה המתחילה ב # נחשבת כהערה עד סופה ו- מתעלם ממנה.מתעלם ממנה.

הערות:הערות: אם לא נשים אם לא נשיםTABTAB.בתחילת שורת הפקודה, היא לא תתבצע. בתחילת שורת הפקודה, היא לא תתבצע ניתן לשבור שורה ארוכה לכמה שורות, אך יש להוסיף / בסוף כל ניתן לשבור שורה ארוכה לכמה שורות, אך יש להוסיף / בסוף כל

בתחילת כל שורה(. בתחילת כל שורה(.TABTABשורה פרט לאחרונה )ועדיין יש לשים שורה פרט לאחרונה )ועדיין יש לשים אין לשים רווחים לא בתחילת שורה ולא בסופהאין לשים רווחים לא בתחילת שורה ולא בסופה-סיום שורות ב-סיום שורות בEnterEnter

Page 22: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

הגדרת מקרוהגדרת מקרואם יש מחרוזת שחוזרת פעמים רבות או שהיא עשויה להשתנותאם יש מחרוזת שחוזרת פעמים רבות או שהיא עשויה להשתנות

בעתיד אז ניתן להגדירה כמקרו ולגשת אליה באמצעות $בעתיד אז ניתן להגדירה כמקרו ולגשת אליה באמצעות $@$@$ הוא ה - הוא ה - targettargetהנוכחי הנוכחי *$*$ הוא ה - הוא ה - targettargetהנוכחי ללא סיומת הנוכחי ללא סיומת

CC = gccOBJS = a.o b.o c.oEXEC = progDEBUG_FLAG = # now empty, assign -g for debugCOMP_FLAG = -cCLEAN = clean$(EXEC) : $(OBJS)

$(CC) $(DEBUG_FLAG) $(OBJS) -o [email protected] : a.c a.h b.h

$(CC) $(DEBUG_FLAG) $(COMP_FLAG) $*.cb.o : b.c b.h

$(CC) $(DEBUG_FLAG) $(COMP_FLAG) $*.cc.o : c.c c.h b.h

$(CC) $(DEBUG_FLAG) $(COMP_FLAG) $*.cclean:

rm -f $(OBJS) $(EXEC)

> make cleanrm -f a.o b.o c.o prog> makegcc -c a.cgcc -c b.cgcc -c c.cgcc a.o b.o c.o -o prog

Page 23: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

יצירתיצירתmakefilemakefileבאופן אוטומטיבאופן אוטומטי

אפשר למצוא את כל הקשרים בין קבצים ע"י שימוש אפשר למצוא את כל הקשרים בין קבצים ע"י שימושבפקודה הבאה:בפקודה הבאה:

gcc -MM gcc -MM c-filesc-files:למשל:למשל

ניתן לשמור פלט זה בקובץ ולהשתמש בו כשלד ל ניתן לשמור פלט זה בקובץ ולהשתמש בו כשלד לmakefilemakefileהדרוש הדרוש

> gcc -MM *.c> gcc -MM *.ca.o : a.c a.h b.ha.o : a.c a.h b.hb.o : b.c b.hb.o : b.c b.hc.o : c.c c.h b.hc.o : c.c c.h b.h

Page 24: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

ADTADTAbstract Data TypeAbstract Data Type

Page 25: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

ADT ADT מבנה נתונים מופשטמבנה נתונים מופשט ADTADTהינו מודול מסוג מיוחד הינו מודול מסוג מיוחד -ב-בADTADTמסתירים את המימוש מהמשתמש מסתירים את המימוש מהמשתמש מגדירים טפוס של מצביע למבנה שגודלו מגדירים טפוס של מצביע למבנה שגודלו

ושדותיו אינם ידועיםושדותיו אינם ידועים נותנים למשתמש קבוצת פונקציות אשר רק נותנים למשתמש קבוצת פונקציות אשר רק

בעזרתן ניתן לטפל בטפוסבעזרתן ניתן לטפל בטפוס כיוון ש כיוון שADTADT הנו מודול, הכללים החלים על הנו מודול, הכללים החלים על

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

המספקת שירות מסוים. מקבל השרות אינו יודע המספקת שירות מסוים. מקבל השרות אינו יודע השירות ניתן השירות ניתןכיצדכיצד)ואינו מתעניין( )ואינו מתעניין(

Page 26: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

: :דוגמאדוגמאADTADTתאריךתאריך במודול התאריך שניתן, ישנה בעיה. כיוון במודול התאריך שניתן, ישנה בעיה. כיוון

שהמבנה חשוף המשתמש יכול לשנות את שהמבנה חשוף המשתמש יכול לשנות את השדות שלא דרך פונקציות הממשק. באופן זה, השדות שלא דרך פונקציות הממשק. באופן זה,

––יתכן ויגרם שהמבנה יהיה במצב לא תקין יתכן ויגרם שהמבנה יהיה במצב לא תקין 4545לדוגמא ששדה היום בתאריך יהיה לדוגמא ששדה היום בתאריך יהיה

נראה לכן מימוש של תאריך כ נראה לכן מימוש של תאריך כADTADT

Page 27: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Date.hDate.hקובץ הממשקקובץ הממשק - - /* date.h - date ADT module header file /* date.h - date ADT module header file This module defines a pointer to date type and implements some date This module defines a pointer to date type and implements some date manipulation functions.*/manipulation functions.*/#ifndef#ifndef DATE_H DATE_H#define#define DATE_H DATE_H#include#include <stdio.h> <stdio.h> /* for FILE definition *//* for FILE definition */

typedef structtypedef struct Date_t *Date ; Date_t *Date ;typedef enum {DateSuccess, DateFail, typedef enum {DateSuccess, DateFail,

DateFailRead, DateBadArg} DateResult;DateFailRead, DateBadArg} DateResult;/* allocates a new date. returns NULL if fails.*//* allocates a new date. returns NULL if fails.*/Date dateCreate)int day, int month, int year(; Date dateCreate)int day, int month, int year(; /* reads a date from an open stream ifd *//* reads a date from an open stream ifd */DateResult dateRead )FILE* ifd, Date dt(; DateResult dateRead )FILE* ifd, Date dt(; /* writes the date to the output stream ofd *//* writes the date to the output stream ofd */DateResult datePrint )FILE* ofd, Date dt(; DateResult datePrint )FILE* ofd, Date dt(; /* returns the date’s month number *//* returns the date’s month number */DateResult dateMonth)Date dt, int* month(;DateResult dateMonth)Date dt, int* month(;/* returns the number of days between dates*//* returns the number of days between dates*/DateResult dateDiff)Date a, Date b, int* diff(;DateResult dateDiff)Date a, Date b, int* diff(;/* deallocates a new date. returns NULL if fails.*//* deallocates a new date. returns NULL if fails.*/void dateDestroy )Date dt(; void dateDestroy )Date dt(; #endif#endif

Page 28: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Date.cDate.cקובץ המימושקובץ המימוש - -

/* date.c - date ADT module implementation *//* date.c - date ADT module implementation */#include#include <string.h> <string.h>#include#include "date.h" "date.h" structstruct Date_t { Date_t { int day;int day; char[4] month; char[4] month; int year;int year;};};static const charstatic const char* monthes[]= {“JAN”, “FEB”, ”MAR”, “APR”, ”MAY”,* monthes[]= {“JAN”, “FEB”, ”MAR”, “APR”, ”MAY”,

“ “JUN”, “JUL”, “AUG”, “SEP”, “OCT”,JUN”, “JUL”, “AUG”, “SEP”, “OCT”, “ “NOV”, “DEC”}; NOV”, “DEC”};

Page 29: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Date.cDate.cקובץ המימושקובץ המימוש - -

Date dateCreate)int day, Date dateCreate)int day, intint month, month, intint year( year( {{

Date dt = NULL;Date dt = NULL;ifif )day < 1 || day > 31 || month < 1 || month > 12( )day < 1 || day > 31 || month < 1 || month > 12(

return NULL ;return NULL ;dt = )Date( malloc)sizeof)dt = )Date( malloc)sizeof)structstruct Date_t((; Date_t((;if if )dt == NULL()dt == NULL(

return NULL;return NULL;dt->day = day ;dt->day = day ;strcpy )dt->month,monthes[month-1](;strcpy )dt->month,monthes[month-1](;dt->year = year ;dt->year = year ;returnreturn dt ; dt ;

}}

Page 30: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Date.cDate.cקובץ המימושקובץ המימוש --DateResult dateRead)FILE* fd, Date dt(DateResult dateRead)FILE* fd, Date dt({{

intint month =0; month =0;if if )fd == NULL || dt == NULL()fd == NULL || dt == NULL(

returnreturn DateBadArg; DateBadArg;ifif )fscanf )fd, "%d %s %d", &)dt->day(, dt->month, &)dt->year(( != 3( )fscanf )fd, "%d %s %d", &)dt->day(, dt->month, &)dt->year(( != 3(

returnreturn DateFailRead; DateFailRead;ifif )dt->day < 1 || dt->day > 31 || dateMonth)dt, &month( != )dt->day < 1 || dt->day > 31 || dateMonth)dt, &month( !=

DateSuccess || dt->year < 0(DateSuccess || dt->year < 0(returnreturn DateFail; DateFail;

returnreturn DateSuccess; DateSuccess;}}

DateResult datePrint)FILE* fd, Date dt(DateResult datePrint)FILE* fd, Date dt({{

ifif )fd == NULL || dt == NULL( )fd == NULL || dt == NULL(returnreturn DateBadArg; DateBadArg;

ifif )fprintf )fd, "%d %s %d ", dt->day, dt->month, dt->year( < 0( )fprintf )fd, "%d %s %d ", dt->day, dt->month, dt->year( < 0(returnreturn DateFail; DateFail;

returnreturn DateSuccess; DateSuccess;}}

Page 31: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Date.cDate.cקובץ המימושקובץ המימוש --DateResult dateMonth)Date dt, int* month(DateResult dateMonth)Date dt, int* month({{

intint j = 0; j = 0;ifif )dt == NULL( )dt == NULL(

returnreturn DateBadArg; DateBadArg;for for )j = 0; j < 12; j++()j = 0; j < 12; j++(

ifif )strcmp)dt->month, months[j]( == 0({ )strcmp)dt->month, months[j]( == 0({*month = j+1;*month = j+1;returnreturn DateSuccess; DateSuccess;

}}returnreturn DateFail; DateFail;

}}

Page 32: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

Date.cDate.cקובץ המימושקובץ המימוש --DateResult dateDiff)Date a, Date b, int* diff(DateResult dateDiff)Date a, Date b, int* diff({{

intint da, db, res; da, db, res;ifif ))res = dateMonth)a,&da(( != DateSuccess( ))res = dateMonth)a,&da(( != DateSuccess(

returnreturn res; res;if if ))res = dateMonth)b,&db(( != DateSuccess())res = dateMonth)b,&db(( != DateSuccess(

returnreturn res; res;da = a->day + 30 * da + 365 * a->year;da = a->day + 30 * da + 365 * a->year;db = b->day + 30 * db + 365 * b->year;db = b->day + 30 * db + 365 * b->year;*diff = ))da - db < 0( ? -)da - db( : da - db(;*diff = ))da - db < 0( ? -)da - db( : da - db(;returnreturn DateSuccess; DateSuccess;

}}

voidvoid dateDestroy)Date dt( dateDestroy)Date dt({{

ifif )dt == NULL( )dt == NULL(returnreturn;;

free)dt(;free)dt(;}}

Page 33: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

תוכנית הנעזרת במודול התאריךתוכנית הנעזרת במודול התאריך#include#include <stdio.h> <stdio.h>#include#include "date.h" "date.h"intint main)( main)( {{ Date d1,d2; Date d1,d2; intint month, diff; month, diff; if if ))d1 = dateCreate)1,1,1(( == NULL(||)d2 = dateCreate)1,1,1(( == NULL(())d1 = dateCreate)1,1,1(( == NULL(||)d2 = dateCreate)1,1,1(( == NULL(( returnreturn 1; 1; ifif )dateRead)stdin,d1( == Fail || )dateRead)stdin,d1( == Fail || dateRead)stdin,d2( == Fail(dateRead)stdin,d2( == Fail( returnreturn 1; 1; printf )"The month of "(;printf )"The month of "(; datePrint)stdout, d1(;datePrint)stdout, d1(; dateMonth)d1, &month(;dateMonth)d1, &month(; printf)"is %d.\n", month(;printf)"is %d.\n", month(; printf)"The difference between "(;printf)"The difference between "(; datePrint)stdout, d1(;datePrint)stdout, d1(; printf)"and "(;printf)"and "(; datePrint)stdout, d2(;datePrint)stdout, d2(; dateDiff)d1, d2,&diff(;dateDiff)d1, d2,&diff(; printf)"is %d days.\n", diff(;printf)"is %d days.\n", diff(; dateDestroy)d1(;dateDestroy)d1(; dateDestroy)d2(;dateDestroy)d2(; returnreturn 0; 0;}}

Page 34: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

מצביעים לפונקציותמצביעים לפונקציותכאשר אנו קוראים לפונקציה התוכנית מבצעת את הפעולות הבאות:כאשר אנו קוראים לפונקציה התוכנית מבצעת את הפעולות הבאות:

הארגומנטים המועברים לפונקציה מושמים במקום מסויים )מחסנית הארגומנטים המועברים לפונקציה מושמים במקום מסויים )מחסניתהקריאות( ע”פ הסדר בו מופיעים בהגדרת הפונקציההקריאות( ע”פ הסדר בו מופיעים בהגדרת הפונקציה

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

)מחסנית הקריאות()מחסנית הקריאות(הערך המוחזר מועבר למשתנה שאמור להכיל את תוצאת הפונקציההערך המוחזר מועבר למשתנה שאמור להכיל את תוצאת הפונקציה

מסקנהמסקנה ,אם קיימות שתי פונקציות המקבלות את אותם פרמטרים בדיוק, אם קיימות שתי פונקציות המקבלות את אותם פרמטרים בדיוק

ומחזירות את אותו טיפוס , הדבר היחיד המשתנה בין הקריאות ומחזירות את אותו טיפוס , הדבר היחיד המשתנה בין הקריאות לפונקציות הנו הכתובת של תחילת הפונקציה. לתוכנית לא אכפת לפונקציות הנו הכתובת של תחילת הפונקציה. לתוכנית לא אכפת

לאיזו מהפונקציות היא קוראתלאיזו מהפונקציות היא קוראת

כיצד ניתן לנצל זאת ?כיצד ניתן לנצל זאת ? ניתן להגדיר מצביעים לפונקציות אשר יכולים להכיל את כתובת ניתן להגדיר מצביעים לפונקציות אשר יכולים להכיל את כתובת

התחלה של פונקציות הזהות מבחינת הצהרתןהתחלה של פונקציות הזהות מבחינת הצהרתןנוכל לקרוא לפונקציות שונות ע”י מצביע זהנוכל לקרוא לפונקציות שונות ע”י מצביע זה

Page 35: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

::דוגמא פשוטהדוגמא פשוטה? פונקציות השוואה בין מספרים, מה ההבדל בינהן

typedef enum { Left, Eq, Right } Relation ;

Relation bigger(int a, int b){

if (a > b) return Left ;if (a==b) return Eq ;return Right ;

}

Relation bigger2(int a, int b) {

if (a<0) a = -a; if (b<0) b = -b;

if (a > b) return Left ;if (a==b) return Eq ;return Right ;

}

Page 36: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

::דוגמא פשוטהדוגמא פשוטהint main() {/* pfunc is a pointer to a function with signature Relation f(int, int) */ Relation (*pfunc)(int, int) ;Relation (*pfunc)(int, int) ; int a = -5 , b = 3 ; Relation c ; c = getchar(); if ( c == '1')

pfunc = bigger;pfunc = bigger; else

pfunc = bigger2;pfunc = bigger2; c = pfunc(a,b); switch (c) { case Left: printf ("%d\n",a);

break; case Eq: printf ("%d\n",a);

break; case Right: printf ("%d\n",b);

break; default: printf ("Error\n");

break; return 0;}

מה ההבדל?

Relation (*pfunc) (int, int) ;

Relation *pfunc (int, int) ;

Page 37: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

דוגמא מתקדמת – מיון מערכיםדוגמא מתקדמת – מיון מערכים

#include <stdio.h>typedef enum { Left, Right, Eq } Relation;typedef Relation (*cmp_func)(int, int);typedef Relation (*cmp_func)(int, int);

int sort(int *arr, int n, cmp_func cmpcmp_func cmp){ int i, j, t; if(arr==NULL || cmp==NULL) return 0; for(i=0; i<n; i++) { for(j=i+1; j<n; j++) { if(cmp(arr[i], arr[j])cmp(arr[i], arr[j])==Left) { t = arr[i]; arr[i] = arr[j]; arr[j] = t; } } } return 1;}

Relation bigger(int a, int b){if(a>b) return Left;if(a==b) return Eq;return Right;

}Relation abs_bigger(int a, int b){

if(a<0) a=-a; if(b<0) b=-b;

if(a>b) return Left;if(a==b) return Eq;return Right;

}

Page 38: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

דוגמא מתקדמת – מיון מערכיםדוגמא מתקדמת – מיון מערכים

int main(){

int arr[] = { 1, -3, 9, -10, -5 }; sort(arr, 5, bigger);sort(arr, 5, bigger); /* -10 -5 -3 1 9 */ sort(arr,5,abs_bigger);sort(arr,5,abs_bigger);/* 1 -3 -5 9 -10*/

return 0;}

Page 39: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

פונקצית מיון כלליתפונקצית מיון כללית

typedef Relation (*cmp_func)(int, int);typedef Relation (*cmp_func)(int, int);

int sort(int *arr, int n, cmp_func cmpcmp_func cmp){ int i, j, t; if(arr==NULL || cmp==NULL) return 0; for(i=0; i<n; i++) { for(j=i+1; j<n; j++) { if(cmp(arr[i], arr[j])cmp(arr[i], arr[j])==Left) { t = arr[i]; arr[i] = arr[j]; arr[j] = t; } } } return 1;}

נרחיב את פונקצית המיון למיין כל טיפוס שהואנרחיב את פונקצית המיון למיין כל טיפוס שהוא פונקצית מיון כללית יכולה להכתב ע"י מצביעים מטפוסvoid*

typedef Relation (*cmp_func)(void* , void* );

int sort(int sort(void **arrvoid **arr, int n, cmp_func cmp), int n, cmp_func cmp){{ int i, j;int i, j; void *t;void *t; if(arr==NULL || cmp==NULL) return 0;if(arr==NULL || cmp==NULL) return 0; for(i=0; i<n; i++) {for(i=0; i<n; i++) { for(j=i+1; j<n; j++) {for(j=i+1; j<n; j++) { if(cmp(arr[i], arr[j])==Left) {if(cmp(arr[i], arr[j])==Left) { t = arr[i];t = arr[i]; arr[i] = arr[j];arr[i] = arr[j]; arr[j] = t;arr[j] = t; }} }} }} return 1;return 1;}}

Page 40: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

פונקצית מיון כלליתפונקצית מיון כללית

Relation dateComp(void* date1, void* date2){Date d1 = (Date)date1;Date d2 = (Date)date2;if(d1->year > d2->year) return Left;if(d1->year < d2->year) return Right;if(dateMonth(d1) > dateMonth(d2)) return Left;if(dateMonth(d1) < dateMonth(d2)) return Right;if(d1->day > d2->day) return Left;if(d1->day < d2->day) return Right;return Eq;

}

למיון למיוןintintים-ים-

למיון תאריכיםלמיון תאריכים

Relation cmp(void* a, void* b) {return bigger (*((int*)a ), (*(int*)b));

}

Page 41: תרגול מס' 4 פתוח מודולרי ב-C makefile ADT-Abstract Data Type דוגמא פשוטה לADT- (תאריך( מצביעים לפונקציות לי-טל משיח litalma@cs.technion.ac.il

מיון תאריכיםמיון תאריכים

1 JAN 20002 FEB 200120 MAY 2010

int main() {int i=0;Date d[3];d[0] = dateCreate(20, 5, 2010);d[1] = dateCreate(1, 1, 2000);d[2] = dateCreate(2, 2, 2001);sort(d,3,dateComp);

for (i=0; i<3; i++)datePrint(d[i]);

return 0;}