49
ההההה1 הההה- הההה הה ההההה[email protected]

תוכנה 1 - חזרה שולי לב יהודי [email protected]. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

  • View
    227

  • Download
    0

Embed Size (px)

Citation preview

Page 1: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

- חזרה1תוכנה

שולי לב יהודי

[email protected]

Page 2: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

2

Arrays and Strings

מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל •איבר נעשית ע”י אינדקס.

מערך מוגדר בזיכרון רציף. האיבר הראשון נמצא Cב-• מוגדר החל מכתובת aבכתובת הנמוכה. לדוגמא, אם

1000:char a[6];

Element a[0] a[1] a[2] a[3] a[4] a[5]Address 1007 1008 1009 1010 1011 1012

Page 3: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

3

Single-Dimension Arrays

type var_name[size]; double balance[100];

. לדוגמא:0האינדקס של האיבר הראשון הוא •char p[10];

p[0] אלמנטים 10 עם charactersמגדיר מערך של .p[9]עד

השטח שמוגדר עבור מערך:•total bytes = sizeof(base type) * size of

array

Page 4: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

4

Single-Dimension Arrays (cont.)

אין בדיקה של גבולות המערך!ניתן לכתוב מעבר לגבולות ללא שגיאת קומפילציה:int count[10], i;

/* this causes count to be overrun */for (i=0; i < 100; i++) count[i] = i;

Page 5: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

5

Generating a Pointer to an Array

שם המערך ללא ציון אינדקס הוא מצביע למערך:•int sample[10];int *p;p = sample;

•p האיבר הראשון של כתובת יקבל את sample.

Page 6: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

6

Passing Single-Dimension Arrays to Functions

לא ניתן להעביר תוכן של מערך שלם כארגומנט •לפונקציה. ניתן להעביר מצביע לתחילת המערך:

void main(void){

int i[10];func1(i);

}

3בפונקציה, ניתן להגדיר את הפרמטר באחד מ-• אופנים:

Page 7: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

7

Passing Single-Dimension Arrays to Functions

• void func1(int *x) /* pointer */{...}

• void func1(int x[10]) /* sized array */{...}

• void func1(int x[]) /* unsized array */{...}

איברים:32גם זה יעבוד - יעבור מצביע - לא יוצר •• void func1(int x[32]) /* sized array */

Page 8: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

8

Return an Array from a Function

int main(void){

char *mystr;

mystr = getstr();printf("%s\n", mystr);

return 0;}

char *getstr() {

char str[20]; str[0] = 'a';

str[1] = 'b';str[2] = '\0';

return(str);}

יודפס main משוחרר ולכן ב-str ביציאה מהפונקציה השטח של •"זבל".

= char *str דינמית ע"י: str צריך להקצות את •malloc(20);

Page 9: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

9

Strings

•String הוא מערך של characters-המסתיים ב null 1`. לכן גודל המערך צריך להיות גדול ב-\0שמצוין ע”י `

:10מאורך המחרוזת. למשל למחרוזת באורך char str[11];

helloניתן להגדיר קבוע מחרוזת ע”י גרשיים: ”•there”

.nullבקבוע אין צורך להוסיף

Page 10: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

10

String Manipulation Functions

Name Functionsstrcpy(s1,s2) Copies s2 into s1strcat(s1,s2) Concatenates s2 onto the end of s1strlen(s1) Returns the length of s1strcmp(s1,s2) Returns 0 if s1 and s2 are the same;

less than 0 if s1<s2; greater than 0 if s1>s2

•strcmp מחזירה false:אם המחרוזות שוות. לכן כדי לבדוק שוויון if (!strcmp(s1,s2)) printf(“equal strings\n”);

includeכדי להשתמש בפונקציות: <•<string.h #

Page 11: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

11

Arrays of Strings

מוגדר ע”י מערך דו-מימדי:•

char str_array[30][80]; תווים.79 מחרוזות, כל אחת באורך של עד 30מגדיר מערך עם

כדי לגשת למחרוזת אחת:•

gets(str_array[2]);שקול ל:

gets(&str_array[2][0]);אך צורת הכתיבה הראשונה מקובלת יותר.

Page 12: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

12

Indexing Pointers

שם מערך ללא אינדקס הוא מצביע לאיבר הראשון במערך.•

:trueלכן, הביטוי הבא הוא •p == &p[0]

