WHAT IS A POINTER Simply stated a pointer

  • Slides: 26
Download presentation
WHAT IS A POINTER? • Simply stated, a pointer is an address. • A

WHAT IS A POINTER? • Simply stated, a pointer is an address. • A running program consists of three parts: execution stack, code, and data. They are stored in main memory. • Each cell of the main memory has an address. A pointer variable is a variable whose value is either NULL (0) or a legal address. pointers 1

Why pointers? Pointers are used in programs to access memory and manipulate addresses. To

Why pointers? Pointers are used in programs to access memory and manipulate addresses. To get the effect of call-by-reference in C, we must use pointers in the parameter list of a function definition and pass addresses of variables as arguments in the function call. To hold the memory location of a chunk of dynamically allocated memory block. pointers 2

How to declare pointers: A pointer must be defined to point to some type

How to declare pointers: A pointer must be defined to point to some type of variable. Following a proper definition, it cannot be used to point to any other type of variable or it will result in a "type incompatibility" error. Declaration examples: int *p, **pp; // how to read? char *cp; float *fp 1, *fp 2, *fp 3; pointers 3

Example: int k = 567, *p; p = &k; // p refers to k

Example: int k = 567, *p; p = &k; // p refers to k // p points to k // p contains the address of k 567 p k pointers 4

How to initialize pointers? A pointer variable must be initialized to an address of

How to initialize pointers? A pointer variable must be initialized to an address of something before you can access the value located at that address. Two operators: & address operator * dereference operator pointers 5

Example: int x = 5, y = 6, z; int *px, *py; *pz; px

Example: int x = 5, y = 6, z; int *px, *py; *pz; px = &x; py = &y; pz = &z; *pz = *px + *py; // z = x + y (11) y = 2 * *px + y; // y = ? pointers 6

Example: // the dereference operator * is the // inverse of the address operator

Example: // the dereference operator * is the // inverse of the address operator & double x, y, *p; p = &x; y = *p; // y = *&x; or y = x; int a, *p = &a; // OK int *p = &a, a; // wrong pointers 7

Exercises: int i = 3, j = 5, *p = &i, *q = &j,

