Tutorial 10. Introduction to C++ שימו

Similar documents
הנכות 1 םוכיס לוגרת 13 1

הקלחמ ה תמרב ת ונ וכ ת (static members ) יליזרב דהוא Java תפשב ם דקת מ תונכת ביבא ל ת תטיסרבינוא

הנכות 1 םוכיס לוגרת 13 1

הנכות 1 םוכיס לוגרת 13 1

תוכנה 1. תרגול מספר 11: Static vs. Dynamic Binding מחלקות מקוננות Nested Classes

תרגול 3 מערכים ופונקציות

הנכות 1 םוכיס לוגרת 14 1

הנכות 1 תואיגש םע תודדומתהו תואלול,םי : כרעמ 2 לוגרת

הנכות 1 תואיגש םע תודדומתהו תואלול,םיכרעמ : לו 2 גרת

לתיכנות עם MATLAB Lecture 5: Boolean logic and Boolean expressions

לתיכנות עם MATLAB Lecture 5: Boolean logic and Boolean expressions

תוכנה 1 תרגול 2: מערכים, מבני בקרה ושגיאות

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

תוכנה 1 בשפת Java נושאים שונים בהורשה רובי בוים ומתי שמרת בית הספר למדעי המחשב אוניברסיטת תל אביב

תרגול 4 פונקציות. מבנה של פונקציה: public static <return value type> <function name> (<arg1 type> <arg1>, <arg2 type> <arg2>, ) { <function body> }

תכנות מונחה עצמים משחקים תשע"ו

מערכים שעור מס. 4 כל הזכויות שמורות דר ' דרור טובי המרכז האוניברסיטאי אריאל 1

תוכנה 1 ומחלקות פנימיות

תוכנה 1 תרגול 2: מערכים ומבני בקרה

Algorithms. Intro2CS week 5

ASP.Net Web API.