באותו אופן, ניתן להוסיף אינדקס למצביע, כאילו שהוגדר •כמערך:

int *p, i[10];p = i;p[5] = 100; /* assign using index */*(p+5) = 100; /* assign using pointer arithmetic */

.i באיבר השישי של 100שתי הפקודות מציבות

Page 13: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

13

Array Initialization

• int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

•[0]i [9 והלאה עד ]1 יקבל את הערךi שיקבל את הערך 10.

:charactersאיתחול מערך של •char str[15] = “I like the sea”;

זה שקול ל:•

char str[15] = {‘I’, ‘ ‘, ‘l’, ‘i’, ‘k’, ‘e’, ‘ ‘, ‘t’, ‘h’, ‘e’, ‘ ‘,

‘s’, ‘e’, ‘a’, ‘\0’};

Page 14: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

14

Pointers

?Pointerמה זה •משתנה המכיל כתובת של

משתנה אחר10031000

1001

1002

1003

1004

1005

Variable in memory

Memory address

Page 15: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

15

Pointer Variable

משתנה שצריך להכיל ערך של מצביע צריך להיות •מוגדר כך:

type *name;

•type-מציין את סוג המשתנים שה pointer יכול להצביע עליהם.

כל מצביע יכול להצביע לכל משתנה מסוג כלשהו, אולם•pointer arithmetic-נעשה לפי ה base type.

Page 16: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

16

The Pointer Operators

& מחזיר את הכתובת של משתנה בזיכרון:•

m = &count;-שם בm את הכתובת של count אין כל קשר לערך של .

!countהמשתנה

מחזיר את הערך שנמצא בכתובת שמופיעה אחריו. *•הוא המשלים של &. לדוגמא:

q = *m; m. כלומר, את הערך ש-q בתוך countישים את הערך של

מצביע עליו.

Page 17: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

17

The Pointer Operators(cont.)

ועם *א להתבלבל עם כפל - ל bitwise AND& - .