Exercises: int i = 3, j = 5, *p = &i, *q = &j, *r; double x; Expression p == &i p=i+7 **&p r = &x 7 **p/*q+7 *(r =&j)*=*p Equivalence p == (&i) p = (i + 7) *(*(&p)) r = (&x) (((7*(*p)))/(*q))+7 (*(r =(&j)))*= (*p) pointers Value 1 illegal 3 illegal 11 15 8

Pointers to void: void * is a generic pointer type (in ANSI C). int

Pointers to void: void * is a generic pointer type (in ANSI C). int x = 6, *px = &x; void * vp; double *qx; qx = px; // illegal vp = px; // ok qx = vp; // ok qx = (double*) px; // ok pointers 9

Call by Reference vs Call by Value: • When variables are passed as arguments

Call by Reference vs Call by Value: • When variables are passed as arguments to a function, their values are copied to the corresponding function parameters, and variables themselves are not changed in the calling environment. This Call-by-Value mechanism is strictly enforced in C. • For a function to effect Call-by-Reference, pointers must be used in the parameter list of the function definition. Then, when the function is called, addresses of variables must be passed as arguments. pointers 10

Example: Before swap: void swap(int *p, int *q) { int tmp; tmp = *p;

Example: Before swap: void swap(int *p, int *q) { int tmp; tmp = *p; *p = *q; *q = tmp; } int main(void) { int a = 3, b = 7; swap(&a, &b); } pointers p a=3 q b=7 After swap: p a=7 q b=3 11

Example: return multi-values through pointers void minmax(int table[], int n, int *minp, int *maxp){

Example: return multi-values through pointers void minmax(int table[], int n, int *minp, int *maxp){ int i, min = INT_MIN, max = INT_MAX; for (i = 0; i < n; i++) if (table[i] < min) min = table[i]; else if (table[i] > max) max = table[i]; *minp = min; *maxp = max; } int main(){ int table[] = {10, 15, 38, 27, -21, 88, 69}; int min, max; minmax(table, 7, &min, &max); // print min and max } pointers 12

Array and Pointers: An array name by itself is a base address, or pointer

Array and Pointers: An array name by itself is a base address, or pointer value, and can be thought of as a constant pointer. The base address of an array is the initial location in memory where the array is stored, that is, it is the address of the first element (index 0) of the array. pointers 13

Relationship between Arrays and Pointers: #define N 100 int a[N], *pa, sum, i; //

Relationship between Arrays and Pointers: #define N 100 int a[N], *pa, sum, i; // suppose array a has been initialized pa = a; equivalent pa = &a[0]; pa = a + 10; equivalent pa = &a[10]; sum = 0; for ( pa = a; pa < &a[N]; pa++) sum += *pa; sum = 0; for ( i = 0; i < N; i++) sum += a[i]; pointers 14

Example: return multi-values through an array void minmax(int table[], int n, int results[]){ int

Example: return multi-values through an array void minmax(int table[], int n, int results[]){ int i, min = INT_MIN, max = INT_MAX; for (i = 0; i < n; i++) if (table[i] < min) min = table[i]; else if (table[i] > max) max = table[i]; results[0] = min; results[1] = max; } int main(){ int table[] = {10, 15, 38, 27, -21, 88, 69}; int results[2]; minmax(table, 7, results); // print results[0] and result[1] } pointers 15

Passing arrays to functions: int sum(int a[], int n){ int j, s = 0;

Passing arrays to functions: int sum(int a[], int n){ int j, s = 0; for (j = 0; j < n; j++) s+= a[j]; return s; } Calls sum(v, 100) sum(v, 88) sum(&v[7], k-7) sum(v + 7, 2*k) What gets computed v[0] + v[1] + … + v[99] v[0] + v[1] + … + v[87] v[7] + v[8] + … + v[k-1] v[7] + v[8] + … + v[2*k+6] pointers 16

Pointer Arithmetic: Pointer arithmetic is automatically done in units of the pointer’s underlying base

Pointer Arithmetic: Pointer arithmetic is automatically done in units of the pointer’s underlying base type. If p is a pointer to a particular type, then p + 1 yields the correct machine address for storing or accessing the next variable of that type. In a similar fashion, p + i, ++p, p+= i all make sense. If p and q are both pointing to elements of an array, then p – q yields the integer value representing the number of elements between p and q. pointers 17

Pointer Arithmetic: The only legal arithmetic operators on pointers are adding or subtracting an

Pointer Arithmetic: The only legal arithmetic operators on pointers are adding or subtracting an integer, or subtracting one pointer from another. Pointers can be compared ( == != < <= > >= ). Two pointers are equal only if they point to the same location. One pointer is less than another if it points a lower location in memory. Don’t compare pointers that don’t access the same array. pointers 18

Another Example: Suppose we want to implement a statistics program for an array of

Another Example: Suppose we want to implement a statistics program for an array of data. Functions to be implemented are: double maximum(double a[], int n); double average(double a[], int n); double sum(double a[], int n); Problem: inefficient code because each function involves a for loop. pointers 19

Efficient code - using pointers: void stat(double a[], int n, double *p_ave, double *p_max,

Efficient code - using pointers: void stat(double a[], int n, double *p_ave, double *p_max, double *p_sum) { int i; *p_max = *p_sum = a[0]; for (i = 1; i < n; i++){ *p_sum += a[i]; if (*p_max < a[i]) *p_max = a[i]; } *p_ave = *p_sum/(double) n; } pointers 20

Pointer as return value: int * search(int a[], int n, int key) { int

Pointer as return value: int * search(int a[], int n, int key) { int *p = a, *ep = a + n; while (p < ep && *p != key) p++; return p != ep ? p : NULL; } int * foo(…) // A common mistake { int a = 5; return &a; } pointers 21

Pointers and Efficiency: int a[], sum, i, *p, *ep; // assume a[] is initialized

Pointers and Efficiency: int a[], sum, i, *p, *ep; // assume a[] is initialized // run the following schemes 10000 times // scheme 1 20 Sec sum = 0; for (i = 0; i < 10000; i++) sum += a[i]; // scheme 2 13 Sec (35% speed up) sum = 0; p = a; for (i = 0; i < 10000; i++) sum += *p; // scheme 3 12 Sec (40% speed up) sum = 0; p = a; ep = a + 10000; while (p < ep) sum += *p++; pointers 22

Generic Pointers: // suppose we want to copy one array into another double f[10],

Generic Pointers: // suppose we want to copy one array into another double f[10], g[10]; f = g; // illegal, f is a constant address memcpy(f, g, sizeof(g)); // call library function --------------------------------void *memcpy(void *xp, const void *yp, size_t n){ unsigned char *dp = xp; const unsigned char *sp = yp; const unsigned char *ep = yp + n; while (sp < ep) *dp++ = *sp++; return xp; } pointers 23

Dynamical Memory Allocation: C requires the number of items in an array to be

Dynamical Memory Allocation: C requires the number of items in an array to be known at compile time. Too big or too small? Dynamical memory allocation allow us to specify an array’s size at run time. Two important library functions are malloc, which allocates space from HEAP, and free, which returns the space (allocated by malloc) back to HEAP for reuse later. pointers 24

Example: /* allocate and free an array of doubles, with error check */ #include

Example: /* allocate and free an array of doubles, with error check */ #include <stdio. h> #include <stddef. h> // definition of NULL #include <stdlib. h> // definition for malloc/free double *dcreate(int n){ double* dp; if ((dp = malloc(n*sizeof(double)) != NULL) return dp; printf(“dcreate: dynamic allocation failed. ”); exit(0); } void dfree(double *dp){ if (dp != NULL) free(dp); } pointers 25

Some Comments: Don’t assume malloc will always succeed. Don’t assume the dynamically allocated memory

Some Comments: Don’t assume malloc will always succeed. Don’t assume the dynamically allocated memory is initialized to zero. Don’t modify the pointer returned by malloc. free only pointers obtained from malloc, and don’t access the memory after it has been freed. Don’t forget to free memory which is no longer in use (garbage). pointers 26