You are on page 1of 7

‫תרגול ‪13‬‬

‫מצביעים חזרה ותוספות‪:‬‬
‫כאשר מוסיפים למצביע מספר‪ ,‬המצביע יצביע לכתובת בזכרון של המספר*(גודל הסוג של המצביע) ועוד‬
‫הכתובת המקורית של המצביע‪.‬‬
‫לדוגמא‪:‬‬
‫;}‪int a[]={10,11,22,33‬‬
‫;‪int *p=a‬‬
‫)‪p=a+2  p= p+ 2* sizeof(int‬‬
‫)‪now p will point on 22 (he will have 22’s address‬‬
‫כאשר מחסרים ממצביע מצביע נוסף‪ ,‬מקבלים‬
‫בקפיצות של הסוג שעליו מצביע הפויינטר‬
‫לדוגמא‪:‬‬

‫‪ ,int‬מספר זה הוא מרחק הכתובות בין‬

‫‪ 2‬המצביעים‬

‫;}‪int a[]={10,11,22,33‬‬
‫;‪int *p‬‬
‫‪p=a+4; //p will point on 33‬‬
‫‪printf(“%i”,p-a); //will print 4‬‬
‫מה הפלט של התוכנית הבאה‪:‬‬
‫>‪#include<stdio.h‬‬
‫)(‪void main‬‬
‫{‬
‫;} ‪int a[ ] = { 0, 1, 2, 3, 4‬‬
‫;‪int i, *p‬‬
‫) ‪for( p = a + 4 ; p >= a ; p--‬‬
‫;)"‪printf(" %i", *p); printf("\n‬‬
‫)‪i++‬‬
‫;)"‪printf("\n‬‬

‫; ‪for( p = a + 4, i = 0 ; i <= 4‬‬
‫;)]‪printf(" %i", p[-i‬‬
‫}‬

‫‪Output:‬‬
‫‪43210‬‬
‫‪43210‬‬

‫‪Avshalom Elmalech 83120‬‬

:‫ומה עם התוכנית הבאה‬
#include<stdio.h>
void main()
{
int a[ ] = { 0, 1, 2, 3, 4 };
int i, *p;
for( p = a + 4 ; p >= a ; p-- )
printf(" %i", a[p-a]); printf("\n");
for( p = a , i = 0 ; p + i <= a + 4 ; i++, p++)
printf(" %i", *(p+i));
printf("\n");
}
Output:
4 3 2 1 0
0 2 4

:‫מצביעים למבנים‬
.‫מצביע יכו להצביע גם על מבנה‬
?‫איך נכנסים לשדה בתוך מבנה דרך מצביע על מבנה‬
:‫דרך א‬
#include<stdio.h>
struct David
{
int sum;
double avg;
};
void main()
{
David d1;
David* d_ptr=&d1;
(*d_ptr).sum=5;
}

:‫דרך ב‬
#include<stdio.h>
typedef struct
{
int sum;
double avg;
} David;
void main()
{
David d1;
David* d_ptr=&d1;
d_ptr->sum=5;
}

Avshalom Elmalech 83120

:‫דוגמא‬
#include<stdio.h>
typedef struct
{
//attributes:
char name[64];
long employee_id;
float
salary;
} Employee;
void show_employee(Employee *emp)
{
printf("Employee data: \n");
printf("\t name: %s\n",emp->name);
printf("\t id: %d\n",emp->employee_id);
printf("\t salary: %f\n",emp->salary);
}
int main()
{
Employee Worker={" Sami",12345,25000},
Boss={" Diana",101,101101.00};
Employee *ptrB, *ptrW;
ptrW=&Worker;
ptrW->salary=34000;
ptrB=&Boss;
if((*ptrW).salary>ptrB->salary)
printf("Something strange in your firm!\n");
ptrB=ptrW;
show_employee(ptrB);
show_employee(&Boss);
}

‫הקצאה דינאמית‬
‫ נשתמש‬,MAXSIZE ‫ ואנחנו לא רוצים לבזבז מקום ולהקצות מערך בגודל‬,‫אם לא ידוע מראש גודל מערך‬
.‫ כל פעם נבקש מקום (בזמן ריצה) שאנחנו צריכים‬,‫בהקצאה דינאמית‬
malloc
:‫סינטקס‬
void* malloc(size_t_Size);
‫) הנדרש‬bytes ( ‫ – מספר הבתים‬size_t_Size
)‫ לפויינטר שחזר לסוג שרצינו להקצות‬casting ‫ פויינטר לתחילת המקום שהוקצה ( צריך לעשות‬- void*

:‫דוגמא‬
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *pt;
//a pointer to array of ints
pt=(int*) malloc(4*sizeof(int));
}

Avshalom Elmalech 83120

:‫דוגמא‬
#include<stdio.h>
#include<stdlib.h>
int main()
{
int **pt;
//a pointer to array of pointers to int
pt=(int**) malloc(4*sizeof(int*));
}

