+ All Categories
Home > Documents > Introduction to Programming in C

Introduction to Programming in C

Date post: 04-Jan-2016
Category:
Upload: kirk-mullins
View: 42 times
Download: 0 times
Share this document with a friend
Description:
Introduction to Programming in C. תרגול 7. 01.04.2011. 1. 1. נושאים. מצביעים רקע אופרטורים על מצביעים מצביעים כפרמטרים לפונקציה הקצאת זיכרון דינאמית Malloc free. מצביעים. תאור הזיכרון של המחשב: - PowerPoint PPT Presentation
23
1 1 Introduction to Programming in C ללללל7 01.04.2011
Transcript
Page 1: Introduction to  Programming in C

111

Introduction to Programming in C

7תרגול

01.04.2011

Page 2: Introduction to  Programming in C

נושאים

מצביעים•רקע–אופרטורים על מצביעים–מצביעים כפרמטרים לפונקציה –

הקצאת זיכרון דינאמית•–Malloc–free

Page 3: Introduction to  Programming in C

:תאור הזיכרון של המחשב( כאשר כל בית byteניתן לחשוב על זיכרון המחשב כעל רצף של תאים, כל אחד בגודל בית )

(. כל תא בזיכרון מזוהה ע"י ערך מספרי המתאר את מיקומו המדוייק. bits סיביות )8בגודל של (. למשל, אם נגדיר את המשתנים memory addressערך זה הינו הכתובת של התא בזיכרון )

הבאים: char var1; // storage for type char is 1 byte. double var2; // storage for type char is 8 byte. int var3; // storage for type char is 4 byte.

כתובת של משתנה הינה הכתובת של הבית הראשון ברצף הבתים שמשתנה זה תופס ברגע שנצהיר על משתנים כמצביעים, נוכל להציב לתוכם כתובות של משתנים. בזיכרון. לדוגמא:

 int x = 200 ;int p; /*Declaration of a pointer “p” that is of type “int *”.*/p=&x; /*Assign the address of “x” to be the value of “p”.*/

 .x מכיל את הכתובת של המשתנה pבשלב זה המשתנה

מצביעים

var1 var2 var3

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

Page 4: Introduction to  Programming in C

אופרטורים מצביעיםהאופרטור &

מציין &כלומר האופרטור ,x היא כתובת הזיכרון של x& הוא משתנה אזי x אם ".…"כתובתו של

 :(pointers)מצביעים

משתנה כלשהו. במילים מצביע הינו משתנה שהערך שלו הוא כתובת שלאחרות, מצביע הינו משתנה שמצביע למשתנה אחר.

, שורת ההצהרה int כמצביע למשתנה כלשהו מטיפוסpאם נרצה להגדיר את ;int *p תיראה כך:

:באופן כללי, תבנית הצהרה על מצביעים הינה <variable-type> *<variable name>;

האופרטור הינו אופרטור שפועל על מצביעים. למשל עבור הדוגמה האופרטור

מצביע p הוא התוכן של תא הזיכרון ש-p* כלומר .x שקול ל-p*הקודמת עליו.

Page 5: Introduction to  Programming in C

דוגמאות

int x = 200 ;int p; /*Declaration of a pointer “p” that is of type “int *”.*/p=&x; /*Assign the address of “x” to be the value of “p”.*/ p=500; // < שקול= => x=500;.

זהירות בעת שימוש במצביעים:

! אין הוא בהכרח מצביע על ערך חוקיpכשמצהירים על מצביע int *pi;*pi = 100; /*wrong!!!!*/

,זוהי אינה שגיאת קומפילציה, אלא, segmentation fault טעות זו ידועה בשם שגיאה בזמן ריצה.

Page 6: Introduction to  Programming in C

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

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

:intמטיפוס  void swap(int a, int b){

int tmp = a;a = *b; *b = tmp;

} כתובת של מערך

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

שכן הוא מייצג כתובת קבועה, לא ניתן לשנותה במהלך מצביעהתוכנית.

Page 7: Introduction to  Programming in C

דוגמא נוספת #include <stdio.h> void main(){int x , *px; /*Define a variable of type int named "x" and a variable of type pointer to int named "px".*/ int y, *py ; px=&x; /*Assign the address of "x" to be the value of "px".*/ py=&y; scanf("%d%d",px,py); /*Read two integers values from the input

and assign them to "x" and "y". Make sure that you understand why!!! */

printf("x=%d , y=%d\n",*px,*py); /*Print the values of the x and y which are the variables pointed to by px and py. */

Page 8: Introduction to  Programming in C

1תרגיל :1שאלה

:Cנתונה השורה הבאה של תכנית בשפת int a, *b, c[4];

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

 (א *(c+3) = 8;(ב a = *(c + *b);(ג *(c++) = 12; (ד c = b; (ה b = c;(ו a = (*c)++;(ז *(b+1) = (*c)++;(ח a = *b - *c;(ט *c = *(b++);(י *(b++)= *(&a);(יא *b==2=a; (יב c[3] = *b == 2;

Page 9: Introduction to  Programming in C

1תרגיל :1שאלה

:Cנתונה השורה הבאה של תכנית בשפת int a, *b, c[4];

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

 (א *(c+3) = 8; // c[2]=8;(ב a = *(c + *b); (ג *(c++) = 12; /*Compilation Error: error C2105: '++' needs l-value*/(ד c = b; /*Compilation Error: error C2106: '=' : left operand must be l-value*/(ה b = c;(ו a = (*c)++;(ז *(b+1) = (*c)++;(ח a = *b - *c;(ט *c = *(b++);(י *(b++)= *(&a);(יא *b==2=a; /*Compilation Error: error C2106: '=' : left operand must be l-value*/(יב c[3] = *b == 2;

Page 10: Introduction to  Programming in C

2תרגיל תוכנית לחישוב אורך המחרוזת עם שימוש במצביעים:

#include <stdio.h>#define MAX_LENGTH 80

int my_strlen (char *s){ char *p = s;while (*p) p++;return p - s;

}void main(){

char str[MAX_LENGTH];int len;printf("Enter a string:");gets(str);len = my_strlen(str);printf("The lenght of the string %s is %d \n",str,len);

}

Page 11: Introduction to  Programming in C

3תרגיל   מחרוזות הממחישה שימוש במצביעים:2תוכנית לחיבור

#include <stdio.h>#include <string.h>#define MAX_LENGTH 81 /*Option #1*/void stringCat(char *s1, char *s2){

while (*s1 ) ++s1; /*We could equivalently have written: s1++; */do }

*s1 = *s2;s1++;s2++;

}while(*s2); *s1 = '\0';

}/*Option #2*/void stringCat(char *s1, char *s2){

while (*s1 ) ++s1;while(*(s1++) = *(s2++));

{

Page 12: Introduction to  Programming in C

3המשך תרגיל /*Option #3*/

void stringCat(char *s1, char *s2){strcpy(s1+strlen(s1),s2);

}

void main(){char str1[MAX_LENGTH], str2[MAX_LENGTH];

printf("Enter a string #1 with maximum %d characters:",(MAX_LENGTH-1)/2); gets(str1); printf("Enter a string #2 with maximum %d characters:",(MAX_LENGTH-1)/2); gets(str2); stringCat(str1,str2); /*We can use any (but not more than one) of the options above! */

printf("The final string is \"%s\" \n",str1);}

Page 13: Introduction to  Programming in C

4תרגיל שמקבלת כארגומנט שתי מחרוזות. במידה char * strstr(char *st1, char *st2)כתוב פונקציה

שממנו st1, הפונקציה מחזירה מצביע לתו של st1 מוכללת במחרוזתst2שהמחרוזת .NULLמתחילה המחרוזת הזאת, אחרת הפוקציה מחזירה

#include <stdio.h>#include <stdlib.h>

char * iterStrstr(char *st1, char *st2){char *p1,*p2;int len2 = strlen(st2);int len1 = strlen(st1);while (len1>=len2){

for(p1=st1,p2=st2;*p2 && *p1==*p2;p1++,p2++);if(!*p2)

return st1;st1++;len1--;

}return NULL;

}

Page 14: Introduction to  Programming in C

4המשך תרגיל

void main(){char st1[]="bnbnbacdhghg",st2[]="acd";char *c;if(c= strstr(st1,st2))

printf ("The first character in both st2 and st1 is %c\n ",*c);else

printf ("Sorry, st2 isn't contained in st1!!!\n");{

Page 15: Introduction to  Programming in C

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

זיכרון דינאמית.

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

הזיכרון שהתוכנית שלנו עלולה לצרוך.

- הקצאת מקום נעשה בזמן בריצה על יד הקצאת זיכרון דינאמית(. פונקציה זו memory allocation )קיצור ל-)(mallocקריאה לפונקציה

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

. NULLנכשלת מוחזר הערך

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

. )(freeשיחרור של זיכרון דינאמי נעשה ע"י קריאה לפונקציה הפונקציה מקבלת מצביע לכתובת תחילת קטע הזיכרון שרוצים

לשחרר.

Page 16: Introduction to  Programming in C

אופרטורים sizeofהאופרטור מחזיר את גודלו של הטיפוס בבתים.sizeofהאופרטור

sizeof (name_of_charecter)תבנית: אילו הינו כותבים: .4 מחזיר sizeof (float) לדוגמא:

float f; sizeof(f) ( 4היה מחזיר את אותו דבר.)

: mallocשימוש בפונקציה variable_pointer = (pointer_type) malloc (size_of_memory);

 דוגמא:int size, *p_list;printf("Enter the number of elements:");scanf("%d", &size);p_list = (int*)malloc (size * sizeof(int));

Page 17: Introduction to  Programming in C

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

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

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

לאחר הקצאת זיכרון תמיד צריך לבדוק האם ההקצאה הצליחה. void main(){ long *l_list; l_list =(long*) malloc (5*sizeof(long)); if (l_list == NULL){ printf ("Failed to allocate memory"); return; } free(l_list);}

Page 18: Introduction to  Programming in C

5תרגיל :תוכנית להדגמה של מערך דו-מימדי דינאמי

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

. בתחילה נאתחל מערך של מצביעים, ולאחר מכן נאתחל כל מצביע )(mallocפונקצית -ים בגודל המוגדר ע"י int הרצוי. למשל, יצירת מערך של typeלהיות מערך של ה-

המשתמש שבכל איבר בו יש את הערך של מכפלת האינדקסים שלו:#include <stdio.h>#include <stdlib.h> void main(){

int i,j,rows,cols,t;int **array;printf("enter num of rows: ");scanf("%d",&rows);printf("enter num of columns: ");scanf("%d",&cols);if (!(array=(int **)malloc(rows*sizeof(int *)))){

printf("Memory allocation failed, quiting… "); return;

} . . .

Page 19: Introduction to  Programming in C

5המשך תרגיל for (i=0;i<rows;i++) } /*Fill in the different rows:*/

if (!(array[i]=(int *)malloc(cols*sizeof(int))))} for (t=0;t<i;t++) /*Free all priory allocated

memory:*/free(array[t]);

free(array);printf("Memory allocation failed, quiting… ");return; /*Terminate the program!*/

}for (j=0;j<cols;j++) /*Fill in the different columns:*/

array[i][j]=i*j;}for (i=0;i<rows;i++){ /*Print the different rows:*/

for (j=0;j<cols;j++)printf("%d ",array[i][j]);

printf("\n");}

Page 20: Introduction to  Programming in C

5המשך תרגיל

/*Free allocated memory:*/

for(i=0;i<rows;i++)free(array[i]);

free(array);}

Page 21: Introduction to  Programming in C

6תרגיל עיין בקטע הבא וסמן את כל התשובות הנכונות:

 

#include <stdio.h>#include <stdlib.h>#define MAX 10

void main(){int *ptr, *arr[MAX];int i, j;for (i=MAX-1 ; i>=0; i--)

if (arr[i] = (int *) malloc(i * sizeof(int)))for (j=0; j<i; j++)

*(*(arr+i)+j) = j*i;ptr = *(arr+MAX-1);while (*ptr)

printf ("%d ", *ptr--);}

התכנית לא מדפיסה כלום.1.

(run time error.)יש שגיאה בזמן ריצה 2.

.72 63 54 45 36 27 18 9התכנית תדפיס: 3.

התכנית תדפיס אינסוף אפסים.4.

.0התכנית תדפיס 5.

התכנית תדפיס ערכים לא ידועים.6.

אף לא אחת מהתשובות לעיל.7.

Page 22: Introduction to  Programming in C

6פתרון תרגיל

Page 23: Introduction to  Programming in C

Bye!!!


Recommended