Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 מבחן מועד ג' סמסטר אביב -2006 אשכול מחשבים (Cluster) הוא קבוצה של מחשבים המחוברים ביניהם ופועלים יחד בצורה מתואמת, כך שבמובנים רבים הם יכולים להיחשב.

Similar presentations


Presentation on theme: "1 מבחן מועד ג' סמסטר אביב -2006 אשכול מחשבים (Cluster) הוא קבוצה של מחשבים המחוברים ביניהם ופועלים יחד בצורה מתואמת, כך שבמובנים רבים הם יכולים להיחשב."— Presentation transcript:

1 1 מבחן מועד ג' סמסטר אביב -2006 אשכול מחשבים (Cluster) הוא קבוצה של מחשבים המחוברים ביניהם ופועלים יחד בצורה מתואמת, כך שבמובנים רבים הם יכולים להיחשב כמחשב אחד. עיקרון הפעולה הוא חלוקת המשימות החישוביות (Jobs) למספר רב של נקודות קצה (Nodes) המחוברות לאשכול. לצורך פתרון השאלה ניתן להניח כי Node מאופיין על ידי שם יחודי (מחרוזת) והוא בעל התכונות הבאות: מהירות CPU (שבר עשרוני), גודל הזיכרון (מספר שלם) וגודל דיסק (מספר שלם). משימה חישובית מתוארת באמצעות שורת הפעלה (מחרוזת), מספר המחשבים שהמשימה תרוץ עליהם (לא יותר ולא פחות, מס' מדוייק) ודרישות מדוייקות לגבי מאפייני המחשבים האלו (מהירות, גודל זיכרון וגודל דיסק). לצורך פתרון השאלה יש להניח כי לא ניתן להריץ בו-זמנית 2 משימות על אותו מחשב.

2 2 מבחן מועד ג' סמסטר אביב -2006 סעיף א' (20 נקודות) ממש/י את קובץ המנשק של המודול Cluster. בנוסף ל-type-ים וכד', על המנשק לתמוך בפונקציות הבאות בלבד: CreateCluster – יצירת אשכול מחשבים DestroyCluster – הריסת אשכול מחשבים AddNode – הוספת מחשב מסוים לאשכול מחשבים RemoveNode – הורדת מחשב מסוים מאשכול מחשבים MergeClusters - בהינתן 2 אשכולות יצירת אשכול חדש – איחוד של השניים RemoveSubcluster – בהינתן 2 אשכולות יצירת אשכול חדש – הפרש בין הראשון והשני IsNodeInCluster – בהינתן אשכול ומחשב מסוים, בדיקה האם המחשב שייך לאשכול IsJobRunnable – בהינתן אשכול ומשימה מסוימים, הפונקציה מחזירה אינדיקציה האם ניתן להריץ את המשימה על האשכול ואם כן אז גם מחזירה תת-אשכול (מתוך האשכול שניתן כפרמטר) שניתן להריץ עליו משימה זו. CreateMatchings – בהינתן אשכול ורשימת משימות חישוביות הפונקציה תחזיר את אוסף "ההתאמות" של משימות אל תתי אשכולות מתוך האשכול שניתן כפרמטר. הסברים נוספים בהמשך...

3 3 פתרון סעיף א' #ifndef CLUSTER_H #define CLUSTER_H #include "image.h" typedef enum {FALSE, TRUE} Boolean; typedef enum {SUCCESS =1, FAILURE =-1} Result; typedef struct Cluster_t *Cluster; Cluster CreateCluster(); // or Result CreateCluster(Cluster *); Result DestroyCluster(Cluster c); Result AddNode(Cluster c,char* name,double cpu, int memsize, int disksize); Result RemoveNode(Cluster c,char* name); Result MergeCluster(Cluster c1, Cluster c2, Cluster * c3); Result RemoveSubCluster(Cluster c, Cluster c2, Cluster * c3); Result IsNodeInCluster(Cluster c, char* name, Boolean * res); Result IsJobRunnable(Cluster c, Job job, Cluster * res); // res will be null // incase the job is not runnable Result CreateMatching(Cluster c, Job* jobs, int num_jobs, Cluster** mutch); CreateCluster DestroyCluster AddNode RemoveNode MergeClusters RemoveSubcluster IsNodeInCluster IsJobRunnable CreateMatchings