קודמים לכל )של מצביעיםו-& ( *האופרטורים שהוא -)5(האופרטורים האריתמטיים, למעט מינוס אונרי

בעל קדימות זהה.

צריך לדאוג שהמצביע אכן תמיד מצביע לערך מסוג מניח שכל compiler, ה-intמתאים. אם הגדרנו מצביע ל-

. intכתובת שהוא יכיל היא כתובת של ערך מסוג

Page 18: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

18

The Pointer Operators(cont.)

void main(void) { double x, y; int *p;

/* The next statement causes p (which is an integer pointer) to point to a double. */

p = &x;

/* The next statement does not operate as expected */ y = *p;}

בתים 4 , רקint מוגדר כמצביע ל-p. כיוון ש-y ל-xלא תהייה השמה של ערך •.floating point בתים שמכילים מספר 8ולא yיועברו ל-

(שגיאת קומפילציה).castingאי אפשר לבצע השמה כזו ללא C++ב- •

Page 19: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

19

Pointer Expressions

Pointer Assignmentsvoid main(void){

int x;int *p1, *p2;

p1 = &x;p2 = p1;

printf(“ %p”, p2); /* print the address of x, not x ’s value */

}

Page 20: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

20

Pointer Expressions (cont.)

Pointer Arithmetic פעולות אפשריות: חיבור וחיסור.2•

בתים.4 הוא באורך int. נניח ש-2000 וערכו int מצביע ל-p1דוגמא: •.2001 ולא 2004 יכיל p1 , p1++אחרי הפעולה

הבא.integer מקודם, הוא יצביע ל-p1בכל פעם ש-

p1 = p1+12ניתן לחבר ערך כלשהו, למשל: ;•p1-מהסוג של 12 יצביע לאלמנט ה) p1.אחרי זה שהוא מצביע כעת (

ניתן להחסיר ערך של מצביע מערך של מצביע אחר כדי למצוא את • שלהם) הנמצאים ביניהם.base typeמספר האלמנטים (מה-

:לכפול, לחלק, לחבר שני מצביעים, לבצע פעולות לוגיותלא ניתן )bitwise לחבר או לחסר ערכי ,(float או double .

Page 21: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

21

Pointer Expressions (cont.) Pointer Arithmetic - example:

ch

ch +1

ch+2

ch+3

ch+4

ch+5

3000

3001

3002

3003

3004

3005

char *ch = 3000;

short *i = 3000; i

i + 1

i + 2

כל פעולות האריתמטיקה על

מצביע נעשות baseבהתאם ל-

type שלו

Page 22: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

22

Pointer Expressions (cont.) Pointer Comparisons• Example: if (p < q) printf(“p points to lower memory than q\n”);

בד”כ שימושי כאשר מספר מצביעים מצביעים לאובייקטים משותפים, כמו •במערך.

:stack דוגמא - מחסנית• רשימת איברים שהגישה אליהם היא בשיטתLast-in , First-out

(LIFO).2 :פעולות

()pushמכניסה ערך למחסנית - ()popמוציאה ערך מהמחסנית -

0בדוגמא, הערכים שהמשתמש מקליד,מוכנסים למחסנית. אם הוקלד ,-.1). התכנית מסתיימת כשמתקבל ערך popמוציאים ערך מהמחסנית (

Page 23: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

23

Pointer Expressions (cont.)

Stack example:#include <stdio.h>#include <stdlib.h>

#define SIZE 50

void push(int i);void pop(void);

int *tos, *p1, stack[SIZE];

void main(void){ int value; tos = stack; /* tos points to the top of the stack */ p1 = stack; /* initialize p1 */

do {printf(“Enter value: “);scanf(“%d”, &value);if (value != 0) push(value);else printf(“value on top is%d\n”, pop());} while (value != -1);

}void push(int i){

p1++;if (p1 == (tos + SIZE)) { printf(“Stack overflow”); exit(1);}*p1 = i;

}

Page 24: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

24

Pointer Expressions (cont.)

Stack example (cont.):

pop(void){

if (p1 == tos) { printf(“Stack underflow”); exit(1);}p1--;return *(p1 + 1);

}

:הערה•

הסוגריים returnבפקודת ה-הכרחיים. בלעדיהם היה:

return *p1 + 1;הערך שהיה חוזר הוא הערך

, ולא 1 ועוד p1שבכתובת (שהיא p1+1הערך בכתובת

. )p1 בתים אחרי 4

Page 25: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

25

Arrays of Pointers

int:int *x[10] מצביעים ל-10מערך של •

לאיבר השלישי במערך: var הכנסת כתובת המשתנה•

x[2] = &var;

:varלמציאת הערך של •

*x[2]

העברת מערך של מצביעים לפונקציה - קריאה לפונקציה •עם שם המערך ללא אינדקס. למשל, פונקציה המקבלת

תראה כך:xמערך

Page 26: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

26

Arrays of Pointers (cont.)

void display_array(int *q[ ]){ int t;

for (t=0; t < 10; t++) printf (“%d “, *q[t]);}

•q-אינו מצביע ל integers אלא מצביע למערך ,.integersשל מצביעים ל-

Page 27: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

27

Arrays of Pointers (cont.)

שימוש נפוץ במערך של מצביעים הוא להחזקת מצביעים •.stringsל-

לדוגמא, פונקציה המקבלת קוד שגיאה ומדפיסה הודעה מתאימה:•void syntax_error(int num){ static char *err[] = {

“Cannot open file\n”, “Read error\n”, “Write error\n”, “Media Failure\n”

}; printf (“%s”, err[num]);

}

Page 28: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

28

Using Structures Pointers

לפני שם המשתנה: & ע”י structureמציאת כתובת ה-•struct bal { float balance; char name[80];} person;

struct bal *p; /* declare a structure pointer */

p = &person; ואז.p במצביע person שם את כתובת

-p : -> נעשית ע”י האופרטורstructureגישה לשדה ב-•>balance

משמש כדי לגשת לשדה כאשר פועלים ישירות על )dot (.האופרטור • (ולא ע”י מצביע).structureה-

העברת כתובת של שדה תעשה כך:•func(&person.x); func2(person.name); func3(&person.name[2])

Page 29: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

29

The Operator -> An Example: display a timer

struct my_time {int hours;int minutes;int seconds;

};void main(void) {

struct my_time systime;systime.hours = 0;systime.minutes = 0;systime.seconds = 0;for ( ; ; ) {

update(&systime); display(&systime);}

}

void update(struct my_time *t){

t->seconds++;if (t->seconds == 60) { t->seconds = 0; t->minutes++;}

...}void display(struct my_time *t){

printf(“%02d:”, t->hours);printf(“%02d:”, t->minutes);printf(“%02d:”, t->seconds);

}

Page 30: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

30

Multiple Indirection(Pointers to Pointers)

address value

address address value

Pointer Variable

Pointer Pointer Variable

Single Indirection

Multiple Indirection

Page 31: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

31

Multiple Indirection (cont.)float **newbalance ; הגדרת מצביע למצביע: •newbalance אינו מצביע למספר floating-point אלא

. floatמצביע למצביע ל- פעמיים:*כדי לגשת לערך עצמו יש להפעיל את אופרטור ה-•

int x, *p, **q;

x = 10; p = &x; q = &p;

printf(“%d”, **q); /* print the value of x */

Page 32: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

32

Initializing Pointers

אחרי שמצביע הוגדר אך לפני שהושם לו ערך, הוא מכיל •ערך לא ידוע (“זבל”).

,”אם ננסה להשתמש במצביע לפני שיש לו ערך “חוקיסביר שהתכנית תעוף (וכנראה גם מערכת ההפעלה)!

מוסכמה: מצביע שכרגע אינו מצביע למיקום בר-תוקף • null). מצביע שערכו 0 (שהוא nullבזיכרון, מאותחל ל-אינו מצביע לכלום.

כדי לציין למשל, סוף של מערך של nullנשתמש בערך •מצביעים.

Page 33: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

33

Initializing Pointers (cont.)

Search (char *p[], char *name) { register int i; for (i=0; p[i]; ++i) if (!strcmp(p[i], name)) return; return -1;}

מציין את סוף המערך. הלולאה רצה כל nullכאן, ערך •.null ולא הגענו למצביע שערכו nameעוד לא נמצא

Page 34: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

34

Initializing Pointers (cont.)

במחרוזת כאילו שהוא מערך:charניתן לאתחל מצביע ל-•

char *p = “hello world”; string table שומר את כל קבועי המחרוזות ב-compiler ה-•

את הכתובת של הקבועpולכן הפקודה תכניס ל-“hello world”-כפי שהוא מאוחסן ב string table.

Page 35: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

35

Pointers to Functions

למרות שפונקציה אינה משתנה, יש לה מקום פיזי בזיכרון •שניתן לשמור אותו במצביע.

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

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

דוגמא:•

Page 36: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

36

Pointers to Functions (cont.)

void check (char *a, char *b, int (*cmp)(const char *, const char *));

void main(void){

char s1[80], s2[80];int (*p)(const char *, const char *);

p = strcmp;gets(s1);gets(s2);check(s1, s2, p);

}

void check (char *a, char *b, int (*cmp)(const char *, const char *))

{ printf(“testing for equality\

n”);if (!(*cmp)(a,b)) printf(“equal”);else printf(“not equal”);

}.strcmp*) קורא ל-cmp)(a,bהביטוי (•

גם כך:checkניתן לקרוא ל-•

check(s1, s2, strcmp);

Page 37: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

37

Dynamic Allocation Functions

קצאה דינמית - הקצאת שטח בזמן ריצה.ה•

- שטח הנמצא בין התכנית heapזיכרון דינמי מוקצה על ה-•.stack לבין ה-),data(והשטח הקבוע שלה

- משחררת.free - מקצה שטח, mallocפונקציות עיקריות: •# include stdlib.h צריך את השורה: •

prototype: void *malloc(size_t number_of_bytes);

שפרושו שניתן לשים את הערך voidמחזירה מצביע ל-•החוזר במצביע מכל סוג שהוא.

Page 38: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

38

Dynamic Allocation Functions (cont.)

הראשון בשטח שהוקצה. byteבהצלחה - מוחזר מצביע ל-•.nullבכשלון - כאשר אין מספיק מקום - מוחזר

char *p ; לדוגמא: •

p = malloc(1000);

-אין צורך בcast-הערך מוסב אוטומטית לפי ה ,type בצד לא נעשית הסבה אוטומטית!).C++שמאל (ב-

:portability נחוץ ל-sizeof. ה-integers 50הקצאת •int *p;p = malloc(50 * sizeof(int));

Page 39: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

39

Dynamic Allocation Functions (cont.)

יש לבדוק האם הערך החוזר אינוnull!

•free.מחזירה למערכת שטח שהוקצה קודם prototype: void free(void *p);

•p.הוא מצביע לשטח שהוקצה קודם -חשוב לא לקרוא לfree!עם ארגומנט לא נכון

Page 40: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

40

Problems with Pointers

שימוש בערך לא טוב של מצביע יכול לגרום לכתיבה לשטח •אחר.

טעויות נפוצות:• uninitialized pointer:

/* this program is wrong */void main(void){

int x, *p;x = 10;*p = x;

}

p לא אותחל ולכן נכתב 10הערך

במקום לא ידוע בזיכרון.הבעיה

משמעותית בתכנית גדולה.

Page 41: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

41

Problems with Pointers (cont.)

Misunderstanding of how to use a pointer:/* this program is wrong */void main(void){

int x, *p;x = 10;p = x;printf(“%d”, *p);

}

printf לאתדפיס את הערך

אלא ערך 10כלשהו אחר.

תיקון יש לכתוב:ל

p = &x;

Page 42: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

42

Problems with Pointers (cont.)

Incorrect assumptions about variables locations:אי אפשר לדעת היכן המשתנים ממוקמים בזיכרון. לכן אם •

ננסה להשוות בין מצביעים שאינם מצביעים לאובייקט משותף, נקבל תוצאה לא צפויה:

char s[80], y[80];char *p1, *p2;p1 = s;p2 = y;if (p1 < p2) . . .

לא נכון להניח מוקצים y ו-sש-

ברצף.

Page 43: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

43

Problems with Pointers (cont.)

second ו-firstבאותו אופן לא נכון לאתחל את המערכים • זה compilers (למרות שבחלק מה-19 עד 0במספרים

יעבוד):

int first[10], second[10];int *p, i;p = first;for (i=0; i < 20; i++) *p++ = i;

Page 44: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

44

argc and argv – Arguments to main()

command line ע"י ה-()mainמעבירים ערכים ל-•arguments:

program_name command_line_arguments •argc-ו argv מוגדרים built-in ובהם מתקבלים

הארגומנטים.•argc מכיל את מספר הארגומנטים והוא int, ערכו תמיד

כיוון ששם התכנית הוא הארגומנט הראשון.1לפחות •argv -הוא מצביע למערך של מצביעים לcharacter כל ,

איבר במערך מצביע לארגומנט. – התכנית צריכה להמיר stringsכל הארגומנטים הם •

המתאים.formatמספרים ל-

Page 45: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

45

argc, argv

/* The name of the program is “name” */void main(int argc, char *argv[ ]){ if (argc != 2) { printf (“You forgot to type your name.\n”);

exit(1);}printf(“Hello %s”, argv[1]);

}

> name Tom> Hello Tom

Page 46: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

46

argc, argv

ברוב סביבות העבודה הארגומנטים מופרדים ע"י רווח או •tab:פסיק, נקודה-פסיק אינם נחשבים מפרידים. לדוגמא .

run Spot, run מחרוזות: 3 אלו הןHerb,Rick,Fred וזוהי מחרוזת אחת:

” Alon Ronit“ וגם זו:

Page 47: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

47

argc, argv - Example/* countdown – the program counts down from a starting value (which is specified on the command line) and beeps when it reachs 0. */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>

void main(int argc, char *argv[ ]){ int disp, count;

if (argc < 2) { printf(“You must enter the length of the count.\n”); exit(1);}

Page 48: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

48

argc, argv – Example (cont.)

/* if the string “display” is the second argument, the countdown will also be displayed on the screen. */ if (argc == 3 && !strcmp(argv[2], “display”)) disp = 1; else disp = 0;

for (count=atoi(argv[1]); count; --count) if (disp) printf(“%d\n”, count);

putchar(‘\a’); /* this will ring the bell in most computers */

printf (“Done\n”);}

Page 49: תוכנה 1 - חזרה שולי לב יהודי shulyl@tau.ac.il. 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית

49

What Does main() Return?

לתהליך שקורא לה שהוא int מחזירה ()mainהפונקציה •בד"כ מערכת ההפעלה.

עם אותו ()exit שקולה לקריאה ל-()mainהחזרת ערך מ-•ערך

אם לא מוחזר ערך הערך שחוזר לתהליך הקורא אינו מוגדר •, אך לא תמיד).0 יחזירו compilers(רוב ה-

אם איננה מחזירה ערך, void כ-()mainניתן להגדיר את •אולם אם פונקציה איננה מחזירה ערך וגם לא מוגדרת

.warning יתקבל voidכ-