420 likes | 443 Views
Learn about memory addresses, pointers, and pointer arithmetic in computer science. See examples and common errors in using pointers effectively.
E N D
Pointers Department of Computer Science-BGU
כתובת של משתנה נניח משתנים: double x; //8bytes short y ; //2bytes char c ; //1 bytes כאשר בזמן הריצה של התוכנית המחשב יקצה זיכרון למשתנים. לכל תא זיכרון יש ערך מספרי המציין את מיקומו המדויק בזיכרון המחשב. ערך זה מכונה כתובת זיכרון (memory address). • כתובת הזיכרון של משתנה הינה הכתובת של הבית הראשון ברצף הבתים שמשתנה זה תופס בזיכרון. למשל Department of Computer Science-BGU
כתובת של משתנה • האופרטור & • אם x הוא משתנה אזי &x היא כתובת הזיכרון של x, כלומר האופרטור & מציין "כתובתו של…". • ובדוגמא שלנו : • &x = 1000 • &y = 1008 • &c = 1010 • כתובות זיכרון אלו הינם ביטויים בעליי ערך וטיפוס. הטיפוס של כתובת הזיכרון של משתנה כלשהו נגזר מהמשתנה עצמו. 1000 x 1008 y 1010 c Department of Computer Science-BGU
Using pointers מצביע הוא משתנה אשר מכיל כתובת זיכרון. כשנרצה להצהיר על מצביע ל type נוסיף את התו '' משמאל למשתנה . לדוגמא : הגדרת מצביע ל int int <identifier> ; הגדרת מצביע ל char char <identifier> ; הגדרת מצביע ל double double <identifier> ; ברגע שנצהיר על משתנים מצביעים, נוכל להציב לתוכם כתובות של משתנים . לדוגמא נתונה התוכנית הבאה : Department of Computer Science-BGU
C … 7 3 4 … 172 173 174 175 176 177 178 179 180 181 P … 174 3 4 … 832 833 834 835 836 837 838 839 840 841 Pointers • Pointer is a variable that contains the addressof a variable • Here P is said to point to the variable C Department of Computer Science-BGU
Using pointers • The unary operator & gives the address of a variable • The statement P=&C assigns the address of C to the variable P, and now P points to C • To print a pointer, use %p format. Department of Computer Science-BGU
Using pointers int C; int *P; // Declare P as a pointer to int C = 7; P = &C; C … 7 3 4 … 172 173 174 175 176 177 178 179 180 181 P … 174 3 4 … 832 833 834 835 836 837 838 839 840 841 Department of Computer Science-BGU
האופרטור • The unary operator * is applied on pointers • Access the object the pointer points to • The statements: • int * P; • int C; • P = &C; *P=5; Puts in C (the variable pointed by P) the value 5 Department of Computer Science-BGU
האופרטור printf(“%d”, *P); // Prints out ‘7’ *P = 177; printf(“%d”, C); // Prints out ‘177’ P = 177; /* This is unadvisable !!! */ C … 7 3 4 … 177 172 173 174 175 176 177 178 179 180 181 P … 177 174 3 4 … Department of Computer Science-BGU 832 833 834 835 836 837 838 839 840 841
Common errors • It is impossible to define pointers to constants or expressions. • It is also impossible to change a variable’s address (because it is not for us to determine!). • Therefore, the following are errors: • i = &3; • j = &(k+5); • k = &(a==b); • &a = &b; • &a = 150; Department of Computer Science-BGU
Pass arguments by value • The functions we saw till now accepted their arguments “by value” • They could manipulate the passed values • They couldn’t change values in the calling function • But address is a value !! And we can pass the address as argument to functions • Remember ?! void swap(int x, int y) { …swap x and y… } Department of Computer Science-BGU
How can we fix it? void swap(int * x, int * y){ int temp; temp = *x; *x = *y; *y = temp; } void main() { int a=7,b=8; printf("a = %d, b = %d\n", a, b); swap(&a,&b); printf("a = %d, b = %d\n", a, b); } Department of Computer Science-BGU
Back to scanf • We can now understand the & in scanf(“%d”,&a); • The argument list in scanf is simply passed by address, • so scanf can change its content. Department of Computer Science-BGU
Pointer-array equivalence • Arrays are actually a kind of pointers! • When an array is defined, a fixed amount of memory the size of the array is allocated. • The array variable is set to point to the beginning of that memory segment. • When a pointer is declared, it is uninitialized (like a regular variable). Department of Computer Science-BGU
Pointers and Arrays • Recall that an array S holds the address of its first element S[0]. • Assume: • int S[10]; int *P; P=S; // From now P is equivalent to S • S is actually a pointer to S[0] • Both P and S are now pointing to S[0] Department of Computer Science-BGU
Pointer arithmetic • Pointers can be incremented and decremented. • If p is a pointer to a particular type, p+1 yields the correct address of the next variable of the same type. • Is it possible ?? YES • If int * p ; p = p +1; means p = p + sizeof(int); • p++, p+i, and p += i also make same sense. p + 4 means p + (4 * sizeof(int)) Department of Computer Science-BGU
What is this ‘sizeof’ ? • The sizeof operator gets a variable or a type as an input and outputs its size in bytes: double x; s1=sizeof(x); /* s1 is 8 */ s2=sizeof(int) /* s2 is 4 */ Department of Computer Science-BGU
Pointer arithmetic • What about arrays ?? They are pointers !! • Unlike pointers, the value of an array variable cannot be changed. We can write : int a[10]; int * p; p = a; • But the arrays are constants !! So … p++ ; a++; // Correct //Error!! Array Address is constant Department of Computer Science-BGU
Pointer arithmetic - example • If p and q point to elements in an array, q-p yields the number of elements between p and q. • However, there is a difference between pointer arithmetic and “regular” arithmetic. Department of Computer Science-BGU
An additional use • A function that accepts an array and searches for something within it (a char, a number, etc.) • What should the function return? • The index where the ‘something’ was found • A pointer to the place where it was found Department of Computer Science-BGU
Functions that return pointers • Like any other data type, functions can return pointers. • For example, a prototype for a function returning a pointer to char will be –char *func(…); • But how would we indicate failure • Suppose we searched the array and didn’t find anything – what should we return? Department of Computer Science-BGU
The NULL pointer • The NULL pointer is an ‘empty’ pointer that points to nothing. • It is the address number 0. • If a pointer p is set to NULL, trying to access *p results in a run-time (not compilation) error. • Often used to indicate failure Department of Computer Science-BGU
Example- solving quadratic equation - the "easy way" #include <stdio.h> #include <math.h> int quad(double ,double ,double ,double* ,double* ); void main(){ double a,b,c,x1,x2; int res; scanf("%lf%lf%lf",&a,&b,&c); res=quad(a,b,c,&x1,&x2); switch(res){ case 0 : printf("No solution\n"); break; case 1 : printf("x1=x2=%.2f\n",x1); break; case 2 : printf("x1=%.2f , x2=%.2f\n",x1,x2); } } Department of Computer Science-BGU
Function quad(……) /* we assume a!=0 the function return : 0 no solution (we neglect the complex option) 1 two equal roots 2 two different roots */ int quad(double a ,double b ,double c ,double* px1 ,double* px2){ double d = (b*b - 4*a*c); if(d < 0) return 0; if(d==0){ *px1 = *px2 = -b/(2*a); return 1; } *px1= (-b + sqrt(d))/(2*a); *px2= (-b - sqrt(d))/(2*a); return 2; } Department of Computer Science-BGU
Usefully functions בשפת C קיימות פונקציות ספריה לטיפול במחרוזות ותווים. על מנת להשתמש בפונקציות אלו יש להוסיף בתחילת התוכנית את שורות: #include <string.h> #include <ctype.h> דוגמאות לפונקציות לבדיקת תווים : האם התו הוא סיפרה int isdigit(int) האם התו הוא רווח int isspace(int) האם התו הוא אות גדולה int isupper(int) האם התו הוא אות קטנה int islower(int) לפונקציות נוספות עיינו בספרות . Department of Computer Science-BGU
Some functions of string.h • int strncmp(char *s1, char *s2, int n) - returns 0 if the first n letters of s1 are equal to those of s2, and returns non-zero if first n letters are different • char * strchr(char * str, char c)– returns a pointer to the first occurrence of a character within a string • char *strstr(char * st1,char * st2) – returns a pointer to the first occurrence of st1 string within the st2. r • void strncpy(char * st1, char * st2, int n) copies the first n letters of st2 to the address of st1. No copy the ‘\0’ letter to st1 !! Department of Computer Science-BGU
Mystery - What does this do? char *rec_stam(char * str, char c) { if (*str == '\0') return NULL; if (*str == c) return str; returnrec_stam(str+1, c); } A recursive implementation of strchr Return pointer to the first instance of the letter c into the string str Department of Computer Science-BGU
Again mystery – what does this do? void main() { char s[101]; char *p; scanf("%100s", s); p = strchr(s, ','); while(p!=NULL) { *p = ' '; p = strchr(p+1, ','); } printf("The result is - %s\n", s); } Department of Computer Science-BGU
Exercise • Write a recursive implementation of strcmp – • Input – two strings • Output – 0 if both are equal, 1 if not • Write a program that accepts two strings from the user and checks whether they are equal Department of Computer Science-BGU
Solution int strcmp_r(char *s, char *t) { if (*s == '\0' || *s != *t) return *s - *t; else return(strcmp_r(s+1, t+1)); } Department of Computer Science-BGU
Dynamic Memory Allocation Department of Computer Science-BGU
Dynamic Memory Allocation • Array variables have fixed size, used to store a fixed and known amount of variables. • This size can’t be changed after compilation. • However, we don’t always know in advance how much space we would need for an array or a variable. • We would like to be able to dynamically allocate memory. (הקצאה דינמית של זיכרון) Department of Computer Science-BGU
The malloc function void *malloc(unsigned int nBytes); • The function malloc is used to dynamically allocate nBytes worth of space. • How to determine nBytes? • malloc returns a pointer to the allocated area on success, NULL on failure. • You should always check whether memory was successfully allocated. • Remember to #include <stdlib.h> Department of Computer Science-BGU
Example #include <stdio.h> #include <stdlib.h> void main(){ int size ,i; int *ptr2memory ; printf("Enter the series length :"); scanf("%d",&size); ptr2memory=(int*)malloc(size*sizeof(int)) ; /* allocating size ints */ if(ptr2memory==NULL){ printf("Memory allocation failed\n"); exit(1); } /* memory allocation succeeded */ /* can use ptr2memory as array */ } Department of Computer Science-BGU
Why casting? • The type void * specifies a general pointer, which can be cast to any pointer type. • Casting is needed because malloc returns void *: void *malloc(unsigned int nbytes); • Casting for integer : y=(int *) malloc(n*sizeof (int)); Department of Computer Science-BGU
Free the allocated memory segment void free(void *ptr); • We use free(p) to free the allocated memory pointed to by p. • If p doesn’t point to an area allocated by malloc, a run-time error occurs. • Always remember to free the allocated memory once you don’t need it anymore. • Otherwise, you may run out of memory before you know it! Department of Computer Science-BGU
Array of pointers • Problem : Write program that receive strings from a user and print these strings in a lexicography order. • Solution : Array of pointers to char (malloc) char * names[256] or char ** names; This is not the same declaration !! Department of Computer Science-BGU
Array of pointers • Declaration: char ** names; int n,i; scanf(“%d”,&n); names = (char **)malloc(n * sizeof(char *)); for(i=o; i<n; i++){ char[i] = (char*)malloc(256*sizeof(char)); } // bubble on the pointers !! Department of Computer Science-BGU
Complete solution • Assuming that the strings have at most 255 letters: void main(){ char ** names, temp[256]; int n,i; scanf(“%d”,&n); names = (char **)malloc(n * sizeof(char *)); for(i=o; i<n; i++){ gets(temp); char[i] = (char*)malloc(strlen(temp)+1); strcpy(char[i],temp); } /* Sorting pointers by lexicography string order */ } Department of Computer Science-BGU
Complete solution • Assuming that the strings have at most 255 letters: void main(){ char ** names, temp[256]; int n,i; printf(“Enter number of names for sorting\n”); scanf(“%d”,&n); names = fill_sorted(n); for(i=o; i<n; i++){ putsts(char[i]); } } Department of Computer Science-BGU
Complete solution (cont.) char ** fill_sorted(int num){ char ** temp, *aux; int i, flag; /* making an array of pointers */ temp = (char **)malloc(num * sizeof(char *)); /* making and filling strings */ for(i=o; i<n; i++){ gets(temp); char[i] = (char*)malloc(strlen(temp)+1); strcpy(char[i],temp); } Department of Computer Science-BGU
Complete solution (cont.) /* Sorting pointers by lexicography string order */ do{ flag=0; for(i=0; i < num-1 ; i++) if(strcmp(temp[i],temp[i+1]) > 0){ aux = temp[i]; temp[i] = temp[i+1]; temp[i+1] = aux; flag = 1; } }while(flag); return temp; } Department of Computer Science-BGU