4 4 פתרון סעיף א' המשך struct Job_t { char* command; int nodes_num; double cpu_size; int mem_size; int diskspace_size; } ; typedef struct Job_t * Job; #endif

5 5 מבחן מועד ג' סמסטר אביב -2006 סעיף ב' (20 נקודות) 1. (8 נקודות) הציגו את מבנה הנתונים של Cluster כפי שיופיע ב- Cluster.c. תאר/י איזה ADT(s) תבחרו לביסוס המימוש. ניתן להיעזר בכלADT שנלמד בכיתה עם שינויים סבירים. תאר/י את השינויים. אם השתמשתם במבנים נוספים לצורך פתרון סעיף א', יש לתאר גם אותם. 2. (12 נקודות) יש לממש את פונקציה 9 מתוך הממשק מסעיף א'. לצורך הפתרון יש להניח את ההנחות הבאות: רשימת משימות הניתנת כפרמטר נתונה בתור אוסף סדור של משימות ויותר חשוב להתאים מחשבים למשימות "ראשונות" מאשר למשימות "אחרונות", כלומר אם ניתן להתאים את משימות 1 ו-2 או משימות 1 ו-3 אז האפשרות הראשונה היא עדיפה. אוסף ההתאמות צריך להיות מקסימלי, כלומר אם הצלחתם "להתאים" משימות 1, 2, ו-5, אבל ניתן בנוסף "להתאים" את משימה 6, אז אוסף ההתאמות שלכם הוא אינו מקסימלי. ניתן להשתמש בפונקציות אחרות מסעיף א'

6 6 פתרון סעיף ב' 1 #include “Set.h” #include “Custer.h” struct Cluster_t { Set nodes; } ; typedef struct Node_t { char* name; double cpu; int mem_size; int disk_size; } Node;

7 7 מבחן מועד ג' סמסטר אביב -2006 סעיף ב' (20 נקודות) 1. (8 נקודות) הציגו את מבנה הנתונים של Cluster כפי שיופיע ב- Cluster.c. תאר/י איזה ADT(s) תבחרו לביסוס המימוש. ניתן להיעזר בכלADT שנלמד בכיתה עם שינויים סבירים. תאר/י את השינויים. אם השתמשתם במבנים נוספים לצורך פתרון סעיף א', יש לתאר גם אותם. 2. (12 נקודות) יש לממש את פונקציה 9 מתוך הממשק מסעיף א'. לצורך הפתרון יש להניח את ההנחות הבאות: רשימת משימות הניתנת כפרמטר נתונה בתור אוסף סדור של משימות ויותר חשוב להתאים מחשבים למשימות "ראשונות" מאשר למשימות "אחרונות", כלומר אם ניתן להתאים את משימות 1 ו-2 או משימות 1 ו-3 אז האפשרות הראשונה היא עדיפה. אוסף ההתאמות צריך להיות מקסימלי, כלומר אם הצלחתם "להתאים" משימות 1, 2, ו-5, אבל ניתן בנוסף "להתאים" את משימה 6, אז אוסף ההתאמות שלכם הוא אינו מקסימלי. ניתן להשתמש בפונקציות אחרות מסעיף א'

8 8 פתרון סעיף ב' 2 Result CreateMatching(Cluster c, Job* jobs, int num_jobs, Cluster** mutches){ Cluster sub_cluster = NULL, mutch = NULL; if(c==NULL || jobs == NULL || Cluster == NULL || num_jobs < 0) return BAD_PARAM; *mutches = (Cluster*) malloc(sizeof(Cluster)*num_jobs); if (*mutches == NULL) return ALLOC_FAIL; for (int i=0; i<num_jobs; i++){ IsJobRunnable(c, jobs[i], &mutch); (*mutches)[i] = mutch; if (mutch !=NULL) RemoveSubCluster(c, mutch, &sub_cluster); c = sub_cluster; } return SUCCESS; }

9 9 הכרות עם ++C ++C כ- C משופר

