תרגול 8 היכרות עם ++C. C++ מעל שפת Cשפת תכנות שנבנתה מעל שפת C CC++ –כמעט כל תכנית ב -C היא גם תכנית ב C++ עד כדי מספר הבדלים קטן C99C שאימץ כמה מהתכונות.

Slides:



Advertisements
Similar presentations
ממיבחניםC שאלות ++.
Advertisements

תוכנה 1 סמסטר א ' תשע " ב תרגול מס ' 7 * מנשקים, דיאגרמות וביטים * לא בהכרח בסדר הזה.
מבוא למדעי המחשב לתעשייה וניהול
בתרגול הקודם הורשה: –ניתן להרחיב רק מחלקה אחת –כל מה שלא private – עובר בהורשה –המילה השמורה super –יצירת היררכיה –Object היא שורש ההיררכיה –דריסה אופרטור.
1 תוכנה 1 תרגול 14 – סיכום. 2 קצת על מנשקים מנשק יכול להרחיב יותר ממנשק אחד שירותים במנשק הם תמיד מופשטים וציבוריים public interface MyInterface { public.
טבלאות סמלים נכתב ע"י אלכס קוגן סמסטר חורף, תשס"ח.
Pointers הרצאה קריטית. השאלות הפתוחות מה זה ה- & שמופיע ב scanf מדוע כשמעבירים מחרוזת ל scanf אין צורך ב & האם ניתן להכריז על מערך שגדלו אינו ידוע בתחילת.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב'
1 מבחן מועד ג' סמסטר אביב אשכול מחשבים (Cluster) הוא קבוצה של מחשבים המחוברים ביניהם ופועלים יחד בצורה מתואמת, כך שבמובנים רבים הם יכולים להיחשב.
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
1 מבוא למדעי המחשב משתנים. 2  סוגי משתנים בשפת C  ההבדלים בין סוגי המשתנים השונים.
1 נושאי התרגול : Copy constructor Assignment operator המרת טיפוסים אוטומטיות. תכנות גנרי - Templates.
תרגול 5 רקורסיות. רקורסיה קריאה של פונקציה לעצמה –באופן ישיר או באופן עקיף היתרון : תכנות של דברים מסובכים נעשה ברור ונוח יותר, מכיוון שזו למעשה צורת.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
חורף - תשס " ג DBMS, צורות נורמליות 1 צורה נורמלית שלישית - 3NF הגדרה : תהי R סכמה רלציונית ותהי F קבוצת תלויות פונקציונליות מעל R. R היא ב -3NF.
מבוא למדעי המחשב © אריק פרידמן 1 מצביעים כמערכים דוגמה.
תרגול חזרה. מבנה האובייקט תאר את מבנה האובייקט כולל מבנה טבלאות הפונקציות הוירטואליות עבור התכנית הבאה struct A { int x; virtual void a() {}; }; struct.
Formal Specifications for Complex Systems (236368) Tutorial #6 appendix Statecharts vs. Raphsody 7 (theory vs. practice)
חלון הפקודות מיועד לבצע פעולה אחת בכל פעם. כיצד אפשר לבצע רשימת פקודות או אפליקציות מורכבות ?
1 מבוא למדעי המחשב מבנה של תכנית. 2 מבנה של תכנית – חלוקה לקבצים  תכנית בשפת C הינה אוסף של הגדרות של:  משתנים (חיצוניים)  פונקציות  ניתן לפרוש תכנית.
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
Backpatching 1. תזכורת מתרגול קודם קוד ביניים - שפת הרביעיות שיטות לייצור קוד ביניים –שימוש בתכונת code –כתיבה ישירה ל-buffer של פקודות שיטות לתרגום מבני.
תכנות תרגול 10 שבוע : הקשר בין מערכים למצביעים נרצה לעמוד על הקשר בין מערך למצביע מאחר ומערכים הם הכללה של משתנים הרי שברור שלמערך ולכל אחד מאיבריו.
תרגול 10: הכרות עם ++C ++C כ- C משופר
תרגול 8 היכרות עם ++C. C++ מעל שפת Cשפת תכנות שנבנתה מעל שפת C –כמעט כל תכנית ב -C היא גם תכנית ב C++ עד כדי מספר הבדלים קטן C99 שאימץ כמה מהתכונות C++
תכנות תרגול 5 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
מבוא למדעי המחשב תרגול 3 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
1 נושאי התרגול : Copy constructorCopy constructor Assignment operatorAssignment operator המרת טיפוסים אוטומטיות המרת טיפוסים אוטומטיות תכנות גנרי – Templates.
תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי
תרגול 10: הכרות עם ++C היכרות עם ++C
מבוא כללי למדעי המחשב הקצאת זיכרון דינאמית
מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל :
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
אתחול עצמים. אתחולים ובנאים יצירת מופע חדש של עצם כוללת: הקצאת זכרון, אתחול, הפעלת בנאים והשמה לשדות במסגרת ריצת הבנאי נקראים גם הבנאי/ם של מחלקת הבסיס.
Structure. מה לומדים היום ? דרך לבנות מבנה נתונים בסיסי – Structure מייצר " טיפוס " חדש מתאים כאשר רוצים לאגד כמה משתנים יחד דוגמאות : עובד : שם, טלפון,
הגדרת משתנים יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר.
Methods public class Demonstrate { public static void main (String argv[]) { public static void main (String argv[]) { int script = 6, acting = 9, directing.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 7. סברוטינות subroutines.
שיאון שחוריMilOSS-il מוטיבציה  python זה קל ו C זה מהיר. למה לא לשלב?  יש כבר קוד קיים ב C. אנחנו רוצים להשתמש בו, ולבסס מעליו קוד חדש ב python.
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
מבנים קרן כליף. ביחידה זו נלמד :  מהו מבנה (struct)  איתחול מבנה  השמת מבנים  השוואת מבנים  העברת מבנה לפונקציה  מבנה בתוך מבנה  מערך של מבנים.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
1 תרגול 11: Design Patterns ומחלקות פנימיות אסף זריצקי ומתי שמרת 1 תוכנה 1.
1 נתבונן בפונקציה הבאה public static int min(int[] a,int n) { int min = a[0]; for (int i = 1; (i < n ) && (i < a.length) ; i++) if (min > a[i]) min = a[i];
עקרונות תכנות מונחה עצמים תרגול 11: OOP in C++. Outline  Where do the objects live ?  Inheritance  Slicing  Overriding vs Shadowing.
מחרוזות – הטיפוס String
Object Oriented Programming
Object Oriented Programming
Operators Overloading
Object Oriented Programming
Object Oriented Programming
מחלקות classes.
תרגול מס' 7 משתנים מיוחסים מבוא ל-C++ קלט/פלט ב-C++
מבוא לתכנות מונחה עצמים Object Oriented Programming
תוכנה 1 תרגול 13 – סיכום.
תוכנה 1 תרגול 13 – סיכום.
מצביעים קרן כליף.
הקצאת זיכרון דינאמית מבוא כללי למדעי המחשב
ניתוח מערכות מידע תכנות ב C#
סוגי משתנים קרן כליף.
מערכים של מצביעים הקצאה דינאמית
מבוא לתכנות מונחה עצמים Object Oriented Programming
תוכנה 1 תרגול 13 – סיכום.
תכנות מכוון עצמים ו- C++ יחידה 02 העמסת פונקציות, ערכי ברירת מחדל, enum, קימפול מותנה קרן כליף.
תוכנה 1 תרגול 13 – סיכום.
תירגול 8:מצביעים והקצאה דינאמית
Presentation transcript:

תרגול 8 היכרות עם ++C

C++ מעל שפת Cשפת תכנות שנבנתה מעל שפת C CC++ –כמעט כל תכנית ב -C היא גם תכנית ב C++ עד כדי מספר הבדלים קטן C99C שאימץ כמה מהתכונות C++ C99 - סטנדרט של C, שאימץ כמה מהתכונות של C++ g++הקומפיילר של C++ שאנחנו נשתמש בקורס הוא g++ לקבצי C++ נהוג לתת סיומות –.h לקובץ header, כמו ב -C –.cpp לקובץ מימוש (source file) 2

הערות ב C++ // ועד סוף השורה C99 –גם ב -C99 –ניתן להשתמש גם ב -C-style הערות /*... */ int foo(int n) { // this is a C++ comment int i = 7; // this is another C++ comment /* this is a C style comment */ return n+i; } 3

הגדרת משתנים ב C++ ב C++ ניתן להגדיר משתנים לא רק בתחילת בלוק –גם ב -C99 int foo(int size){ int i; SetResult setResult; ListResult listResult;... for(i = 0; i < size; ++i)... setResult = setCreate(...); for(i = 0; i < size; ++i)... listResult = listCreate(...);... { int foo(int size){... for(int i = 0; i < size; ++i)... SetResult setResult = setCreate(...); for(int i = 0; i < size; ++i) ListResult listResult = listCreate(...);... { עדיף להכריז על משתנים כמה שיותר קרוב לשימוש הראשון שלהם C before C99 C++/C99 4

זיכרון דינמי ב C++: הקצאת עצמים בודדים int *pi = new int ; *pi = 6;... delete pi; int *pi = (int*)malloc(sizeof(int)) ; if(pi == NULL){... /* out of memory */ } *pi = 6;... free(pi); C++ new type new type; delete pointer delete pointer; C malloctype malloc(sizeof(type)); freepointer free(pointer); אין צורך ב -casting אין צורך בבדיקת תוצאה של new 5

זיכרון דינמי ב C++: הקצאת מערכים int elements_number =...; int *pi = new int[elements_number]; pi[3] = 6;... delete[] pi; int elements_number =...; int *pi = (int*)malloc(sizeof(int) * elements_number) ; if(pi == NULL){... /* out of memory */ } pi[3] = 6;... free(pi); C++ new type[#elements] new type[#elements]; delete[] pointer delete[] pointer; C malloctype*#elements malloc(sizeof(type)*#elements); freepointer free(pointer); 6

זיכרון דינמי ב C++ לא נהוג free/mallocב C++ מותר אך לא נהוג להשתמש בפונקציות free/malloc new/delete –בכל מקרה, אסור לערבב בין new/delete ו - free/malloc freeאסור להפעיל free על הזיכרון שהוקצה על ידי new delete mallocאסור להפעיל delete על הזיכרון שהוקצה על ידי malloc 7

זיכרון דינמי ב C++ חייבים להתאים newdeleteחייבים להתאים בין סוגי new ו -delete – delete new – delete אחרי new – delete[]new[] – delete[] אחרי new[] מותר להפעיל NULLמותר להפעיל delete על NULL if(ptr != NULL) { delete ptr; } 8

const ב C++ לשם טיפוסקבועתוספת לשם טיפוס, מציינת טיפוס של קבוע const type const –משתנים מסוג const חייבים לאתחלחייבים לאתחל לא ניתן לבצע השמהלא ניתן לבצע השמה C99קיים גם ב -C99 #define MAX_SIZE 120 const int maxSize = 120; C before C99 C++/C99 9

const ב C++ i = 7; // OK. initialization to 7 const int i = 7; // OK. initialization to 7 i = 17; // error: assignment to a const variable j; // error: definition of a const variable const int j; // error: definition of a const variable // without initialization // without initialization // assignment of a const variable to a int k = i; // assignment of a const variable to a // non const variable // non const variable const int intArray[] = { 7, 17, 27, 777 } // error: assignment to a const intArray[2] = 8; // error: assignment to a const שימו לב להבדל בין אתחול להשמה 10

מצביעים ל -const ב C++ להגדיר מצביעיםניתן להגדיר מצביעים לטיפוסים קבועים const type* למשל, const int* pi; מצביע pi הוא משתנה מסוג מצביע ל - const int –יכול להחזיק כתובות של משתנים מסוג const int typeconst type*ניתן לבצע השמה של כתובת של משתנה מטיפוס type לתוך מצביע מטיפוס const type* ניתן להמיר –בפרט, ניתן להמיר int* ל const int*- –אך לא להפך 11

מצביעים ל -const ב C++ באילו ביטוים יש שגיאה ? const int i = 7; const int* cpi = &i; *cpi = 17; int j = 17; int* pi = &j; cpi = &j; cpi= pi; pi = cpi; 12

שימוש ב -const בפונקציות : פרמטרים פרמטרים לפונקציהניתן להגדיר כ - const פרמטרים לפונקציה –חשוב מאוד מצביעים –חשוב מאוד עבור פרמטרים שהם מצביעים /* this function changes values pointed by i,f does not change values pointed by c,d */ int foo(int* i, char* c, float*f, double* d); int foo(int* i, const char* c, float*f, const double* d); C before C99 C++/C99 חוסך תיעוד הקומפיילר מוודא שלא משנים פרמטרים שהם const 13

שימוש ב -const בפונקציות : ערכי חזרה ערכי חזרה של פונקציהניתן להגדיר כ - const ערכי חזרה של פונקציה –חשוב מאוד מצביעים –חשוב מאוד עבור ערכי חזרה שהם מצביעים /* please do not change the returned string !!! */ char* foo(int i); const char* foo(int i); C before C99 C++/C99 חוסך תיעוד הקומפיילר מוודא שלא משנים ערכי חזרה שהם const 14

Reference type& = ; שם נוסף reference הוא שם נוסף למשתנה קיים לדוגמה : &int referenceint הביטוי &int משמעותו reference לטיפוס int לא לבלבל " הכתובת של משתנה "x – לא לבלבל עם &x שמשמעותו " הכתובת של משתנה "x בפועל מתבצעתכל פעולה שמפעילים על reference, בפועל מתבצעת על המשתנה שה -reference מתייחס אליו int i = 7; int &j = i; 15

Reference חייב להיות מאותחל reference חייב להיות מאותחל לא ניתן לשנותלאחר האתחול לא ניתן לשנות את המשתנה שה -reference מתייחס אליו int i = 8 ; int &j = i; int x = i; i = 5 ; // i = j = 5, x = 8 j++; // i = j = 6, x = 8 j = x; // i = j = 8, x = 8 j = 7; // i = j = 7, x = 8 שימו לב : ההשמה מתבצעת ל -i j ממשיך להתייחס ל -i 16

השימוש העיקרי ב -Reference העברתפרמטרים החזרת ערכי חזרההעברת פרמטרים לפונקציות / החזרת ערכי חזרה ב -C העברת פרמטרים מתבצעת – by value – by pointer by referenceב C++ קיימת גם העברה by reference דוגמא : void foo(int &i) { i++; } int x = 7; foo(x); //error foo(5); //error 17

השימוש העיקרי ב -Reference כמו במקרה של העברה by pointer משתמשים בהעברה by reference כאשר תשנה משתנים מחוצה לה –רוצים שהפונקציה תשנה משתנים מחוצה לה –אובייקטים גדולים –אובייקטים גדולים - לא רוצים להעביר by value ולהעתיק void swap(int* p, int* q) { int t = *p ; assert(p != NULL); assert(q != NULL); *p = *q; *q = t ; } swap(&x,&y); void swap(int& p, int& q) { int t = p ; p = q; q = t ; } swap(x,y); // OK swap(x,5) ; // Error CC++ 18

הבדלים בין reference למצביע אתחולאתחול – reference חייב להיות מאותחל –מצביע לא חייב להיות מאותחל ערך NULLערך NULL –מצביע יכול להכיל ערך NULL –אין ל -reference ערך NULL. הוא חייב להתייחס למשתנה כלשהו שינוי הצבעה / התייחסותשינוי הצבעה / התייחסות –מצביע יכול לשנות משתנה שהוא מצביע אליו – reference יכול להתייחס למשתנה אחד בלבד 19

דוגמא נוספת לשימוש ב -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]; } מוחזר reference לאיבר האמצעי במערך מה היה קורה אם היינו מחזירים sum ? 20

Function Overloading: הבעיה פונקציה מקסימום של שני שלמיםנניח, אנחנו רוצים לכתוב ב -C פונקציה שמחזירה מקסימום של שני שלמים : int max(int x, int y); פונקציה מקסימום של שלושה שלמיםנניח שבנוסף אנחנו רוצים פונקציה שמחזירה מקסימום של שלושה שלמים. – איזה שם ניתן לה ? –השם max כבר תפוס על ידי פונקציה קודמת int max3(int x, int y, int z); פונקציה מקסימום של שני floatsואם נרצה פונקציה שמחזירה מקסימום של שני floats ? float max_float(float x, float y); 21

Function Overloading: הפתרון ב C++ אותו שם לכל פונקציותאותו שם לכל פונקציות המקסימום ! max int max(int x, int y); max int max(int x, int y, int z); max float max(float x, float y); מאמץ מחשבתיחוסכים מאמץ מחשבתי בהמצאת שמות חדשים קצרים וטבעייםהשמות יוצאים קצרים וטבעיים יותר קריאות –משפר קריאות 22

Function Overloading: איך זה עובד ? השםוגם הפרמטריםהפונקציה מזוהה על ידי השם שלה וגם על ידי הפרמטרים שהיא מקבלת קריאה לפונקציהכשהקומפיילר מזהה קריאה לפונקציה כלשהיא הוא המועמדות –מחפש כל הפונקציות עם אותו שם - המועמדות להיקרא המועמדותשמתאימה ביותר לפי הפרמטרים –מבין כל המועמדות, מחפש פונקציה שמתאימה ביותר לפי הפרמטרים " מנצחת יחידה "אם יש " מנצחת יחידה " היא זאת שנקראת " מנצחת יחידה " שגיאת קומפילציהאם אין " מנצחת יחידה " יש שגיאת קומפילציה –דו - משמעות (ambiguity) 23

:Function Overloading כללים להתאמה 1.exact match trivial conversions 1.exact match ( + trivial conversions: int ->int&, int to const int) promotions 2.match with promotions (char,short int -> int, float->double) conversions 3.match with conversions (int->float, float -> int) user defined type conversions 4.match with user defined type conversions ellipsis 5.match with ellipsis (…) נלמד user defined type conversions בהמשך elipsis מחוץ לחומר של הקורס 24

:Function Overloading כללים להתאמה לא נבדלות ערך מוחזרהפונקציות לא נבדלות על ידי ערך מוחזר אסור עם אותו שם ואותם פרמטריםאסור שיהיו שתי פונקציות עם אותו שם ואותם פרמטרים –שגיאת קומפילציה foo(int i, float f) int foo(int i, float f) {... } foo(int i, float f) float foo(int i, float f) {... } שגיאת קומפילציה : foo עם הפרמטרים int ו - float כבר מוגדרת 25

:Function Overloading דוגמא 1.void print(int); 2.void print(const char *); 3.void print(double); 4.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”); 26

:Function Overloading דוגמא לדו משמעות 1.void foo(int i, float f); 2.void foo(float f, int i); int x,y; foo(x,y); // error - no best matching function foo(x,(float)y); // OK. the first foo is called foo((float)x,y); // OK.the second foo is called 27

Default Parameters: המוטיבציה שברוב המקריםערך קבועפרמטרקיימות פונקציות שברוב המקרים מקבלים ערך קבוע עבור פרמטר כלשהו במקרים נדירים ערך אחר –ורק במקרים נדירים ערך אחר הדפסת מספרים בבסיסים שוניםלרבלדוגמא : הדפסת מספרים בבסיסים שונים. לרב הבסיס יהיה 10 28

Default Parameters: המוטיבציה 29 void print_number(int n, int base ) ; void foo() {... print_number (24,8); print_number (12,10); print_number (x,10); print_number (y,10); print_number (16,2); print_number (24,10); print_number (12,10); print_number (x+2,10); print_number (y-7,10); print_number (30,16); print_number (24,10); print_number (12,10); print_number (x+2,10); print_number (y-7,10); print_number (30,10); } ברוב המקרים הפרמטר השני הוא 10. האם אפשר לחסוך את כתיבתו ?

Default Parameters: המוטיבציה Function Overloadingהפתרון האפשרי - שימוש ב -Function Overloading שתי פונקציותמגדירים שתי פונקציות : void print_number(int n, int base ); // print number in base 10 void print_number(int n) ; void print_number(int n) { print_number(n,10); } 30 שתי הפונקציות עושות כמעט אותו דבר. איך נמנע שיכפול קוד ?

Default Parameters: המוטיבציה 31 void print_number(int n, int base ) ; void foo() {... print_number (24,8); print_number (12,10); print_number (x,10); print_number (y,10); print_number (16,2); print_number (24, 10); print_number (12,10); print_number (x+2,10); print_number (y-7,10); print_number (30,16); print_number (24,10); print_number (12,10); print_number (x+2,10); print_number (y-7,10); print_number (30,10); } void print_number(int n, int base ) ; void print_number(int n) { print_number(n,10); } void foo() {... print_number (24,8); print_number (12); print_number (x); print_number (y); print_number (16,2); print_number (24); print_number (12); print_number (x+2); print_number (y-7); print_number (30,16); print_number (24); print_number (12); print_number (x+2); print_number (y-7); print_number (30); }

Default Parameters לחסוךכתיבת שתי הפונקציההאם אפשר לחסוך את כתיבת שתי הפונקציה print_number ? פרמטר ברירה מחדלהפתרון ב C++ - פונקציה אחת עם פרמטר ברירה מחדל (default parameter) = 10 void print_number(int n, int base = 10); שני פרמטרים כרגילכשקוראים לפונקציה עם שני פרמטרים, הקריאה מתבצעת כרגיל פרמטר אחדאוטומטית ערך ברירה מחדלכשקוראים לפונקציה עם פרמטר אחד, אוטומטית מוצב ערך ברירה מחדל במקום הפרמטר השני כרגיל –הפונקציה מתבצעת כרגיל, כאילו שקראו לה עם שני פרמטרים 32

Default Parameters זהותשתי הקריאות זהות מבחינת הפונקציה : 1.print_number(17,10); 2.print_number(17); אין שינוי מימושהצהרתהאין שינוי במימוש של הפונקציה - רק בהצהרתה רק פעם אחתאת ברירות מחדל של פרמטרים מציינים רק פעם אחת –בד '' כ בהצהרה על הפונקציה ב -header file void print_number(int n, int base = 10); void print_number(int n, int base) {... } 33

Default Parameters לפרמטרים האחרוניםניתן לתת ערכי ברירת מחדל רק לפרמטרים האחרונים : int foo(int a = 0, int b = 0, int c = 0); // OK int bar(int a, int b = 0, int c = 0); // OK int baz(int a = 0, int b = 0, int c); // Error int f(int a = 0, int b, int c = 0); // Error 34

Default Parameters 35 void print_number(int n, int base ) ; void print_number(int n) { print_number(n,10); } void foo() {... print_number (24,8); print_number (12); print_number (x); print_number (y); print_number (16,2); print_number (24); print_number (12); print_number (x+2); print_number (y-7); print_number (30,16); print_number (24); print_number (12); print_number (x+2); print_number (y-7); print_number (30); } void print_number(int n, int base = 10) ; void foo() {... print_number (24,8); print_number (12); print_number (x); print_number (y); print_number (16,2); print_number (24); print_number (12); print_number (x+2); print_number (y-7); print_number (30,16); print_number (24); print_number (12); print_number (x+2); print_number (y-7); print_number (30); }

מימוש ADTs ב ++C

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

ADTs ב ++C לעומת C ב -C מימשנו ADT בצורה הבאה : הממשק –קובץ header הכיל את הממשק הטיפוסהוגדר בו הטיפוס של ה -ADT פונקציותהוצהרו בו פונקציות המטפלות ב - ADT המימוש –בקובץ המימוש ((source הופיע המימוש של הפונקציות ב ++C הוטמעה צורת עבודה זו בשפה ניתן להגדיר טיפוסים ( מחלקות - classes) אשר כוללים בתוכם טיפוס –שדות של כל משתנה מאותו טיפוס ( אובייקט של אותה מחלקה ) –פונקציות –פונקציות ( מתודות ) המופעלות עליו 38 בשפות מונחות עצמים נהוג לקרוא לפונקציות ששייכות למחלקות - " מתודות " שמות נוספים : שיטה, method, member function

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

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

מימוש ב ++C:Source File void Stack::destroy () { delete[] array; } Result Stack::push(int element) { if (topIndex == size){ return Fail ; } array[topIndex] = element; topIndex++; return Success; } 41

מימוש ב ++C:Source File Result Stack::pop () { if (topIndex == 0){ return Fail; } topIndex--; return Success; } Result Stack::top (int& element) { if (topIndex < 1){ return Fail; } element = array[topIndex-1]; return Success; } 42

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

המצביע this שימו לב לאופן השונה בו נקראו הפונקציות ב - C וב ++C להעביר מצביע לאובייקט – ב -C נדרשנו להעביר מצביע לאובייקט ( מבנה ) עליו על הפונקציה לעבוד באופן שונה –ב ++C קראנו לפונקציה של המחלקה באופן שונה : stack.top(i); לאיזה אובייקטכיצד הפונקציה יודעת לאיזה אובייקט התכוונו כאשר קראו לה ? 44

המצביע this פרמטר סמוי thisהתשובה : כאשר נקראת מתודה כלשהי נשלח לה פרמטר סמוי בשם this מצביע למחלקה –טיפוסו הנו מצביע למחלקה בה מוגדרת המתודה מצביע לאובייקט –מכיל מצביע לאובייקט עליו נקראה המתודה בכל גישה שדהמתודה thisבכל גישה לשדה של האובייקט או למתודה שלו מתוך מתודה אחרת הקומפיילר מוסיף הצבעה דרך this void Stack::top(int& e) { e = array[topIndex-1]; } void Stack::top(int& e) { e = this->array[this->topIndex-1]; } המתודה, לאחר שהקומפיילר הוסיף את המצביע this 45

הביעה : הסתרת מידע struct Stack { int* array; int size, topIndex ; Result init (int size) ; void destroy() ; Result push (int e); Result pop (); Result top(int& e); Result print(); } ; 46 מה הבעיה עם המחלקה הזאת ? רמז : איזה עיקרון חשוב של ADT הופר פה ? אין הסתרת מידע ! כל השדות חשופים ! המשתמש יכול לגשת לשדות של המחלקה ישירות ולעקוף את הפונקציות

הפתרון : בקרת גישה לא מסתירים את מבנהב C++ להבדיל מ -ADTs ב -C לא מסתירים את מבנה המחלקה ( השדות שלה ) מגבילים גישהבמקום זה מגבילים גישה לשדות שלה –וגם לפונקציות " הפנימיות " של ADT access modifiersמשתמשים ב -access modifiers ( מאפייני גישה ) – private – private ( פרטי ) רק הפונקציות של המחלקהרק הפונקציות של המחלקה יכולות לגשת לאיברים שהם private – public – public ( ציבורי ) כל פונקציהכל פונקציה יכולה לגשת לאיברים שהם public 47

מחלקה Stack עם access modifiers 48 struct Stack { int* array; int size, topIndex ; Result init (int size) ; void destroy() ; Result push (int e); Result pop (); Result top(int& e); Result print(); } ; struct Stack { private: int* array; int size, topIndex ; public: Result init (int size) ; void destroy() ; Result push (int e); Result pop (); Result top(int& e); Result print(); } ;

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

שמוש ב -class במקום struct מחלקות class structמקובל להגדיר מחלקות על ידי המילה השמורה class ולא struct struct classההבדל בין struct ל- class: classprivate –ב-class, אם לא צוין אחרת, אופן הגישה הנו private structpublic –ב-struct, אם לא צוין אחרת, אופן הגישה הנו public struct נהוג למחלקות ללא מתודותב-struct נהוג למשתמש לייצוג מחלקות ללא מתודות 50

struct Stack { private: int* array; int size, topIndex ; public: Result init (int size) ; void destroy() ; Result push (int e); Result pop (); Result top(int& e); Result print(); } ; שמוש ב -class במקום struct 51 class Stack { int* array; int size, topIndex ; public: Result init (int size) ; void destroy() ; Result push (int e); Result pop(); Result top(int& e); Result print(); } ;

בקרת גישה : Friend functions class Stack { friend friend int second (const Stack &); int* array; int size, topIndex; public: … } int second(const Stack stack&) { assert(stack.topIndex > 1); return stack.array[stack.topIndex-2]; } בצורה סלקטיביתניתן לתת גישה לחלק הפרטי של המחלקה בצורה סלקטיבית friends –מגנון friends פונקציה friend המחלקהניתן להכריז על פונקציה כלשהיא כחברה (friend) של המחלקה לגשת לשדות הפרטיים המחלקה –אז היא יכולה לגשת לשדות הפרטיים של המחלקה 52

Friend classes and Methods class A { …. int foo(); … }; class B { … }; class C { friend int A::foo(); friend class B; }; מחלקה שלמהכחברהניתן להכריז על מחלקה שלמה כחברה של מחלקה כלשהיא –אז כל המתודות שלה חברות –אז כל המתודות שלה הן חברות של המחלקה 53 method foo() of class A is a friend of class C all methods of class B are friends of class C

Friends ב C++: נקודות נוספות שמחלקה A חברה של מחלקה B לא נגררשמחלקה B היא חברה של מחלקה Aמהעובדה שמחלקה A חברה של מחלקה B לא נגרר שמחלקה B היא חברה של מחלקה A שמחלקה A חברה של מחלקה B ומחלקה B חברה של מחלקה C לא נגרר שמחלקה A היא חברה של המחלקה Cמהעובדה שמחלקה A חברה של מחלקה B ומחלקה B חברה של מחלקה C לא נגרר שמחלקה A היא חברה של המחלקה C 54

מודולאריות, הסתרת מידע ו -friends להסתירמחלקה טובה צריכה להסתיר כמה שיותר " פאראנוידית " –כמה שיותר " פאראנוידית " לגבי השדות שלה לא נחוץמשתמשים חיצוניים private –כל מה שלא נחוץ לשימוש שלה על ידי משתמשים חיצוניים צריך להיות private בררנית " החברים " –כמה שיותר בררנית לגבי " החברים " שלה סוציומאטית "friends –כמה שיותר " סוציומאטית "- כמה שפחות friends friend פוגעתכל הוספה של friend פוגעת במודולאריות והסתרת מידע 55

const member functions: מוטיבציה פונקציה כפרמטרנניח יש לנו פונקציה שמקבלת כפרמטר const Stack& const Stack& : void foo(const Stack& stack) {... stack.top(i);... stack.push(j); stack.print(); } 56 מה הבעיה בפונקציה הזאת ? הפונקציה מקבלת פרמטר const, אך משנה אותו על ידי פונקציה push

const member functions אובייקט const רק למתודות constהפתרון ב C++: על אובייקט שהוא const מותר לקרוא רק למתודות שהן const המתודה const const בסוף החתימהניתן להכריז על המתודה כ -const על ידי הוספת מילה שמורה const בסוף החתימה שלה 57 class Stack { int* array; int size, topIndex ; : public: Result init (int size) ; void destroy() ; Result push (int element); Result pop(); Result top(int& element); Result print(); } ; class Stack { int* array; int size, topIndex ; : public: Result init (int size) ; void destroy() ; Result push (int element); Result pop(); const Result top(int& element) const; const Result print() const; } ;

const member functions void foo(const Stack& stack) {... stack.top(i); // OK, top is a const function... stack.push(j); // Error ! Calling a non-const // function on a const object stack.print(); // OK, top is a const function } 58

const member functions מתודה const חלק מחתימתההגדרת מתודה כ - const מהווה חלק מחתימתה שתי מתודות אותו שם ואותם פרמטרים constיתכנו שתי מתודות עם אותו שם ואותם פרמטרים, אך אחת const והשנייה לא class C { … int foo();// will be called for non const objects int foo() const; //will be called for const // objects }; 59

Const Correctness const בטיחותיתככל שתשתמשו ב -const יותר - התוכנה תהיה בטיחותית יותר משתנה שלא אמור להשתנות עדיף שיהיה const –כל משתנה שלא אמור להשתנות עדיף שיהיה const פרמטר לא אמורה לשנות צריך להיות const –כל פרמטר של פונקציה by pointer או by reference שהפונקציה לא אמורה לשנות - צריך להיות const פונקציהשלא משנה את האובייקט צריכה להיות const –כל פונקציה, שלא משנה את האובייקט עליו היא נקראת, צריכה להיות const יתרונות : 1. תיעוד 2. וידוא אוטומטי על ידי הקומפיילר 60

הבעיה : התנגשות של שמות תוכנה בנקאיתהבעיה : נניח אנחנו כותבים תוכנה בנקאית כמה חבילותהתוכנה מורכבת מכמה חבילות - packages) חלקי קוד גדולים ) 1.Clients 2.Investments 3.GUI 4.DB בכל אחת מהחבילותבכל אחת מהחבילות קיימת מחלקה Account ופונקציה reportError התנגשות של שמותאיך נמנע התנגשות של שמות ? איך נבדיל איך נבדיל בין Account של Client וה -Account של GUI ? 61

הפתרון של C נוסיף קידומתנוסיף קידומת לכל שם בכל חבילה : 62 class clientsAccount {... }; void clientsPrintError(char*); class investmentsAccount {... }; void investmentsPrintError(char*); class dbAccount {... }; void dbPrintError(char*); class guiAccount {... }; void guiPrintError(char*);

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

הפתרון של C++: namespaces 64 namespace Clients { class Account {... }; void printError(char*); } namespace Investements{ class Account {... }; void printError(char*); } namespace DB { class Account {... }; void printError(char*); } namespace GUI{ class Account {... }; void printError(char*); }

שימוש בשמות של עם namespace void foo() { Clients::Account account;... Clients::printError(...);... GUI::printError(...); } 65

namespaces: הוראה using לחסוך usingניתן לחסוך ציון namespace על ידי שימוש בהוראה using : using namespace Clients; void foo() { Account account;... printError(...);... GUI::printError(...); } 66

namespaces: הוראה using יותר ספציפיים רק על מה שבאמת משתמשים בועדיף להיות יותר ספציפיים ולהפעיל using רק על מה שבאמת משתמשים בו –ולא להכליל כל השמות ללא צורך –ולא להכליל את כל השמות ב -namespace ללא צורך using Clients::Account; using Clients:: printError; void foo() { Account account;... printError(...);... GUI::printError(...); } 67

קלט / פלט ב ++C “הזרמת” נתוניםב ++ C קלט ופלט מתבצע ע”י “הזרמת” נתונים באמצעות האופרטורים >> ו-<<. משתמשים בערוצים (streams) הערוצים הסטנדרטיים הם – cin - ערוץ הקלט הסטנדרטי, כמו stdin ב -C – cout - ערוץ הפלט הסטנדרטי, כמו stdout ב -C – cerr - ערוץ השגיאות הסטנדרטי, כמו stderr ב -C iostream –מוגדרים בקובץ header סטנדרטי iostream ב -C++ קבצי ה -header הסטנדרטיים הם ללא סיומת.h std –נמצאים ב -namespace std 68

קלט / פלט ב ++C 69 #include int i = 17, j; double d; fprintf (stdout,“%s %d”, “A string”, i); fscanf (stdin, “%d %lf”, &j, &d); fprintf(stderr, “Error !\n”); #include using std::cin; using std::cout; using std::cerr; using std::endl; int i = 17, j; double d; cout << "A string " << i; cin >> j >> d; cerr << “Error!” << endl; C C++

קלט / פלט ב ++C: היתרונות הקומפיילר מזהה הטיפוסים בעצמוהקומפיילר מזהה את הטיפוסים של המשתנים בעצמו –חוסך התעסקות –חוסך התעסקות עם %d, %lf, %s וכו ' –חוסך טעיות –קוד קצר יותר וקריא יותר על משתנים ולא על הכתובותהקלט עובד על משתנים ולא על הכתובות שלהם –חוסך טעויות –חוסך טעויות ב -scanf/fscanf –קוד קצר יותר וקריא יותר 70

inline functions תקורה יקרהקריאה לפונקציות הינה פעולה בעלת תקורה יקרה יחסית –הכנה של מחסנית הקריאות –ביצוע קפיצה לפונקציה –ביצוע קפיצה חזרה פונקציות קטנות כדאי לחסוךעבור פונקציות קטנות יכול להיות כדאי לחסוך מחיר זה MACROב -C היינו משתמשים ב -MACRO inline functionב ++C נשתמש ב -inline function 71

inline functions inline function שהמתכנת ממליץ לקומפיילר inline inline function היא פונקציה שהמתכנת ממליץ לקומפיילר לבצע לה inline –לשתול קוד של פונקציה במקומות שקוראים לה בדומה ל -MACRO אך עם יתרונות של פונקציה - בדיקת פרמטרים וכו ' מופיעה בקובץ.hמופיעה בקובץ.h הקומפיילר יבחרהקומפיילר יבחר האם לבצע inline לפי השיקולים שלו –לא תמיד אפשר –לא תמיד אפשר - רקורסיה –לא תמיד כדאי –לא תמיד כדאי - tradeoff בין חיסכון בפקודות לבין שיכפול קוד מכונה ( גודל קובץ ההרצה ) 72

:inline functions דרך אחת כחלק מהגדרת המחלקהמימוש של inline function כחלק מהגדרת המחלקה : class Stack { public: int getSize() { return size ; }... private: int size;... } 73

:inline functions דרך שנייה הוספת inline לפני המימושהוספת inline לפני המימוש של הפונקציה. ממומשת ב -header file – בכל מקרה על פונקציה זו להיות ממומשת ב -header file class Stack { public: int getSize();... private: int size;... }; inline int Stack::getSize() { return size ; } 74