1 / 40

Pointers in C Rohit Khokher

Pointers in C Rohit Khokher. Pointers are M emory Addresses. Segment part. Offset part. 0x9FFF : 000F. What does this number really mean?. Address. 0x9FFF0 + 0x 000F = 0x9FFFF 655,359 (0 to 655,359) or (1 to 655,360) or 1 to 640 Kb. 0xFFFF:000F. 0xFFFF0 + 0x 000F = 0xFFFFF.

juliet
Télécharger la présentation

Pointers in C Rohit Khokher

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Pointers in CRohitKhokher

  2. Pointers are Memory Addresses Segment part Offset part 0x9FFF:000F What does this number really mean? Address 0x9FFF0 + 0x 000F = 0x9FFFF 655,359 (0 to 655,359) or (1 to 655,360) or 1 to 640 Kb 0xFFFF:000F 0xFFFF0 + 0x 000F = 0xFFFFF 1 Mb = 1,048,576 Memory address space

  3. Pointers are Memory Addresses • Pointers are variables that contain memoryaddresses as their values. • A variable name directly references to a value (direct addressing). • A pointer indirectly references to a value. Referencing a value through a pointer is called indirection (indirect addressing). A value between 1 to 1,048,576 0xFFFF0 + 0x 000F = 0xFFFFF Segment Offset A pointer points to a memory location that contains the data 0xFFFFF 0xFFFFF 456

  4. Concept of Address and Pointers • Memory can be conceptualized as a linear set of data locations. • A variable refers to the content of a locations • A pointer variable holds the address of a given location that contains the data value. Contents ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 * Address space * * . * * Contents 1048576

  5. POINTERS DECLARATION • Examples of pointer declarations: int *a; float *b; char *c; • The asterisk, in the declaration int *a;, tells the compiler that the variable a is a pointer type, meaning it contains an address (pointer) of a memory location that will contain an integer. What does float *b; meant? What does char *c; mean? address 0xFFFFF 0xFFFFF Content/value 456

  6. POINTERS • Consider the statements: #include <stdio.h> int main ( ) { int*aptr ; /* Declare a pointer to an int */ float *bptr ; /* Declare a pointer to a float */ int a ; /* Declare an int variable */ float b ; /* Declare a float variable */ aptr = &a ; bptr = &b ; What is the difference between int *aptr; and int a; declarations? 0xFFFFF 0xFFFFF Assign the address of a to the location at which aptr is pointing to.

  7. POINTERS float x; float *px; x = 6.5; px= &x; X is an address that would contain a float value Remember! The content of the memory location referenced by a pointer is obtained using the ``*'' operator (this is called dereferencing the pointer). Thus, *px refers to the value of x which is 6.5. 6.5 0xFFFFF px is a pointer to objects of type float meaning that it would contain an address of float type object If the address of x is 0xFFFFF then what would be assigned to px? Store the address of x into px

  8. POINTERS We must associate a pointer to a particular data type. For example, we can't assign the address of a short int to a long int. Why? 0xFFFFF 0xFFFFE Int x = 1, y = 2; Int *ip; ip= &x; y = *ip; *ip= 3; 1 3 2 1 0xFFFFE What is wrong with float a, b; Int x, * p; p=&a;?

  9. POINTERS int*p, *q, x, y; p = &x; q = &y; *p = 10; *q = 20; p = q; *p = *q; When a pointer is declared it does not point anywhere. We must set it to point somewhere before its use. The statements int*p; *p = 10; will generate an error. Why? 10 20

  10. You can see the addresses of the data where in the memory they are loaded { char a; int b; float c; a=‘n’; b= 20; c= 20.5; printf (“%c is stored at address %u,\n”,a,&a); printf (“%d is stored at address %u,\n”,b,&b); printf (“%f is stored at address %u,\n”,c,&c); }

  11. You can see the addresses of the data where in the memory they are loaded { int x, y, *p; X=10; p=&x; y=*p; printf (“value of x is %d is,\n”,x); printf (“%d is stored at address %u,\n”,x,&x); printf (“%d is stored at address %u,\n”,*&x,&x); printf (“%d is stored at address %u,\n”,*p, p); printf (“%d is stored at address %u,\n”, p, &p); printf (“%d is stored at address %u,\n”,y, &y); } Pinter address

  12. a=5; b=6.75; aptr= &a ; bptr = &b ; printf ("%d %d\n", aptr, bptr ) ; printf ("%d %f\n", *aptr, *bptr ) ; printf ("%d %f\n", a , b ) ; printf ( "%d %d\n", &a , &b ) ; return 0 ; } } 1659178974 1659178976 5 6.750000 5 6.750000 1659178974 1659178976 POINTERS

  13. POINTERS double x = 3.14; *p = &x; 3.14 Address of X p will be 3.14 Setting pointer value to null int *p = 0; int *p = NULL; Set pointer value directly double x; *p = &x; *p = 3.14; Make sure pointer has been set to an allocated memory region printf(“%x”,p); Prints a hexadecimal number – the address that p points to For a pointer p, ++p and p++ are both equivalent to p + 1

  14. You can see the addresses of the data where in the memory they are loaded /*Program to illustrate the pointer expression and pointer arithmetic*/ #include< stdio.h > main() { int *p1,*p2; int a, b, x, y, z; a=30; b=6; p1=&a; p2=&b; x=*p1+ *p2 –6; y=6*- *p1/ *p2 +30; printf(“\n Address of a +%u”, p1); printf(“\n Address of b %u”, p2); printf(“\n a=%d, b=%d”, a, b); printf(“\n x=%d, y= %d”, x, y); p1=p1 + 70; p2= p2; printf(“\n a=%d, b=%d”,a,b); } Can Add or subtract integers from pointers. Can subtract one pointer from the other. Can use operators with the pointers p1+=; sum+=*p2; etc., Can use relational operators the expressions such as p1 >p2 , p1==p2 and p1!=p2

  15. Arithmetic and Logical Operations on Pointers • A pointer may be incremented or decremented • An integer may be added to or subtracted from a pointer. • Pointer variables may be subtracted from one another. • Pointer variables can be used in comparisons, but usually only in a comparison to NULL.

  16. Arithmetic Operations on Pointers • When an integer is added to or subtracted from a pointer, the new pointer value is changed by the integer times the number of bytes in the data variable the pointer is pointing to. For example, if the pointer valptr contains the address of a double precision variable and that address is 234567870, then the statement: valptr = valptr + 2; would change valptr to 234567886 8 bytes 234567870 + 2 x 8

  17. Review • A variable is declared as int k; • A pointer variable is declared as int *p; • we can get the address of a declared variable by using the unary & operator as in &k. • We can "dereference" a pointer, i.e. refer to the value of that which it points to, by using the unary '*' operator as in *ptr. • Pointer operators: * dereferences a pointer, & creates a pointer (reference to) • An "lvalue" of a variable is the value of its address, i.e. where it is stored in memory. The "rvalue" of a variable is the value stored in that variable (at that address).

  18. Pointers to Referencing & Derefrencing int x, *y, z, *q; x = 3; y = &x; // y points to x printf("%d\n", x); // outputs 3 printf("%d\n", y); // outputs x’s address, will seem like a random number to us printf("%d\n", *y); // outputs what y points to, or x (3) printf("%d\n", *y+1); // outputs 4 (print out what y points to + 1) printf("%d\n", *(y+1)); // this outputs the item after x in memory – what is it? z = *(&x); // z equals 3 (what &x points to, which is x) q = &*y; // q points to 3 – note *& and &* cancel out

  19. Pointers to Arrays int x = 1, y = 2, z[10]; int *ip; // ip is a pointer to an int, so it can point to x, y, or an element of z ip = &x; // ip now points at the location where x is stored y = *ip; // set y equal to the value pointed to by ip, or y = x *ip = 0; // now change the value that ip points to to 0, so now x = 0 // but notice that y is unchanged ip = &z[0]; // now ip points at the first location in the array z *ip = *ip + 1; // the value that ip points to (z[0]) is incremented You can interact with the array elements either through pointers or by using z[ index]

  20. ip= &z[0]; sets pointer ipto point at the first element of the array In fact, z is a pointer as well and we can access z[0] either using z[0], *ip, or *z What about accessing z[1]? We can do z[1] as usual, or we can add 1 to the location pointed to by ip or z, that is *(ip+1) or *(z+1) While we can reset ip to be ip = ip+1, we cannot reset z to be z = z+1 adding 1 to ip will point to z[1], but if z = z + 1 were legal, we would lose access to the first array location since z is our array variable Notice that ip=ip+1 (or ip++) moves the pointer 4 bytes instead of 1 to point at the next array location if the array were an array of doubles, the increment would move ip to point 8 bytes away, if the array were chars, then ip would be 1 byte further Using Pointers with Arrays Increment depends on the size (in bytes) of the object to which a pointer is pointing at.

  21. Here we see two ways to iterate through an array, the usual way, but also a method using pointer arithmetic Let’s consider the code on the right: pj is a pointer to an int We start with pj pointing at a, that is, pj points to a[0] The loop iterates while pj < a + n pj is a pointer, so it is an address a is a pointer to the beginning of an array of n elements so a + n is the size of the array pj++ increments the pointer to point at the next element in the array The instruction (*pj)++ says “take what pj points to and increment it” NOTE: (*pj)++; increments what pj points to, *(pj++); increments the pointer to point at the next array element what do each of these do? *pj++; ++*pj; Iterating Through the Array int j; for(j = 0; j < n; j++) a[j]++; int *pj; for(pj = a; pj < a + n; pj++) (*pj)++;

  22. Array Example Using a Pointer int x[4] = {12, 20, 39, 43}, *y; y = &x[0]; // y points to the beginning of the array printf("%d\n", x[0]); // outputs 12 printf("%d\n", *y); // also outputs 12 printf("%d\n", *y+1); // outputs 13 (12 + 1) printf("%d\n", (*y)+1); // also outputs 13 printf("%d\n", *(y+1)); // outputs x[1] or 20 y+=2; // y now points to x[2] printf("%d\n", *y); // prints out 39 *y = 38; // changes x[2] to 38 printf("%d\n", *y-1); // prints out x[2] - 1 or 37 *y++; // sets y to point at the next array element printf("%d\n", *y); // outputs x[3] (43) (*y)++; // sets what y points to to be 1 greater printf("%d\n", *y); // outputs the new value of x[3] (44)

  23. Strings • There is no string type in C, strings are arrays of chars • char str[10]; // str is an array of 10 chars or a string • char *str; // str points to the beginning of a string of unspecified length • There is a string.h library with numerous string functions • they all operate on arrays of chars and include: • strcpy(s1, s2) – copies s2 into s1 (including ‘\0’ as last char) • strncpy(s1, s2, n) – same but only copies up to n chars of s2 • strcmp(s1, s2) – returns a negative int if s1 < s2, 0 if s1 = = s2 and a positive int if s1 > s2 • strncmp(s1, s2, n) – same but only compares up to n chars • strcat(s1, s2) – concatenates s2 onto s1 (this changes s1, but not s2) • strncat(s1, s2, n) – same but only concatenates up to n chars • strlen(s1) – returns the integer length of s1 • strchr(s1, ch) – return a pointer to the first occurrence of ch in s1 (or NULL if ch is not present) • strrchr(s1, ch) – same but the pointer points to the last occurrence of ch • strpbrk(s1, s2) – return a pointer to the first occurrence of any character in s1 that matches a character in s2 (or NULL if none are present) • strstr(s1, s2) – substring, return a pointer to the char in s1 that starts a substring that matches s2, or NULL if the substring is not present

  24. Implementing Some of These void strcpy(char *s, char *t) { int i = 0; while((s[i] = t[i]) != ‘\0’) i++;} } int strlen(char *s) { int n; for(n = 0; *s != ‘\0’; s++) n++; return n; } int strcmp(char *s, char *t) { int i; for(i=0;s[i] = = t[i];i++) if(s[i] = = ‘\0’) return 0; return s[i] – t[i]; } strcpy(s1, s2) strlen(s1) strcmp(s1, s2) void strcpy(char *s, char *t) { while((*s = *t) != ‘\0’) { s++; t++; } } int strcmp(char *s, char *t) { for( ; *s = = *t; s++, t++) if(*s = = ‘\0’) return 0; return *s - *t; } Notice in the second strcmp and second and third strcpy the use of pointers to iterate through the strings. The conciseness of the last strcmp and strcpy make them hard to understand strcmp(s1, s2) strccpy(s1, s2) void strcpy(char *s, char *t) { while((*s++ = *t++) != ‘\0’); } Check it copies t[i] into s[i] and checks for NULL strcpy(s1, s2)

  25. More On Pointer Arithmetic Got to the first element Decrease pointer by 1 • We can also perform subtraction on pointers • Here, we pass to a function the address of the third element of an array (&a[2]) and use pointer subtraction to get to a[0] and a[1]) Start with the 10th element int a[10] = {…}; int *ip; for(ip = &a[9]; ip >= a; ip--) … ip = &a[2]; Functions addmem int addem(int *ip) { int temp; temp = *ip + *(ip – 1) + *(ip – 2); return temp; } int a[3] = {…}; printf(“%d”, addem(&a[2])); Recall: a[0] = *a and a[i] = *(a + i) If a is an array, and p = &a[0] then we can reference array elements as a[i], *(p+i), but we can also reference them as p[i] and *(a+i) – that is, a and p are both pointers to the array And can be dereferenced by * or by [ ]

  26. Multidimensional Arrays • C allows multidimensional arrays • Example: int matrix[5][10]; • Some differences: • Because functions can be compiled separately, we must denote all but one dimension of a multiple dimensional array in a function’s parameter list • void afunction (intamatrix[ ][10]); • Because arrays are referenced through pointers, there are multiple ways to declare and access 2+ dimensional arrays • This will be more relevant when dealing with an array of strings (which is a 2-D array) int *a[3]; // array of 3 pointers int x[2] = {1, 2}; int y[3] = {3, 4, 5}; int z[4] = {6, 7, 8, 9}; *a = &x[0]; // a[0] points to x[0] *(a+1) = &y[0]; // a[1] points to y[0] *(a+2) = &z[0]; // a[2] points to z[0] // array a is a jagged array, it is not // rectangular, or of equal dimensions int a[10][20]; int *a[10]; int **a; *a[4] –first element of 5th array element *a[9] –first element of 10th array element **a –first element of a[0]

  27. Pointers to Pointers • As indicated in the last slide, we can have an array of arrays which is really an array of pointers or pointers to pointers • We may wish to use pointers to pointers outside of arrays as well, although it is more common that pointers to pointers represent array of pointers • Consider the following: int a; int *p; int **q; a = 10; p = &a; q = &p; printf(“%d”, **q); // outputs 10 We dereference our pointer p with *p but we dereference our pointer to a pointer q with **q *q is actually p, so **q is a 10 Address of a Address of p

  28. Arrays of Strings Implementation • We could implement an array of strings as a 2-D array of chars • char array[10][10]; • This has two disadvantages • All strings will be 10 chars long • Requires 2 nested for-loops for most operations such as string comparison or string copying, which can become complicated • Instead, we will implement our array of strings as an array of pointers • char *array[10]; • Each pointer points to one string • Follow the string through the pointer • Go to the next string using a for-loop • Because strcpy, strcmp, strlen all expect pointers, we can use these by passing an array element (since each array element is a pointer to a string)

  29. Example char *x[ ] = {"hello\0", "goodbye\0", "so long\0", "thanks \0"}; // our array of strings x is a set of 4 pointers char *y; // let y be a pointer to a char so it can be used to move through a single string int i; for(i=0;i<4;i++) // iterate for each string in x { y = x[i]; // x[i] is an array, x is really a pointer, so this sets y to x’s starting addr. while(*y!='\0') // while the thing y points to is not the end of a string { printf("%c", *y); // print what y points to y++; // and go on to the next char in x } printf("\n"); // separate strings in output with \n } • Notice that if we had used char x[ ][ ] = {…}; then the storage space would have been 4 strings of length 23 (the length of the longest string) or 92 bytes instead of 42 bytes as it is above

  30. When an array is passed to a function, what is being passed is a pointer to the array In the formal parameter list, you can either specify the parameter as an array or a pointer Because you can compile functions separately, the compiler must be able to “know” about an array being passed in to a function, so you must specify all (or most) of the definition: The type and all dimensions except for the first Passing Arrays int array[100]; … afunction(array); … void afunction(int *a) {…} or void afunction(int a[ ]) {…} int array[5][10][15]; … afunction(array); … void afunction(int a[ ][10][15]) {…} or void afunction(int *a[10][15]) {…} or void afunction(int a[5][10][15]) {…} or void afunction(int **a[15]) {…} etc

  31. Some Additional Comments • In functions, do not return p; where p is a pointer • Recall local variables are deallocated when the function ends • so whatever p is pointing to will no longer be available • but if you return the pointer, then you still are pointing at that memory location even though you no longer know what is there • We can declare a pointer to point to a void type, which means that the pointer can point to any type • However, this does require a cast before the pointer can be assigned • int x; float y; void *p; // p can point to either x or y • p = (int *) &x; // p can point to int x once the address is cast • p = (float *) &y; // or p can point to float y • Pointers that don’t currently point to anything have the special value NULL and can be tested as (p = = NULL) or (!p), and (p != NULL) or (p)

  32. Pointers and Structures struct tag { char lname[20]; /* last name */ char fname[20]; /* first name */ int age; /* age */ float rate; /* e.g. 12.75 per hour */ }; struct tag my_struct; /* declare the structure my_struct */ int main(void) { strcpy(my_struct.lname,"Jensen"); strcpy(my_struct.fname,"Ted"); printf("\n%s ",my_struct.fname); printf("%s\n",my_struct.lname); return 0; } It will copy the last name and the first name into the structure Passing structure takes more memory (stack space) , aThe pointer uses a minimum amount of stack space.

  33. Pointers and Structures struct tag{ /* the structure type */ char lname[20]; /* last name */ char fname[20]; /* first name */ Int age; /* age */ float rate; /* e.g. 12.75 per hour */ }; struct tag my_struct; /* define the structure */ void show_name(struct tag *p); /* function prototype */ int main(void) { struct tag *st_ptr; /* a pointer to a structure */ st_ptr = &my_struct; /* point the pointer to my_struct */ strcpy(my_struct.lname,"Jensen"); strcpy(my_struct.fname,"Ted"); printf("\n%s ",my_struct.fname); printf("%s\n",my_struct.lname); my_struct.age = 63; show_name(st_ptr); /* pass the pointer */ return 0; } void show_name(struct tag *p) { printf("\n%s ", p->fname); /* p points to a structure */ printf("%s ", p->lname); printf("%d\n", p->age);

  34. Pointers and Structures struct tag{ /* the structure type */ char lname[20]; /* last name */ char fname[20]; /* first name */ Int age; /* age */ float rate; /* e.g. 12.75 per hour */ }; struct tag my_struct; /* define the structure */ struct tag *st_ptr; An instance of tag in memory, also called instantiation st_ptr = &my_struct; Access a member by de-referencing the pointer. Address of my struct (*st_ptr).age = 63; OR st_ptr -> age = 63;

  35. Pointers to Functions • A function that is capable of sorting virtually any collection of data that can be stored in an array. • The data might be an array of strings, or integers, or floats, or even structures. The sorting algorithm can be the same for all.

  36. Pointers to Functions int arr[10] = { 3,6,1,2,3,8,4,1,7,2}; void bubble(int a[], int N); int main(void) { int i; putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr,10); putchar('\n'); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } return 0; } void bubble(int a[], int N) { int i, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (a[j-1] > a[j]) { t = a[j-1]; a[j-1] = a[j]; a[j] = t; } } } } SORTING AN ARRAY OF INTEGERS

  37. Pointers to Functions void bubble(int *p, int N) { int i, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (compare(&p[j-1], &p[j])) { t = p[j-1]; p[j-1] = p[j]; p[j] = t; } } } } int arr[10] = { 3,6,1,2,3,8,4,1,7,2}; void bubble(int *p, int N); int compare(int *m, int *n); int main(void) { int i; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr,10); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } return 0; } m=&p[j-1], n=&p[j], int compare(int *m, int *n) { return (*m > *n); } SORTING AN ARRAY OF INTEGERS BUT IN THIS COMPARISON Is DONE BY A FUNCTION

  38. Pointers to Functions void bubble(int *p, int N) { inti, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (compare((void *)&p[j-1], (void *)&p[j])) { t = p[j-1]; p[j-1] = p[j]; p[j] = t; } } } } intarr[10] = { 3,6,1,2,3,8,4,1,7,2}; void bubble(int *p, int N); int compare(void *m, void *n); int main(void) { inti; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr,10); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } return 0; } Bubble sort or any program can be made general by identifying the code that can be made general. For example by making the compare function or swapping operations general the same bubble sort can be used for different data types. int compare(void *m, void *n) { int *m1, *n1; m1 = (int *)m; n1 = (int *)n; return (*m1 > *n1);}

  39. Pointers to a Function Remember the difference The function name translates into an address of that function in the code segment. Declaration like int (*fptr)(const void *p1, const void *p2); indicates that we are declaring a function pointer. Pass a pointer to a function as a parameter Declaration int *fptr (const void *p1, const void *p2); indicates that we are declaring a function that will return a pointer to an integer type. void bubble(void *p, int width, int N, int(*fptr)(const void *, const void *)); intcompare_string(const void *m, const void *n); intcompare_long(const void *m, const void *n); intcompare_string(const void *m, const void *n) { char *m1 = (char *)m; char *n1 = (char *)n; return (strcmp(m1,n1)); } Int main (void){ /* in the caller origram */ ……. bubble(arr, 4, 10, compare_long); /* sort the longs */ bubble(arr2, 20, 5, compare_string); ……. } intcompare_long(const void *m, const void *n) { long *m1, *n1; m1 = (long *)m; n1 = (long *)n; return (*m1 > *n1); }

  40. Pointers and Dynamic Allocation ofMemory What is compile time allocation? What is run time allocation? Allocate memory at run time using malloc(), calloc() Return a pointer to the first byte of the allocated block. The ANSI compiler return void type pointer int *iptr; iptr = (int *) malloc(10 * sizeof (int)); if (iptr == NULL) { …. Error….} for (k = 0; k < 10; k++) Iptr [k] = 2; Allocates 10 memory locations to store the 10 integers. Access the allocated locations #define COLS 5 typedefintRowArray[COLS]; RowArray *rptr; int main(void) { intnrows = 10; int row, col; rptr = malloc(nrows * COLS * sizeof(int)); for (row = 0; row < nrows; row++) { for (col = 0; col < COLS; col++) { rptr[row][col] = 17;}} return 0;} Explain

More Related