10 10 תוכנית ראשונה ב ++ C // First C++ program #include int main() { /* This is not a good program: we are not using C++ I/O */ printf(“Hello World\n”); // but notice the new style for // one line remarks: return 0; // comment till end of line } הערות של שורה אחת

11 11 זיכרון דינמי ב ++ C הקצאת מערכים: [new type[# of elements להקצאת מערך. delete[] pointer to array לשחרור מערך int *pi = new int[5] ; if (pi == NULL) …. pi[3] = 6; delete[] pi ; אין צורך ב casting הקצאת אובייקטים בודדים: new type במקום: malloc(sizeof(type)) delete pointer במקום: free (pointer) int *pi = new int ; if (pi == NULL) …. *pi = 6; delete pi ;

12 12 ב ++C משתמשים ב-const כתחליף ל define# const int max = 100; const char digits[] = {‘0’,’a’,’2’,’c’,‘4’,’b’}; what happens when we try: “max = 5;”? מה יקרה במקרים הבאים ? digits[3] = ‘u’ ; //מותר? int* max2= &max ; // ? מותר const int* max2 = &max ; // פתרון int k; max2 = &k; // ? מותר שימוש נוסף הינו פרמטרים וערכי החזרה מפונקציות: int cparr (int* to, int size, const int* from); const char* getName (struct Person* p) ; const in C ++ טוב לתיעוד ולקומפיילר מי שיקבל את המחרוזת שהפונקציה החזירה, לא לא יוכל לשנות אותה

13 13 Reference reference הוא שם אחר למשתנה קיים. הביטוי &X משמעותו reference לטיפוס X (לא לבלבל עם &X שמשמעותו "הכתובת של משתנה X). reference חייב להיות מאותחל כאשר הוא נוצר כדי לדעת מי המשתנה הקיים שהוא "יתחפש" אליו. אתחול זה אינו השמה. לאחר האתחול לא ניתן להגיד ל-reference להתחפש למשתנה אחר - הוא "תקוע" עם מי שאתחל אותו. כל פעולה המופעלת על ה reference פועלת על המשתנה שהוא מהווה שם נוסף אליו. int i = 8 ; int &j = i; int x = i; i = 5 ; // j = 5, x = 8 j++; // i = j = 6

14 14 Reference II ב-reference משתמשים בעיקר להעברת פרמטרים אל ומפונקציות. ב- C יכולנו להעביר רק את ערכם של הפרמטרים (call by value). ב- ++C נוכל להעביר את הפרמטרים עצמם. (call by reference). העברת פרמטרים גדולים by reference זולה יותר מהעברתם by value כי אין צורך להעתקם. swap in C void swap(int* p, int* q) { int t = *p ; *p = *q; *q = t ; } swap in C++ void swap(int& p, int& q) { int t = p ; p = q; q = t ; } swap(x,y); // OK swap(x,5) ; // Error

15 15 דוגמא נוספת לשימוש ב reference Int& arrayBounds (int* array, int size, int& max, int& min) { int i,sum = 0 ; max = min = array[0]; for (i=0 ; i<size; i++) { if (max < array[i]) max = array[i]; if (min > array[i]) min = array[i] ; sum += array[i] ; } return array[size/2] ; // what if returns sum ? }

16 16 Function Overloading נניח נרצה לכתוב פונקציה המעלה בחזקה. double pow(double x, double y); בעיה - יעילות. נרצה מימוש שונה כאשר המעריך מטיפוס שלם. פתרון סטייל C: double pow_dd(double x, double y); double pow_di(double x, int y); int pow_ii(int x, int y); מה רע? פתרון סטייל ++C: double pow (double x, double y); double pow (double x, int y); int pow (int x, int y);

17 17 Function Overloading הפתרון שהוצג מסתמך על כך, שב ++C פונקציה מזוהה על פי שמה והפרמטרים שהיא מקבלת. כאשר ישנן מספר פונקציות בעלות שם זהה, הקומפיילר ינסה להחליט מהי הפונקציה ה”קרובה” ביותר מבחינת סוג הפרמטרים המועבר, ולה יקרא. אם הקומפיילר אינו מסוגל להחליט אזי הוא מוציא הודעת על שגיאת ambiguity - חוסר בהירות. בתהליך ההחלטה לא מתחשבים בטיפוס ערך ההחזרה של הפונקציה. מקובל להשתמש ב Function Overloading כאשר יש פונקציות המבצעות פעולה דומה על טיפוסים שונים (לדוגמא pow או print).

18 18 Function overloading resolution rules void print(int) ; void print(const char *) ; void print(double) ; void print(long ) ; char c; int i ; short s; float f; print( c ); print(i); print(s) ; print(f) ; print(‘a’); print(45); print(0.0) ; print (“a”); (what if we had void print (char*); instead ?) rules: 1. exact match (+trivial int ->int&, to const). 2. match with promotions (char,short int -> int, float->double). 3. match with conversions (int->float, float -> int). 4. match with user defined type conversions. 5. match with ellipsis (…) 12 3 4

19 19 Default Parameters לעיתים פונקציה צריכה ברוב המקרים פרמטר בעל ערך קבוע, ורק במקרים נדירים ערך אחר. נרצה שבמקרה השכיח לא נצטרך להעביר את הפרמטר הנ”ל, אלא שזה יבחר באופן דיפולטי על ידי הקומפיילר. לדוגמא: הדפסת מספרים בבסיסים שונים. לרב הבסיס יהיה 10. void print_num(int num, int base = 10) ; void f() { print_num(24,7); print_num(12,10); // no need to send 10. print_num(12); }

20 20 Default Parameters מימוש של פונקציה עם פרמטרים דיפולטים הנו רגיל. ההבדל היחיד הנו באופן הקריאה. אם לא יסופק פרמטר אזי הפונקציה תקבל את הערך הדיפולטי. ניתן לתת ערכי ברירת מחדל רק לפרמטרים האחרונים: int f1(int a = 0, int b = 0, int c = 0); // Ok int f2(int a, int b = 0, int c = 0); // Ok int f3(int a = 0, int b = 0, int c); // Error int f4(int a = 0, int b, int c = 0); // Error את ערכי ברירת המחדל יש לכתוב פעם אחת בלבד (רצוי בהצהרה הראשונה על הפונקציה).

21 21 מימוש מבני נתונים מופשטים ב- ++C

22 22 מבנה הנתונים מחסנית תזכורת מחסנית הינה מבנה נתונים התומך בפעולות הבאות : push - הוסף איבר למחסנית. pop - הוצא את האיבר ה ” צעיר ” ביותר במחסנית. top - החזר את האיבר ה ” צעיר ” ביותר במחסנית. ובנוסף : create - צור מבנה נתונים מסוג מחסנית ( ריק ). destroy - הרוס את מבנה הנתונים מחסנית. print - הדפס את תוכן מבנה הנתונים. 128 top דוגמא למימוש אפשרי: מערך + מצביע למקום הפנוי הבא

23 23 מימוש ב ++ C לעומת C ב-C כאשר הגדרנו ADT נעזרנו: בקובץ header אשר הכיל את הממשק: הוגדר בו הטיפוס של ה ADT והוגדרו בו פונקציות המטפלות ב ADT. בקובץ ה source הופיע המימוש של הפונקציות. ב ++C הוטמעה צורת עבודה זו בשפה, וניתן להגדיר טיפוסים (מחלקות) אשר כוללים בתוכם הן את השדות של כל משתנה מאותו טיפוס (אובייקט של אותה מחלקה) והן את הפונקציות (מתודות) המופעלות עליו.

24 24 מימוש ב-++ Header File :C enum Result {Success, Fail} ; struct Stack { int* array; int size, top_index ; } ; שדות data members פונקציות של המחלקה method or member functions Result init (int size) ; void destroy() ; Result push (int e); Result pop (); Result top(int& e); Result print() ;

25 25 מימוש ב ++ C Source File Result Stack::init (int s) { if ((array = new int[s] )==NULL) return Fail; size = s; top_index = 0 ; return Success ; } void Stack::destroy () { delete[] array ; } ערך מוחזר מסמן שזוהי method של class Stack שם ה method גישה ישירה לשדות של ה - struct כאילו הם משתנים לוקליים

26 26 Result Stack::push(int e) { if (top_index == size) return Fail ; array[top_index] = e; top_index ++ ; return Success; } Result Stack::pop () { if (top_index == 0) return Fail; top_index--; return Success; } מימוש ב ++ C Source File

27 27 Result Stack::top (int& e) { if (top_index == 0) return Fail; e = array[top_index-1]; return Success; } מימוש ב ++ C Source File

28 28 שימוש ב-Stack ב- C שימוש ב - Stack ב - ++C #include “Stack.h” int main() { Stack s ; int i; s.init (100) ; s.push (1); s.push(213); s.pop (); s.top(i); s.destroy (); } #include “Stack.h” int main() { Stack s ; int i; init (&s,100) ; push (s,1); push(s,213); pop (s); top(s,&i); destroy (s); } קריאה לפונקציה מתבצעת בדיוק כמו גישה לשדה

29 29 המצביע this שימו לב לאופן השונה בו נקראו הפונקציות ב- C וב- ++C. ב- C נדרשנו להעביר מצביע לאובייקט (מבנה) עליו על הפונקציה לעבוד, בעוד שב- ++C לא העברנו פרמטר כזה, מצד שני קראנו לפונקציה של המחלקה (מתודה) באופן שונה: s.push(3); // calls push on object s with parameter 3 נשאלת השאלה - כיצד הפונקציה יודעת לאיזה אובייקט התכוונו כאשר קראו לה ? הפתרון: כאשר נקראת מתודה כלשהי נשלח לה פרמטר סמוי בשם this שטיפוסו הנו מצביע למחלקה בה מוגדרת המתודה, ומכיל מצביע לאובייקט עמו נקראה המתודה. בכל גישה לשדה של האובייקט או למתודה שלו מתוך מתודה אחרת הקומפיילר מוסיף הצבעה דרך this. void Stack::top(int& j) { j = array[top_index-1]; } void Stack::top(int& j) { j = this->array[this->top_index-1]; } המתודה, לאחר שהקומפיילר הוסיף את המצביע this

30 30 בעייה: גישה למשתנים struct Stack { private: int* array; int size, top_index ; public: Result init (int size) ; Result destroy() ; Result push (int e); …. } ; ב ++C העבודה עם מחלקות מהווה את דרך העבודה העיקרית. הבעיה עם האופן בו הוגדרה קודם לכן המחלקה Stack הייתה כי כל פונקציה יכלה לגשת ישירות לשדות של אובייקטים מטיפוס Stack. בכדי למנוע זאת הוספו לשפה ה access modifier הקובעים למי מותר לגשת לאיזה חלק במחלקה. private - רק למתודות של המחלקה מותר לגשת לשדות פרטיים או לקרוא למתודות פרטיות. public - כל אחד יכול לגשת לחלק הציבורי.

31 31 שמוש ב- class במקום ב- struct class Stack { int* array; int size, top_index; public: Result init (int size) ; Result destroy() ; Result push (int e); Result pop (); Result top(int& e); Result print() ; } ; מקובל להגדיר מחלקות ע ” י המילה השמורה class ולא struct בה משתמשים לרוב לייצוג מבנים ( מחלקות ללא מתודות ). ההבדל בין struct ל class הנו כי ב - class, אלא אם כן צוין אחרת, מוד הגישה הנו private בעוד שב - struct המוד הדיפולטי הנו public.

32 32 Friend functions אם נרצה בכל זאת לאפשר לפונקציות אשר אינן מתודות של המחלקה גישה לחלק ה private של המחלקה, נוכל להגדירן כ- friend של המחלקה. נרצה לבצע זאת לרוב למען מימוש יעיל יותר של הפונקציה. class Stack { private: int* array; int size, top_index; friend int second (Stack); public: … int Second(Stack s) { if (s.top_index < 2) exit(1); return s.array[s.top_index-2]; }

33 33 Friend classes and Methods class A { …. int f() ; … }; class B { … }; class C { friend int A::f(); friend class B; }; בדומה ל friend function ניתן להגדיר גם method של מחלקה אחת כ- Friend של מחלקה אחרת. ניתן להגדיר מחלקה שלמה כחברה של מחלקה אחרת ואז כל ה- methods של אותה מחלקה יוכלו לגשת לחלק ה- private של המחלקה האחרת. השימוש ב Friends פוגע בקריאות התוכנה, ולכן מומלץ לא להשתמש בכך פרט למקרים יוצאי דופן. method f() of class A is a friend of class C all methods of class B are friends of class C

34 34 const member functions I כאשר מתודה אינה משנה את מצב האובייקט עליו היא נקראת (לדוגמא () size במחלקה Stack) ניתן לציין זאת ע”י הוספת const בסוף ההצהרה על המתודה. הסיבה שרצוי לבצע זאת הנה כי עבור const objects מותר לקרוא רק ל const methods. class C { int read() const; void write(int j); … }; int func (const C& con, C& mut) { con.read () ;// ok con.write(5);// error mut.read();// ok mut.write(5);// ok }

35 35 const member functions II הגדרת מתודה כ- const מהווה חלק מחתימתה. יתכנו שתי מתודות עם אותו שם ואותם פרמטרים, אך אחת const והשנייה לא. class C { … inf f();// will be called for non const objects int f() const; // will be called for const objects }; )ניתן לשנות שדות גם במתודה שהיא const אם השדות סומנו בתור mutable. לא רצוי לעשות זאת ללא סיבה טובה(.

36 36 member function overloading בדומה ל function overloading ניתן להגדיר גם מספר מתודות בעלות שם זהה, אולם עם חתימה שונה. class calculator { … double pow(double, double); double pow(double, int); int pow(int, int); … יכולת זו שימושית במיוחד עבור constructors (בהם אולי כבר נתקלתם בהרצאות ושעליהם נעבור בתרגול הבא) ניתן להגדיר מספר constructors אשר כל אחד מקבל פרמטרים שונים וכך לאפשר מספר צורות אתחול.

37 37 inline functions I קריאה לפונקציות הנה פעולה בעלת תקורה יקרה. עבור פונקציות פשוטות חבל לשלם מחיר זה. ב-C היינו נעזרים ב MACRO. ב-++C נעזר ב inline function. inline function מוגדרת כפונקציה לכל דבר, אולם קומפיילר חכם יבחר לממש אותה בצורה שתמנע את התקורה של פונקציה רגילה. למשל, על ידי השתלת גוף הפונקציה בנקודת הקריאה בדומה למקרו. הדבר עלול לגרום לניפוח קוד ולא תמיד אפשרי (רקורסיה … ) אך לעתים קרובות מייעל את הקריאה לפונקציה.

38 38 inline functions II ניתן להגדיר inline function בשתי דרכים –כחלק מהגדרת המחלקה: class Stack { int _size, top_index; int* array; public: int size() { return _size ;} –להוסיף inline לפני המימוש. בכל מקרה על פונקציה זו להיות ממומשת ב-header file. class Stack { int _size, top_index; int* array; public: int size() }; inline int Stack::size() { return _size ;}

39 39 קלט / פלט ב ++C יתרונות ++C: הקומפיילר מזהה את טיפוסי המשתנים לבד (חוסך טעויות). בקלט, משתמשים במשתנים - לא בכתובותיהם (חוסך טעויות וגם יותר “נקי”). Input / Output in C++: #include int j, k = 123; double d; cout << “A string” << k; cin >> j >> d; Input / Output in C: #include int j,k = 123; double d; fprintf (stdout,“%s %d”, “A string”, k); fscanf (stdin, “%d %lf”, &j, &d); ב ++ C קלט ופלט מתבצע ע”י “הזרמת” נתונים באמצעות האופרטורים >> ו-<<.

40 40 ערוצים סטנדרטים ב-++ C הקלט והפלט ב -++C נעשה ע " י ערוצים (streams). ערוצים הם מחלקות מיוחדות המוגדרות כחלק מהספרייה הסטנדרטית של ++C. הקלט והפלט של עצם מתבצעים ע " י שימוש בפונקציות ואופרטורים המוגדרים עבור מחלקה זו. מחלקות אלו מוגדרות בקובץ iostream, ולכן על מנת להשתמש בהם צריכה להופיע בתחילת הקובץ השורה : #include אופרטורי הקלט והפלט חכמים יותר מפקודות הקלט / פלט של שפת C בכך שאין צורך לציין את סוג המשתנים. ערוצי הפלט מוגדרים במחלקה ostream. קיימים שני ערוצי פלט סטנדרטיים : – ערוץ הפלט הסטנדרטי - cout – ערוץ הודעות השגיאה הסטנדרטי - cerr ערוצי הקלט מוגדרים ע " י המחלקה istream. קיים ערוץ קלט סטנדרטי אחד - cin.

41 41 קלט פלט ב ++C פלט מתבצע ע " י הזרמת נתונים לתוך ערוץ הפלט הרצוי. האופרטור המשמש להזרמת נתונים לתוך ערוץ פלט הוא ">>". ה " הזרמה " נעשית ע " י פקודה מהצורה : ניתן גם להשתמש בפונקציה put על מנת לפלוט נתונים, בצורה הבאה :.put( ); לדוגמא, נניח כי x הוא משתנה שלם וערכו 3, ו - y הוא משתנה ממשי שערכו 2.45 cout << "hello " << x << " " << (x+y); הדוגמה לעיל תדפיס : hello 3 5.45 קלט מתבצע ע " י שאיבת נתונים מתוך ערוץ הקלט. האופרטור המשמש לשאיבת נתונים מתוך ערוץ קלט הוא "<<". ה " שאיבה " נעשית ע " י פקודה מהצורה : >> ניתן גם להשתמש בפונקציה get על מנת " לשאוב " נתונים, בצורה הבאה :.get( ); דוגמא : cin >> x >> y; קורא לתוך x את הנתון הראשון המופיע בקלט ולתוך y את הנתון השני המופיע בקלט.

42 42 דוגמא לקלט ופלט דוגמא : תוכנית זאת קוראת את מה שמופיע בקלט תו אחר תו ומדפיסה את התוים עד שמופיע הסימן לסוף קובץ. #include main() { char x; while (!(cin.eof())) { cin >> x; cout << x; } } ערוצי הקלט וערוצי הפלט הם אובייקטים. ישנן מתודות נוספות אשר ניתן להפעיל על אובייקטים אילו. למשל : הפונקציה eof(), הבודקת אם בערוץ מופיע סימן סוף קובץ. דוגמא נוספת היא הפונקציה width() הקובעת את מספר התווים המינימלי אשר יודפסו בהדפסה הבאה של מחרוזת ומספר, והפונקציה fill() אשר קובעת את התו שיודפס במידה והמחרוזת / מספר קצרים מהנדרש. לדוגמא : cout.width(4); cout.fill(‘#’); cout<<“(“<<12<<“), (“ << 12 << “)\n”; הפלט המתקבל : ###(12),(12)

43 43 ערוצי קבצים שימוש בערוצי קבצים דומה למדי לשימוש בערוצי ק / פ. ערוצי הקבצים הם מחלקות הנורשות מערוצי הק / פ הרגילים ולכן כל הפעולות המוגדרות על ערוצים רגילים מוגדרים גם על ערוצי קבצים. מחלקות אלו מוגדרות בקובץ fstream.h, ולכן על מנת להשתמש בהם צריכה להופיע בתחילת הקובץ השורה : #include ערוצי הקלט מקבצים מוגדרים ע " י המחלקה ifstream. למחלקה זו יש constructor המקבל כקלט מחרוזת ופותח את הקובץ ששמו ערך המחרוזת. ערוצי הפלט לקבצים מוגדרים ע " י המחלקה ofstream. למחלקה זו יש constructor המקבל כקלט מחרוזת ופותח את הקובץ ששמו ערך המחרוזת.

44 44 דוגמא לעבודה עם קבצים #include void copy_file(char *a, char* b) { ifstream from(a);// Open the file a if(!from.is_open()) { // if(!from){ cerr << "cannot open file " << a; exit(1); } ofstream to(b);// Open the file b if(!to.is_open()) { // if(!to){ cerr << "cannot open file " << b; exit(1); } char c; while (!(from.eof())) { if (from.get(c)) to.put(c); }


Download ppt "1 מבחן מועד ג' סמסטר אביב -2006 אשכול מחשבים (Cluster) הוא קבוצה של מחשבים המחוברים ביניהם ופועלים יחד בצורה מתואמת, כך שבמובנים רבים הם יכולים להיחשב."

Similar presentations


Ads by Google