Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointers in C Rohit Khokher. Pointers are Memory Addresses 1 Mb = 1,048,576 0x9FFF : 000F Segment partOffset part What does this number really mean? 0x9FFF0.

Similar presentations


Presentation on theme: "Pointers in C Rohit Khokher. Pointers are Memory Addresses 1 Mb = 1,048,576 0x9FFF : 000F Segment partOffset part What does this number really mean? 0x9FFF0."— Presentation transcript:

1 Pointers in C Rohit Khokher

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

3 Pointers are Memory Addresses Pointers are variables that contain memory addresses 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). 0xFFFF0 + 0x 000F = 0xFFFFF A value between 1 to 1,048,576 SegmentOffset 0xFFFFF 456 A pointer points to a memory location that contains the data

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 * * *. * * 1048576 Address space

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? 0xFFFFF 456 address Content/ value

6 POINTERS Consider the statements: #include 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 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 6.5 Store the address of x into px px is a pointer to objects of type float meaning that it would contain an address of float type object 0xFFFFF If the address of x is 0xFFFFF then what would be assigned to px? If the address of x is 0xFFFFF then what would be assigned to px? 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.

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? Int x = 1, y = 2; Int *ip; ip= &x; y = *ip; *ip= 3; 12 0xFFFFE 0xFFFFF 0xFFFFE 13 What is wrong with float a, b; Int x, * p; p=&a;?

9 POINTERS 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? int*p, *q, x, y; p = &x; q = &y; *p = 10; *q = 20; p = q; *p = *q; 1020

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 POINTERS 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 1659178974 1659178976

13 POINTERS double x = 3.14; *p = &x; p will be 3.14 3.14 Address of X Set pointer value directly double x; *p = &x; *p = 3.14; Make sure pointer has been set to an allocated memory region Setting pointer value to null int *p = 0; int *p = NULL; 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 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 Using Pointers with Arrays ip = &z[0]; sets pointer ip to 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 Increment depends on the size (in bytes) of the object to which a pointer is pointing at.

21 Iterating Through the Array 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; 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 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 int strlen(char *s) { int n; for(n = 0; *s != ‘\0’; s++) n++; return n; } void strcpy(char *s, char *t) { while((*s = *t) != ‘\0’) { s++; t++; } } void strcpy(char *s, char *t) { while((*s++ = *t++) != ‘\0’); } void strcpy(char *s, char *t) { int i = 0; while((s[i] = t[i]) != ‘\0’) i++;} } 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]; } 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 int strcmp(char *s, char *t) { for( ; *s = = *t; s++, t++) if(*s = = ‘\0’) return 0; return *s - *t; } strlen(s1) strcmp(s1, s2) strcpy(s1, s2) strccpy(s1, s2)strcmp(s1, s2) strcpy(s1, s2) Check it copies t[i] into s[i] and checks for NULL

25 More On Pointer Arithmetic 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]) int a[10] = {…}; int *ip; for(ip = &a[9]; ip >= a; ip--) … int a[3] = {…}; printf(“%d”, addem(&a[2])); int addem(int *ip) { int temp; temp = *ip + *(ip – 1) + *(ip – 2); return temp; } 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 [ ] Start with the 10 th element Got to the first element Decrease pointer by 1 Functions addmem ip = &a[2];

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 (int amatrix[ ][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[10][20]; int *a[10]; int **a; *a[4] –first element of 5 th array element *a[9] –first element of 10 th array element **a –first element of a[0] 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

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 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 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 }

30 Passing Arrays 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 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; Lname [20 Fname [20] age rate An instance of tag in memory, also called instantiation st_ptr = &my_struct; Address of my struct (*st_ptr).age = 63; OR Access a member by de- referencing the pointer. 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 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; } 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 compare(int *m, int *n) { return (*m > *n); } m=&p[j-1], n=&p[j], SORTING AN ARRAY OF INTEGERS BUT IN THIS COMPARISON Is DONE BY A FUNCTION

38 Pointers to Functions int arr[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) { 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; } 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((void *)&p[j-1], (void *)&p[j])) { t = p[j-1]; p[j-1] = p[j]; p[j] = t; } } } } int compare(void *m, void *n) { int *m1, *n1; m1 = (int *)m; n1 = (int *)n; return (*m1 > *n1);} 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.

39 Pointers to a Function 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. 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 *)); int compare_string(const void *m, const void *n); int compare_long(const void *m, const void *n); Pass a pointer to a function as a parameter Remember the difference Int main (void){ /* in the caller origram */ ……. bubble(arr, 4, 10, compare_long); /* sort the longs */ bubble(arr2, 20, 5, compare_string); ……. } int compare_string(const void *m, const void *n) { char *m1 = (char *)m; char *n1 = (char *)n; return (strcmp(m1,n1)); } int compare_long(const void *m, const void *n) { long *m1, *n1; m1 = (long *)m; n1 = (long *)n; return (*m1 > *n1); }

40 Pointers and Dynamic Allocation of Memory Allocate memory at run time using malloc(), calloc() What is run time allocation? What is compile time allocation? 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 typedef int RowArray[COLS]; RowArray *rptr; int main(void) { int nrows = 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


Download ppt "Pointers in C Rohit Khokher. Pointers are Memory Addresses 1 Mb = 1,048,576 0x9FFF : 000F Segment partOffset part What does this number really mean? 0x9FFF0."

Similar presentations


Ads by Google