Simple Web Service. namespace MyService { public class Service1 : System.Web.Services.WebService {

תוכנה 1 תרגול מספר 13

תוכנה 1 תרגול מספר 13

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

תכנות מתקדם בשפת C משתנים

סכום (סדרת ערכים) אחרת - דוגמא: סכום-ספרות (num) אם < 10 num החזר 1 או אם = 0 = num החזר 0 public static int numofdigits (int num)

Introduction to Programming in C תרגול 8

Computer Programming A תרגול 9

לתיכנות עם MATLAB Lecture 5: Boolean logic and Boolean expressions

תוכנה 1 * לא בהכרח בסדר הזה

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

תרגול מספר 3: מערכים

מבוא למדעי המחשב תרגול 8 רשימה משורשרת כללית, Comparator

תוכנה 1. תרגול מספר 11: Static vs. Dynamic Binding מחלקות מקוננות Nested Classes בית הספר למדעי המחשב אוניברסיטת תל אביב

מבוא למדעי המחשב תירגול 2: מבוא למדעי המחשב מ' - תירגול 2

מבוא לתכנות בשפת C. Tzachi (Isaac) Rosen

ספרית התבניות הסטנדרטית (STL) כתיבת אלגוריתמים גנריים מצביעים חכמים. .vector. list iterator נכיר תחילה את האוסף הפשוט ביותר בספריה

$ gcc check.c. $ a.out. $ gcc check.c -o check. $ check. $ gcc -Wall check.c -o check. #include <stdio.h>

Programming in C תרגול 8

תוכנה 1 * לא בהכרח בסדר הזה

קורס תכנות שיעור שישי: מחרוזות, מצביעים

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

Practical Session - Heap

תוכנה 1 סמסטר א' תשע"א

משתנים שעור מס. 2 כל הזכויות שמורות דר ' דרור טובי המרכז האוניברסיטאי אריאל 1

תוכנה 1 טיפוסי השפה טיפוסים לא פרימיטיביים הטיפוסים הפרימיטיביים מחרוזות המרה למספרים תרגול 2: טיפוסי שפה, מחרוזות, מערכים ושגיאות

קורס תכנות כתובות בזיכרון כתובות בזכרון מצביעים וכתובות מצביעים וכתובות שיעור שביעי: מבנים, הקצאת זיכרון דינאמית האופרטור &

מבוא למדעי המחשב תירגול 3:

תוכנה 1 מערכים. Array Creation and Initialization. Array Declaration. Loop through Arrays. Array Creation and Initialization

תוכנה 1 מערכים. Array Creation and Initialization. Array Declaration. Array Creation and Initialization. Loop through Arrays

Practical Session No. 14 Topological sort,amortized Analysis

תוכנה 1 3 תרגול מס' מערכים ומבני בקרה

מבוא לתכנות ב- JAVA תרגול 5. Ipc161- practical session 5

תרגול 3 מערכים ופונקציות

מבוא למדעי המחשב תרגול 13: עצים בינאריים

תרגול 12. Standard Template Library כתיבת אלגוריתמים גנריים מצביעים חכמים

תרגול 6 רקורסיה ותכנות מונחה עצמים

קורס תכנות שיעור שני: שימוש במשתנים,

ב ה צ ל ח ה! אוניברסיטת בן גוריון בנגב מספר נבחן : תאריך המבחן: כ"ה תשרי תשע"ח 15/10/17 שמות המורים: ציון סיקסיק מיועד לתלמידי : א'

עקרונות שפות תכנות 2016 תרגול 8 Type Inference System. Substitution Interpreter.

מבוא לתכנות תוכנית שעור מס. 1 1 דר' דרור טובי, המרכז האוניברסיטאי אריאל בשומרון.

תור שימושים בעולם התוכנה

מחרוזות ב Java ותכנות מונחה בדיקות )Test Driven Development(

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

תרגול מס' 5: IO )קלט-פלט(

Amortized Analysis, Union-Find,

Engineering Programming A

במידה ולסעיף ניתנה תשובה ובנוסף נרשם לגבי הסעיף לא יודע/ת אזי הניקוד שיינתן

תוכנה 1. תרגול מס' 3 עבודה עם מחרוזות )Strings( מתודות )Methods( העברת פרמטרים

ת ונכת סרוק תורשוקמ תומישר :יעישת רועיש 1

תוכנה 1 * לא בהכרח בסדר הזה

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

מדעי המחשב 2 יחידות לימוד פתרון בחינת הבגרות פרק א. I x > a. פתרון 2: משפט switch

Smart Pointers Nir Adar

Nir Adar

Programming for Engineers in Python

Programming for Engineers in Python

Exams questions examples

תזכורת: עץבינארי מבוא למדעי המחשב הרצאה 24: עצי חיפוש בינאריים

רזח יליגרתו םי יראני ב ם

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

<exp> ::= <define> <cexp> <define> ::= ( define <var-decl> <cexp> ) / DefExp(var:VarDecl, val:cexp)

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

רשימות דילוגים Skip Lists

Java פעולות עוברות בירושה סביבת יסודות מדעי המחשב נספח הורשה

מבוא לתכנות מערכות מבחן מועד א' סמסטר חורף

שאלה 1 מהו הפלט של התוכנית הבאה:

דף הדרכה ליצירת שרת/ לקוח עם GUI

פתרון מוצע לבחינת מה"ט ב_שפת c מועד אביב תשע"ח, פברואר 8102 מחבר: מר שייקה בילו, מכללת אורט רחובות

תרגילים ופתרונות בשפת - C הסתעפויות

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

מבוא למדעי המחשב תרגול 12 מחסנית )Stack( memoization

פרק 15 טיפוס חדש: מבנים שימוש במבנים שימוש במבנים שימוש במבנים

Introduction to OOP. Contents:

מצליחה. 1. int fork-bomb() 2. { 3. fork(); 4. fork() && fork() fork(); 5. fork(); printf("bla\n"); 8. return 0; 9. }

Practical Session #4 - ADTs: Array, Queue, Stack, Linked List

Communication Networks ( ) / Spring 2011 The Blavatnik School of Computer Science, Tel-Aviv University. Allon Wagner

מבוא למדעי המחשב השפעת השינוי על סטודנט הרצאה 18: פולימורפיזם ומחלקות אבסטרקטיות אם ברצוננו ששכר הלימוד לא יעלה על 2500.

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

Transcription:

Introduction to ++ שימו תרגול זה אינו התרגול הרישמי של הקורס. הוא מבוסס על חוברת התרגולים אך מכיל שינויים, הסברים נוספים ודוגמאות שונות או נוספות.

+ + תוכנ ית רא שונה ב הכרו ת עם + + תרגול // First ++ program #include <iostream> int main() /* This is not a good program: we are not using ++ I/O */ printf( Hello World\n ); // But notice the new style for // one line remarks. return 0; // comment till end of line מה ההבדל בין <iostream.h> ו <iostream> השימוש ב - h. ב ++ הינו מישן.(deprecated) וזה אף פעם לא רעיון טוב להשתמש ב feature מיושן בקוד חדש. <iostream> מכיל פעולות ש - <iostream.h> אינו מכיל. <iostream> מוכרז ב std,namespace ואילו.global scope ב <iostream.h> max = 5; digits[3] = u ; int* max2= &max; const int* max3 = &max; int k; max3 = &k; const משתמשים ב - const כתחליף ל - #define const int max = 0; const char digits[] = 0, a, 2, c, 4, b ; מה יקרה במקרים הבאים? error warning nothing ב ++ 1

const למה יותר טוב להשתמש במשתנים const ולא ב?define // n1 can be changed Fred n1 = Fred(); // n2 can t be changed const Fred n2 = Fred(); const Read from right to left משתנים חיים ב scope אפשר לראות אותם ב debugger אפשר לקבל את הכתובת שלהם אפשר להעביר אותם by const reference הם לא יוצרים מילות מפתח חדשות בתוכנית // p1 points to Fred that is const - this Fred can t // be changed via p1 const Fred *p1; // p2 is a const pointer to Fred you can change the // Fred object via p2, but you can t change the pointer // p2 itself Fred* const p2; // p3 is a const pointer to a const Fred you can t // // change the pointer p3 itself, nor can you change the // Fred object via p3 const Fred* const p3; const שימוש נוסף הינו פרמטרים וערכי החזרה מפונקציות. void f1 (int* p); void f2 (const int* p); int* f3 (int* p); const int* f4 (int* p); const void f(const int* p1, int* p2) int i = *p1; // get the original value of *p1 *p2 = 7; // if p1 == p2, this will also change *p1 int j = *p1; // get the possibly new value of *p1 if (i!= j) std::cout << "*p1 changed, but not via pointer p1!\n ; int main() int x; f(&x, &x); // perfectly legal 2

+ + זיכר ון די נמי ב הקצאת אובייקטים בודדים: new type במקום malloc(sizeof(type)) שחרור אובייקטים בודדים: delete pointer במקום free(pointer) int *pi = new int; *pi = 6; delete pi; זיכר ון די נמי ב + + הקצאת מערך: elements] new type[# of שחרור מערך : array delete[] pointer to int *pi = new int[5]; pi[3] = 6; delete[] pi; שאלה: איך מקצים מערך דו מימדי? + + זיכר ון די נמי ב זיכר ון די נמי ב + + int** array; array = new int*[5]; for (int i = 0; i < 5; i++) array[i] = new int; for (int i = 0; i < 5; i++) delete array[i]; delete[] array; האם אפשר למחוק מצביעים שהוקצו עם new ע"י?free האם אפשר למחוק מצביעים שהוקצו עם malloc ע"י?delete בשום פנים ואופן לא! מערך דו מימדי למה להשתמש ב - new ולא ב?malloc onstructors/destructors בטיחות malloc מחזיר void* ואילו new.type* Overridability new הוא אופרטור ואילו malloc לא. 3

+ + זיכר ון די נמי ב זיכר ון די נמי ב + + האם צריך לבדוק שלא חזר NULL אחרי שעושים?new לא! new לא מחזיר.NULL האם צריך לבדוק שהמצביע אינו NULL לפני שעושים?delete לא! delete לא יעשה כלום אם המצביע שווה ל -.NULL מה קורה למעשה כשעושים?delete p מה יקרה אם שוכחים [] כאשר מוחקים מערך שהוקצא ע"י?new T[n] הדבר באחראיות המתכנת. לא תהיה שגיאת קומפילציה או זמן ריצה. כנראה.heap corruption אחרי Fred[n] Fred *p = new איך הקומפיילר יודע שישנם n ערכים לשחרר ע"י []p?delete קסם! Fread *p; p = new Fred; delete p; if (p!= NULL) p->~fread(); operator delete (p); מימוש אפשרי: בעת ההקצאה יוקצא תא נוסף בתחילת המערך ובו הקומפיילר ישמור את מספר סאיברים במערך. Reference reference הוא שם אחר (alias) למשתנה קיים. הביטוי &X משמעותו reference לטיפוס X (לא לבלבל עם X& שמשמעותו "הכתובת של משתנה X). reference חייב להיות מאותחל כאשר הוא נוצר כדי לדעת מי המשתנה הקיים שהוא "יתחפש" אליו. אתחול זה אינו השמה. לאחר האתחול לא ניתן להגיד ל - reference להתחפש למשתנה אחר - הוא "תקוע" עם מי שאתחל אותו. כל פעולה המופעלת על ה reference פועלת על המשתנה שהוא מהווה שם נוסף אליו. Reference int i = 8; int &j = i; int x = i; i = 5; // j = 5, x = 8 j++; // i = j = 6 4

Reference ב reference משתמשים בעיקר להעברת פרמטרים אל ומפונקציות. ב - יכולנו להעביר רק את ערכם של הפרמטרים ) by call.(value ב - + + נוכל להעביר את הפרמטרים עצמם. ) by call.(reference swap in void swap(int* p, int* q) int t = *p; *p = *q; *q = t; swap in ++ void swap(int& p, int& q) int t = p; p = q; q = t; swap(x, y); // OK swap(x, 5); // Error Reference מה עדיף reference או?pointer reference כשאפשר, pointer כשצריך... העברת פרמטרים גדולים by reference זולה יותר מהעברתם by value כי אין צורך להעתיקם. יוצא מהכלל כשרוצים להשתמש ב value - Sentinel משתמשים ב pointer NULL ונותנים לו משמעות מיוחדת. alias לאובייקט, לא יכול להיות alias הוא reference ל.NULL Reference Reference int& arraybounds(int* array, int size, int& max, int& min) int sum = 0; max = min = array[0]; for (int 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]; int main () int arr[] = 5, 4, 3, 2, 1; int min, max; int x = arraybounds(arr, 5, max, min); max = 5, min = 1, x = 3 int y = arraybounds(arr, 5, 5, min); error int z = arraybounds(arr, 5, max, min)++; max = 5, min = 1, z = 3 int w = &arraybounds(arr, 5, max, min) - arr; max = 5, min = 1, w = 2 return 1; 5

Function Overloading נניח נרצה לכתוב פונקציה המעלה בחזקה. double pow (double x, double y); נרצה מימוש שונה כאשר המעריך מטיפוס שלם. Function Overloading double pow (double x, double y); double pow (double x, int y); int pow (int x, int y); פתרון סטייל ++: פתרון סטייל : double pow_dd (double x, double y); double pow_di (double x, int y); int pow_ii (int x, int y); Function Overloading Function overloading ב ++ פונקציה מזוהה על פי שמה והפרמטרים שהיא מקבלת. כאשר ישנן מספר פונקציות בעלות שם זהה, הקומפיילר ינסה להחליט מהי הפונקציה ה קרובה ביותר מבחינת סוג הפרמטרים המועבר, ולה יקרא. אם הקומפיילר אינו מסוגל להחליט אזי הוא מוציא הודעה על שגיאת - ambiguity חוסר בהירות. בתהליך ההחלטה לא מתחשבים בטיפוס ערך ההחזרה של הפונקציה. מקובל להשתמש ב - Overloading Function כאשר יש פונקציות המבצעות פעולה דומה על טיפוסים שונים (לדוגמא pow או.(print 1 2 3 4 1 1 1 3 1 1 3 2 void print(int); void print(const char *); void print(double); void print(long); char c = k ; int i = 5; short s = 4; float f = 0.6; print(c); print(i); print(s); print(f); print( a ); print(45); print(0.0); print( a ); Rules: 1. exact match trivial (int -> int&) -> 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 ( ) 6

Default Parameters לעיתים פונקציה צריכה ברוב המקרים פרמטר בעל ערך קבוע, ורק במקרים נדירים מעבירים ערך אחר. נרצה שבמקרה השכיח לא נצטרך להעביר את הפרמטר הנ ל, אלא שזה יבחר באופן דיפולטי על ידי הקומפיילר. לדוגמא: הדפסת מספרים בבסיסים שונים. לרב הבסיס יהיה. void print_num(int num, int base = ); void f() print_num(24, 7); print_num(12, ); // no need to send. print_num(12); 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 את ערכי ברירת המחדל יש לכתוב פעם אחת בלבד (רצוי בהצהרה הראשונה על הפונקציה). מבנה הנתונים מחסנית מימוש מבני נתונים מופשטים ב - ++ מחסנית הינה מבנה נתונים התומך בפעולות הבאות: create צור מבנה נתונים מסוג מחסנית (ריק). destroy הרוס את מבנה הנתונים מחסנית. הוסף איבר למחסנית. הוצא את האיבר ה צעיר ביותר במחסנית. החזר את האיבר ה צעיר ביותר במחסנית. הדפס את תוכן מבנה הנתונים. push pop top print 1 2 8 top 7

מימ וש ב ++ לע ומ ת ב - כאשר הגדרנו ADT נעזרנו: בקובץ header אשר הכיל את הממשק: הוגדר בו הטיפוס של ה - ADT והוגדרו בו פונקציות המטפלות ב.ADT בקובץ ה - source הופיע המימוש של הפונקציות. ב ++ הוטמעה צורת עבודה זו בשפה, וניתן להגדיר טיפוסים (מחלקות) אשר כוללים בתוכם הן את השדות של כל משתנה מאותו טיפוס (אובייקט של אותה מחלקה) והן את הפונקציות (מתודות) המופעלות עליו. Header File : + + enum Result Success, Fail; struct Stack int* array; int size, top_index; Result create (int size); Result destroy (); Result push (int e); Result pop (); Result top (int& e); Result print(); ; מימוש ב data members member functions/ methods Source File מימו ש ב + + Source File מימו ש ב + + Result Stack::create (int s) How come new returns NULL? if ((array = new int[s]) == NULL) return FAIL; size = s; top_index = 0; return Success; void Stack::destroy () delete[] array; Not so good programming! Result Stack::push(int e) if (top_index == size) return FAIL; array[top_index] = e; top_index++; return Success; 8

Source File + + מימו ש ב מימו ש ב Source File + + Result Stack::top(int& e) if (top_index == 0) return Fail; e = array[top_index - 1]; return Success; Result Stack::pop() if (top_index == 0) return Fail; top_index--; return Success; Source File + + המצב יע מימו ש ב this #include Stack.h int main() #include Stack.h int main() כיצד הפונקציה יודעת לאיזה אובייקט התכוונו כאשר קראו לה? Stack s; int i; Stack s; int i; s.create(0); s.push(1); s.push(213); s.pop(); s.top(i); s.destroy(); return 1; ++ create(&s, 0); push(s, 1); push(s, 213); pop(s); top(s, &i); destroy(s); return 1; כאשר נקראת מתודה כלשהי נשלח לה פרמטר סמוי בשם this שטיפוסו הנו מצביע למחלקה בה מוגדרת המתודה, ומכיל מצביע לאובייקט עמו נקראה המתודה. בכל גישה לשדה של האובייקט או למתודה שלו מתוך מתודה אחרת הקומפיילר מוסיף הצבעה דרך.this 9

המצביע this void Stack::top(int& j) j = array[top_index - 1]; compiler void Stack::top(int& j) j = this->array[this->top_index - 1]; בעיה: גישה למשתנים ב ++ העבודה עם מחלקות מהווה את דרך העבודה העיקרית. הבעיה עם האופן בו הוגדרה קודם לכן המחלקה Stack הייתה כי כל פונקציה יכלה לגשת ישירות לשדות של אובייקטים מטיפוס.Stack בכדי למנוע זאת הוספו לשפה ה - modifiers access הקובעים למי מותר לגשת לאיזה חלק במחלקה. private/public/protected - private רק למתודות של המחלקה מותר לגשת לשדות פרטיים או לקרוא למתודות פרטיות. - public כל אחד יכול לגשת לחלק הציבורי. struct Stack private: int* array; int size, top_index; public: Result create(int size); Result destroy(); Result push(int e); ; לעומת struct class Stack int* array; int size, top_index; public: Result create(int size); Result destroy(); Result push(int e); Result pop(); Result top(int& e); Result print(); ; class By default: class private struct public

Friend functions אם נרצה בכל זאת לאפשר לפונקציות אשר אינן מתודות של המחלקה גישה לחלק ה - private של המחלקה, נוכל להגדירן כ - friend של המחלקה. נרצה לבצע זאת לרוב למען מימוש יעיל יותר של הפונקציה. Friend functions class Stack private: int* array; int size, top_index; friend int second(stack); int second(stack s) if (s.top_index < 2) exit(1); return s.array[s.top_index - 2]; Friend classes and Methods const member functions class A int f(); ; method f() of class A is a friend of class בדומה ל friend function ניתן להגדיר גם method של מחלקה אחת כ - Friend של מחלקה אחרת. כאשר מתודה אינה משנה את מצב האובייקט עליו היא נקראת (לדוגמא size() במחלקה (Stack ניתן לציין זאת ע י הוספת const בסוף ההצהרה על המתודה. class B ; class friend int A::f(); friend class B; ; all methods of class B are friends of class ניתן להגדיר מחלקה שלמה כחברה של מחלקה אחרת ואז כל ה- methods של אותה מחלקה יוכלו לגשת לחלק ה- private של המחלקה האחרת. השימוש ב Friends פוגע בקריאות התוכנה, ולכן מומלץ לא להשתמש בכך פרט למקרים יוצאי דופן. הסיבה שרצוי לבצע זאת הנה כי עבור const objects מותר לקרוא רק ל - methods.const class int read() const; void write(int j); ; int func(const & con, & mut) con.read(); // ok con.write(5); // error mut.read(); // ok mut.write(5); // ok 11

const member functions הגדרת מתודה כ - const מהווה חלק מחתימתה. יתכנו שתי מתודות עם אותו שם ואותם פרמטרים, אך אחת const והשנייה לא. class int f(); // will be called for non const objects int f() const; // will be called for const objects ; The first f() is called mutator. The second one is called inspector. mutable לעיתים רוצים לשנות אובייקט למרות שהוא,const אז אפשר להשתמש ב.mutable class Animal private: string name; string food; mutable int age; public: void setage(int age); ; void main() const Animal Tiger("Fluffy, "Antelope", 1); Tiger.setAge(2); member function overloading inline functions בדומה ל function overloading ניתן להגדיר גם מספר מתודות בעלות שם זהה, אולם עם חתימה שונה. קריאה לפונקציות הנה פעולה בעלת תקורה יקרה. יכולת זו שימושית במיוחד עבור.constructors ניתן להגדיר מספר constructors אשר כל אחד מקבל פרמטרים שונים וכך לאפשר מספר צורות אתחול. עבור פונקציות פשוטות חבל לשלם מחיר זה. ב - היינו נעזרים ב MARO (אבל על הבעיות הרבות שלו כבר שמעתם...). ב - ++ נעזר ב - inline.function class calculator double pow(double, double); double pow(double, int); int pow(int, int); inline function מוגדרת כפונקציה לכל דבר, אולם קומפיילר חכם יבחר לממש אותה בצורה שתמנע את התקורה של פונקציה רגילה. למשל, על ידי השתלת גוף הפונקציה בנקודת הקריאה בדומה למקרו. הדבר עלול לגרום לניפוח קוד ולא תמיד אפשרי (רקורסיה ( אך לעתים קרובות מייעל את הקריאה לפונקציה. 12

inline functions ניתן להגדיר inline function בשתי דרכים: כחלק מהגדרת המחלקה. להוסיף inline לפני המימוש. בכל מקרה על פונקציה זו להיות ממומשת ב - file.header inline functions האם inline משפר ביצועים? כן ולא! לפעמים! אולי! class Stack int _size; int top_index; int* array; public: int size() return _size; ; class Stack int _size, top_index; int* array; public: int size() ; inline int Stack::size() return _size; מגדיל מהירות (אין קריאות לפונקציה). מקטין מהירות (עלול לגרום page faults וגישות רבות לזכרון). מגדיל כמות הקוד (מנפח את הקוד בגלל השיכפול). מקטין כמות הקוד (נחסך הקוד של הקריאה לפונקציה וחזרה מהמחסנית). לא משפיע רוב המערכות מוגבלות לא ע"י זמן.PU אין תשובה אחת פשוטה נסיון וטעיה! ערוצים סטנדרטים ב - ++ קלט / פלט ב + + ב ++ קלט ופלט מתבצע ע י הזרמת נתונים באמצעות האופרטורים << ו -.>> הקלט והפלט ב - ++ נעשה ע"י ערוצים.(streams) יתרונות ++ הקומפיילר מזהה את טיפוסי המשתנים לבד (חוסך טעויות). בקלט, משתמשים במשתנים - לא בכתובותיהם (חוסך טעויות וגם יותר נקי ). /* Input / Output in */ #include <stdio.h> int j, k = 123; double d; fprintf(stdout, %s %d, A string, k); fscanf(stdin, %d %lf, &j, &d); // Input / Output in ++ #include <iostream> int j, k = 123; double d; cout << A string << k; cin >> j >> d; ערוצים הם מחלקות מיוחדות המוגדרות כחלק מהספרייה הסטנדרטית של ++. הקלט והפלט של עצם מתבצעים ע"י שימוש בפונקציות ואופרטורים המוגדרים עבור מחלקה זו. מחלקות אלו מוגדרות בקובץ,iostream ולכן על מנת להשתמש בהם צריכה להופיע בתחילת הקובץ השורה: #include <iostream> 13

ערוצ ים סט נדרט ים ב ++ - אופרטורי הקלט והפלט חכמים יותר מפקודות הקלט/פלט של שפת בכך שאין צורך לציין את סוג המשתנים. ערוצי הפלט מוגדרים במחלקה.ostream קיימים שני ערוצי פלט סטנדרטיים: ערוץ הפלט הסטנדרטי - cout ערוץ הודעות השגיאה הסטנדרטי - cerr ערוצי הקלט מוגדרים ע"י המחלקה.istream קיים ערוץ קלט סטנדרטי אחד - cin. קלט פלט ב ++ פלט מתבצע ע"י הזרמת נתונים לתוך ערוץ הפלט הרצוי. האופרטור המשמש להזרמת נתונים לתוך ערוץ פלט הוא ">>". ה"הזרמה" נעשית ע"י פקודה מהצורה: <ostream> << <data> ניתן גם להשתמש בפונקציה put על מנת לפלוט נתונים, בצורה הבאה: <ostream>.put(<data>); int x = 3; double y = 2.45; cout << "hello " << x << " " << (x + y); קלט פלט ב ++ קלט מתבצע ע"י שאיבת נתונים מתוך ערוץ הקלט. האופרטור המשמש לשאיבת נתונים מתוך ערוץ קלט הוא "<<". ה"שאיבה" נעשית ע"י פקודה מהצורה: <istream> >> <variable name> ניתן גם להשתמש בפונקציה get על מנת "לשאוב" נתונים, בצורה הבאה: <istream>.get(<variable name>); int x; double y; cin >> x >> y; פלט קלט formatting cout.setf(ios_base::oct, ios_base::basefield); cout.setf(ios_base::dec, ios_base::basefield); cout.setf(ios_base::hex, ios_base::basefield); cout.precision(8); cout.width(5); cout.fill( # ); cout.setf(ios_base::left, ios_base::adjustfield); cout.setf(ios_base::right, ios_base::adjustfield); cout.setf(ios_base::internal, io_base::adjustfield); cin.eof(); - 14

formatting - ערוצ י ק בצ ים קלט פלט דוגמא תוכנית זאת קוראת את מה שמופיע בקלט תו אחר תו ומדפיסה את התווים עד שמופיע הסימן לסוף קובץ. #include <iostream> int main() char x; while (!(cin.eof())) cin >> x; cout << x; return 1; ערוצי הקבצים הם מחלקות הנורשות מערוצי הק/פ הרגילים ולכן כל הפעולות המוגדרות על ערוצים רגילים מוגדרים גם על ערוצי קבצים. מחלקות אלו מוגדרות בקובץ,fstream ולכן על מנת להשתמש בהם צריכה להופיע בתחילת הקובץ השורה: #include <fstream> ערוצי הקלט מקבצים מוגדרים ע"י המחלקה.ifstream למחלקה זו יש constructor המקבל כקלט מחרוזת ופותח את הקובץ ששמו ערך המחרוזת. ערוצי הפלט לקבצים מוגדרים ע"י המחלקה.ofstream למחלקה זו יש constructor המקבל כקלט מחרוזת ופותח את הקובץ ששמו ערך המחרוזת. #include <fstream> void copy_file(char *a, char* b) ifstream from(a); // Open the file a if(!from.is_open()) cerr << "cannot open file " << a; exit(1); ofstream to(b); // Open the file b if(!to.is_open()) cerr << "cannot open file " << b; exit(1); char c; while (!(from.eof())) if (from.get(c)) to.put(c); 15