calloc
:‫סינטקס‬
void* calloc(size_t NumOfElements, size_t SizeOfElement);
‫ מספר התאים הנדרש‬-NumOfElements
‫ גודל כל תא בבתים‬-SizeOfElement

:‫דוגמא‬
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *pt;
//a pointer to array of ints
pt=(int*) calloc(4,sizeof(int));
}

malloc

‫ מאתחל את התאים שאותם הוא מקצה ואילו‬calloc ‫ הוא ש‬,calloc ‫ לבין‬malloc ‫ההבדל בין‬
....‫משאיר בהם זבל‬
.‫ – אחזרי שמסיימים עם זכרון שהקצנו דינאמית ואין לנו שימוש בו יותר צריך לשחרר אותו‬free()
‫ כל מה שהקצאתם בתוכנית אתם חייבים לשחרר בסוף‬,‫הכלל הוא פשוט‬

Avshalom Elmalech 83120

:‫דוגמא‬
#include <stdio.h>
#include <malloc.h>
int main()
{
int *single_int, *array_int;
int num, i;
single_int= (int*) malloc(sizeof(int));
printf("How many numbers to enter ?\n");
scanf("%d" , &num);
array_int = (int*) malloc (num*sizeof(int));
for(i=0; i<num; i++)
{
printf("please enter element #%d : ", i+1);
scanf("%d" , &array_int[i]);
}
*single_int = 0;
//Summarize the elements of the array.
for (i=0; i<num; i++)
*single_int +=array_int[i];
printf("The total sum is: %d \n" , *single_int);
free(single_int);
free(array_int);
}

?‫ איך עושים זאת‬,‫צריך לבדוק שבאמת המחשב הקצה מקום בזכרון‬
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
long *buffer;
printf("How many numbers to enter ?\n");
scanf("%d" , &num);
//allocate array using calloc –
// all elements are initialized to 0.
buffer = (long *)calloc( num, sizeof( long ) );
//Checks if the allocation succeed.
if( buffer != NULL )
printf("Allocated %d long integers\n" ,num);
else //Didn’t succeed.
{
printf("Can’tallocate memory\n" );
exit(1);
}
free( buffer );
}

Avshalom Elmalech 83120

realloc
:‫סינטקס‬
void *realloc(void *ptr, size_t size)

)calloc ‫ או‬malloc ‫ – מצביע לבלוק שהוקצה דינאמית בעבר ( ע"י‬ptr
‫ מספר התאים המבוקש‬-Size
‫ המשך המקום גם יוקצה‬- ‫ אם יש מספיק מקום בהמשך‬:‫הערה‬
‫ המקום בהמשך יוקצה והערכים ממקודם יועתקו‬- ‫ אבל יש מקום רציף בהמשך‬,‫אם אין מקום‬
.‫למקום החדש‬
NULL ‫– הפונקציה תחזיר‬
‫אם אין רצף בגודל המבוקש פנוי‬
)free(ptr) ‫ מצביע עליו משוחרר (שקול ל‬ptr ‫ – אז המקום ש‬0 ‫אם מכניסים גודל‬
malloc ‫ אז הפונקציה מתנהגת כמו‬NULL ‫ הוא‬ptr
‫אם‬
:‫דוגמא‬
/* Using realloc() to change memory allocation. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buf[80], *message;
/* Input a string. */
puts("Enter a line of text.");
gets(buf);
/* Allocate the initial block and copy the string to it. */
message = realloc(NULL, strlen(buf)+1);
strcpy(message, buf);
/* Display the message. */
puts(message);
/* Get another string from the user. */
puts("Enter another line of text.");
gets(buf);
/* Increase the allocation, then concatenate the string to it. */
message = realloc(message,(strlen(message) + strlen(buf)+1));
strcat(message, buf);
/* Display the new message. */
puts(message);
return(0);
}

Avshalom Elmalech 83120

:‫דוגמא‬
#include <stdio.h>
#include <malloc.h>
int main()
{
int *ptr, i;
if((ptr =(int*) calloc(5, sizeof(int)))==NULL)
{
printf("Not enough memory - calloc failed.\n");
return 1;
}
*ptr = 1;
*(ptr+1) = 2;
ptr[2] = 4;
ptr[3] = 8;
ptr[4] = 16;
if((ptr = realloc(ptr, 7*sizeof(int)))==NULL)
{
printf("Not enough memory - realloc failed.\n");
return 1;
}
printf("Now allocating more memory... \n");
ptr[5] = 32; /* now it's legal! */
ptr[6] = 64;
for(i=0 ; i<7 ; i++)
printf("ptr[%d] holds %d\n", i, ptr[i]);
realloc(ptr,0); /* same as free(ptr); - just fancier! */
while(1<2){;}
return 0;
}

Output:
Now allocating more memory...
ptr[0] holds 1
ptr[1] holds 2
ptr[2] holds 4
ptr[3] holds 8
ptr[4] holds 16
ptr[5] holds 32
ptr[6] holds 64

Avshalom Elmalech 83120