Presentation is loading. Please wait.

Presentation is loading. Please wait.

Arrays and Pointers.

Similar presentations


Presentation on theme: "Arrays and Pointers."— Presentation transcript:

1 Arrays and Pointers

2 Values vs Locations Variables name memory locations, which hold values. New Type : Pointer A pointer contains a reference to another variable (its address) value 1024: 32 x address name

3 Pointer int x; int * xp ; xp = &x ; *xp = 0; /* Assign 0 to x */
pointer to int int x; Pointers Abstractly int x; int *p; p=&x; ... (x == *p) True (p == &x) True 1024: 32 int * xp ; x xp = &x ; 1024 xp address of x *xp = 0; /* Assign 0 to x */ *xp = *xp + 1; /* Add 1 to x */

4 Pointers A variable in a program is stored in a certain number of bytes at a particular memory location, or address, in the machine. A pointer is the address of a variable in memory. If v is a variable, &v is its address. Declare p to be of type pointer to int. int * p; p = &i ; p = NULL; p = (int *) 1776; /* an absolute address in memory */

5 /*Declaring pointer variables*/
char * cp; /* pointer to char */ double * dp; /* pointer to double */ int * ip; /* pointer to int */ Operators for pointers The indirection operator * or dereferencing operator the value pointed to by -- if ptr = &i, *ptr and i mean the same thing. *ptr = *ptr + 1; /* i=5 */ ptr = ptr+1; /* modifies the memory address stored in ptr. */ The address operator & Generates the memory address of its operand (must be some- thing that is a memory object) int i = 4 ; int *ptr ; ptr = &i;

6 Pointers If p is a pointer *p is the value of the variable of which p is the address. 3. 1. int a=1, b=2, *p; b = *p ; p a b b a p 1 2 1 1 p = &a; 2. a b p 1 2

7 Call by value Program1 void swap1 (int x, int y) { int temp; temp = x;
x = y; y = temp; } main 3 5 i j swap1 int main (void ) { int i = 3, j = 5; swap1 (i, j) ; printf (“%d,%d\n”,i,j); return 0; } 3 5 5 3 x y temp 3,5

8 Call by reference: output parameters
Program2 void swap2 (int *px, int *py) { int temp; temp = *px; *px = *py; *py = temp; } main 1024: 3 992: 5 i j int main (void ) { int i = 3, j = 5; swap2(&i, &j) ; printf (“%d,%d\n”,i,j); return 0; } swap2 1024 992 px py 5,3

9 Dissection of swap2 () Call by value is used in C : whenever variables are passed as arguments to a function, their values are copied to the corresponding function parameters, and the variables themselves are not changed in the calling environment. In program 2, the addresses of the variables i and j (&i and &j) are passed to swap2. These addresses are copied to the pointer variables px and py respectively. px and py thus contain the addresses of i and j (local variables of main). Using px and py, the locations i and j can be accessed and their contents can be modified.

10 Call by reference Some programming languages provide the call-by-reference mechanism that can be used to change the values of variables in the calling environment. C does not. In C, the effect of call-by-reference is achieved by : 1. Declaring a function parameter to be a pointer 2. Using the dereferenced pointer in the function body 3. Passing an address as an argument when the function is called.

11 Vocabulary Dereferencing or indirection : Output parameter:
following a pointer to a memory location Output parameter: a pointer parameter of a function can be used to provide a value (input), and/or store a changed value (output)

12 scanf demystified int x, y ; printf (“%d %d %d”, x, y, x+y) ;
What about scanf ? scanf (“%d%d%d”,x,y,x+y); NO ! scanf (“%d%d”, &x, &y); YES !

13 Why use pointers ? as output parameters:
functions that need to change their actual parameters. to get multiple “return” values: functions that need to return several results to create dynamic data structures

14 Arrays and pointers An array name is an address, or a pointer value.
Pointers as well as arrays can be subscripted. A pointer variable can take different addresses as values. An array name is an address, or pointer, that is fixed.

15 Arrays and pointers int a[20], i, *p;
The expression a[i] is equivalent to *(a+i) p[i] is equivalent to *(p+i) When an array is declared the compiler allocates a sufficient amount of contiguous space in memory. The base address of the array is the address of a[0]. Suppose the system assigns 300 as the base address of a. a[0], a[1], ...,a[19] are allocated 300, 304, ..., 376.

16 Arrays and pointers #define N 20 int a[2N], i, *p, sum;
p = a; is equivalent to p = *a[0]; p is assigned 300. Pointer arithmetic provides an alternative to array indexing. p=a+1; is equivalent to p=&a[1]; (p is assigned 304) for (p=a; p<&a[N]; ++p) sum += *p ; p=a; for (i=0; i<N; ++i) sum += p[i] ; for (i=0; i<N; ++i) sum += *(a+i) ;

17 Arrays and pointers a is a constant pointer. a=p; ++a; a+=2; illegal
int a[N]; a is a constant pointer. a=p; ++a; a+=2; illegal

18 Pointer arithmetic and element size
double * p, *q ; The expression p+1 yields the correct machine address for the next variable of that type. Other valid pointer expressions: p+i ++p p+=i p-q /* No of array elements between p and q */

19 Arrays, Pointers, Strings
Lecture 18 19/2/2002

20 Pointer arithmetic and element size
double a[2], * p, *q ; p=a; /*points to base of array*/ q=p+1; /*  q=&a[1] */ printf(“%d\n”, q-p); /* 1 printed */ printf(“%d\n”, (int)q - (int)p); /* 8 printed */

21 Arrays as function arguments
In a function definition, a formal parameter that is declared as an array is actually a pointer. When an array is passed as an argument to a function, the base address of the array is passed “call by value”. The array elements are not copied. double sum (double *a, int n) { int i; double sum; for (i=0,sum=0.0; i<n; i++) sum += a[i]; return sum; } double sum (double a[], int n) { int i; double sum; for (i=0,sum=0.0; i<n; i++) sum += a[i]; return sum; }

22 Recursively finding the sum
double sum (int a[], int n) { if ( ) return ; return ; } n == 0 a[0] sum (a+1, n-1)

23 Various ways that sum() might be called
What gets computed and returned Invocation

24 Recursive programs using arrays
int sum (int a[], int size) { if (size==0) return 0; return a[0]+sum(a+1,size-1); } void reverse (int a[], int size) { if (size==0 || size==1) return; swap2 (&a[0], &a[size-1]); reverse (a+1,size-2); } could have written swap2(a,a+size-1);

25 Recursive programs using arrays
int * binsearch (int elem, int a[], int size) { if (size==0) return NULL; mid = size/2; if (elem == a[mid]) return &a[mid]; if (elem > a[mid]) { return binsearch (elem, a+mid+1, size-mid-1); } else return (elem, a, mid);

26 Recursive programs using arrays
void remove (char c, char s[]) { char * p; if (s[0]==‘\0’) return; if (s[0] == c) { shiftleft (s); remove (c, s); } else remove (c, s+1); void shiftleft (char s[]) { int i; for (i=0; s[i] !=‘\0’;i++) { s[i] = s[i+1]; }

27 Strings 1-d arrays of type char
By convention, a string in C is terminated by the end-of-string sentinel \0 (null character) char s[21] - can have variable length delimited with \0. Max length is 20 as the size must include storage needed for the delimiter. String constants : “hello”, “abc” “abc” is a character array of size 4.

28 Strings A string constant is treated as a pointer. Its value is the base address of the string. char *p = “abc”; printf (“%s %s\n”,p,p+1); /* abc bc is printed */ p a b c \0

29 Differences : array & pointers
char s[] = “abcde”;  char s[] = {‘a’,’b’,’c’,’d’,’e’.’\0’}; The compiler allocates 6 bytes of memory for the array s which are initialized with the 6 characters. char *p = “abcde”; The compiler allocates space for p, puts the string constant “abcde” in memory somewhere else, initializes p with the base address of the string constant. p s a b c d e \0 a b c d e \0

30 A program using strings
/* Count the number of words in a string */ #include <ctype.h> int word_cnt (char s[]) { int cnt = 0, i; for (i=0; s[i] != ‘\0’) { while (isspace(s[i])) /* skip white space */ ++i; if (s[i] != ‘\0’) { /* found a word */ ++cnt; while (!isspace(s[i]) && s[i]!=‘\0’) /* skip the word */ } return cnt;

31 The program with pointers
/* Count the number of words in a string */ #include <ctype.h> int word_cnt (char *s) { int cnt = 0; while (*s != ‘\0’) { while (isspace(*s)) /* skip white space */ ++s; if (*s != ‘\0’) { /* found a word */ ++cnt; while (!isspace(*s) && *s!=‘\0’) /* skip the word */ } return cnt;

32 String-handling functions in the standard library
#define string.h char *strcat (char *s1, const char *s2); Takes 2 strings as arguments, concatenates them, and puts the result in s1. Returns s1. Programmer must ensure that s1 points to enough space to hold the result. char *strcat(char *s1, const char *s2) { char *p = s1; while (*p) /* go to the end */ ++p; while (*p++ = *s2++) /* copy */ ; return s1; }

33 Dissection of the strcat() function
char *p = s1; p is being initialized, not *p. The pointer p is initialized to the pointer value s1. Thus p and s1 point to the same memory location. while (*p) ++p; /*  while (*p != ‘\0’) ++p; */ As long as the value pointed to by p is non-zero, p is incremented, causing it to point at the next character in the string. When p points to \0, the expression *p has the value 0, and control exits the while statement. while (*p++ = *s2++) ; At the beginning, p points to the null character at the end of string s1. The characters in s2 get copied one after another.

34 int strcmp (const char *s1, const char *s2);
Two strings are passed as arguments. An integer is returned that is less than, equal to, or greater than 0, depending on whether s1 is lexicographically less than, equal to, or greater than s2. int strcmp(char *s1, char *s2) { for (;*s1!=‘\0’&&*s2!=‘\0’; s1++,s2++) { if (*s1>*s2) return 1; if (*s2>*s1) return -1; } if (*s1 != ‘\0’) return 1; if (*s2 != ‘\0’) return -1; return 0;

35 char *strcpy (char *s1, const char *s2);
The characters is the string s2 are copied into s1 until \0 is moved. Whatever exists in s1 is overwritten. It is assumed that s1 has enough space to hold the result. The pointer s1 is returned. size_t strlen (const char *s); A count of the number of characters before \0 is returned. size_t strlen (const char *s) { size_t n; for (n=0; *s!=‘\0’; ++s) ++n; return n; } char * strcpy (char *s1, char *s2) { char *p = s1; while (*p++ = *s2++) ; return s1; }

36 Examples of string handling functions
char s1[] = “beautiful big sky country”, s2[] = “how now brown cow”; Expression Value strlen (s1) strlen (s2+8) strcmp(s1,s2) Statements What gets printed printf(“%s”,s1+10); strcpy(s1+10,s2+8); strcat(s1, “s!”); printf(“%s”, s1);

37 Examples of string handling functions
char s1[] = “beautiful big sky country”, s2[] = “how now brown cow”; Expression Value strlen (s1) strlen (s2+8) strcmp(s1,s2) negative integer Statements What gets printed printf(“%s”,s1+10); big sky country strcpy(s1+10,s2+8); strcat(s1, “s!”); printf(“%s”, s1); beautiful brown cows!

38 Arrays, Pointers, Strings
Lecture 19 21/2/2002

39 String-handling functions in the standard library
#define string.h char *strcat (char *s1, const char *s2); Takes 2 strings as arguments, concatenates them, and puts the result in s1. Returns s1. Programmer must ensure that s1 points to enough space to hold the result. char *strcat(char *s1, const char *s2) { char *p = s1; while (*p) /* go to the end */ ++p; while (*p++ = *s2++) /* copy */ ; return s1; }

40 Dissection of the strcat() function
char *p = s1; p is being initialized, not *p. The pointer p is initialized to the pointer value s1. Thus p and s1 point to the same memory location. while (*p) ++p; /*  while (*p != ‘\0’) ++p; */ As long as the value pointed to by p is non-zero, p is incremented, causing it to point at the next character in the string. When p points to \0, the expression *p has the value 0, and control exits the while statement. while (*p++ = *s2++) ; At the beginning, p points to the null character at the end of string s1. The characters in s2 get copied one after another.

41 int strcmp (const char *s1, const char *s2);
Two strings are passed as arguments. An integer is returned that is less than, equal to, or greater than 0, depending on whether s1 is lexicographically less than, equal to, or greater than s2. int strcmp(char *s1, char *s2) { for (;*s1!=‘\0’&&*s2!=‘\0’; s1++,s2++) { if (*s1>*s2) return 1; if (*s2>*s1) return -1; } if (*s1 != ‘\0’) return 1; if (*s2 != ‘\0’) return -1; return 0;

42 char *strcpy (char *s1, const char *s2);
The characters is the string s2 are copied into s1 until \0 is moved. Whatever exists in s1 is overwritten. It is assumed that s1 has enough space to hold the result. The pointer s1 is returned. size_t strlen (const char *s); A count of the number of characters before \0 is returned. size_t strlen (const char *s) { size_t n; for (n=0; *s!=‘\0’; ++s) ++n; return n; } char * strcpy (char *s1, char *s2) { char *p = s1; while (*p++ = *s2++) ; return s1; }

43 Examples of string handling functions
char s1[] = “beautiful big sky country”, s2[] = “how now brown cow”; Expression Value strlen (s1) strlen (s2+8) strcmp(s1,s2) Statements What gets printed printf(“%s”,s1+10); strcpy(s1+10,s2+8); strcat(s1, “s!”); printf(“%s”, s1);

44 Examples of string handling functions
char s1[] = “beautiful big sky country”, s2[] = “how now brown cow”; Expression Value strlen (s1) strlen (s2+8) strcmp(s1,s2) negative integer Statements What gets printed printf(“%s”,s1+10); big sky country strcpy(s1+10,s2+8); strcat(s1, “s!”); printf(“%s”, s1); beautiful brown cows!

45 Multidimensional Arrays

46 Multidimensional Arrays
double a[100]; int b[4][6]; char c[5][4][9]; A k-dimensional array has a size for each dimensions. Let si be the size of the ith dimension. If array elements are of type T and v=sizeof(T), the array declaration will allocate space for s1*s2*...*sk elements which is s1*s2*...*sk*v bytes.

47 2-dimensional Arrays It is convenient to think of a 2-d array as a rectangular collection of elements . int a[3][5] col0 col1 col2 col3 col4 row0 a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] row1 a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] row2 a[2][0] a[2][1] a[2][2] a[2][3] a[2][4] row3 a[3][0] a[3][1] a[3][2] a[3][3] a[3][4]

48 Pointers and multi-d arrays
There are numerous ways to access elements of a 2-d array. a[i][j] is equivalent to: *(a[i]+j) (*(a+i)[j]) *((*(a+i))+j) *(&a[0][0] + 5*i + j)

49 Pointers and multi-d arrays
We can think of a[i] as the ith row of a. We can think of a[i][j] as the element in the ith row, jth column. The array name, a (&a[0]) is a pointer to an array of 5 integers. The base address of the array is &a[0][0]. Starting at the base address the compiler allocates contiguous space for 15 ints.

50 The storage mapping function
(The mapping between pointer values and array indices.) int a[M][N]; The storage mapping function : a[i][j] is equivalent to *(&a[0][0] + N*i + j)

51 Formal parameter declarations
When a multi-dimensional array is a formal parameter in a function definition, all sizes except the first must be specified so that the compiler can determine the correct storage mapping function. In the header of the function definition, the following 3 parameter declarations are equivalent: int a[][5] int a[3][5] int (*a)[5] int sum ( int a[][5] ) { int i, j, sum=0; for (i=0; i<3; i++) for (j=0; j<5; j++) sum += a[i][j]; return sum; }

52 3-dimensional arrays int a[X][Y][Z];
The compiler will allocate X*Y*Z contiguous ints. The base address of the array is &a[0][0][0] Storage mapping function : a[i][j][k]  *(&a[0][0][0] + Y*Z*i +Z*j + k) In the header of the function definition, the following 3 parameter declarations are equivalent: int a[][Y][Z], int a[X][Y][Z], int (*a)[Y][Z]

53 Initialization : multi-d arrays
int a[2][3] = {1,2,3,4,5,6}; int a[2][3] = {{1,2,3}, {4,5,6}}; int a[][3] = {{1,2,3}, {4,5,6}};

54 The use of typedef #define N 4 typedef double scalar;
typedef scalar vector[N]; typedef scalar matrix[N][N]; or typedef vector matrix[N];

55 void add (vector x, vector y, vector z) {
int i; for (i=0; i<N; i++) x[i] = y[i]+z[i]; } scalar dot_product (vector x, vector y) { scalar sum = 0.0; sum += x[i]*y[i]; return sum;

56 void multiply (matrix x, matrix y, matrix z) {
int i, j, k; for (i=0; i<N; i++) { for (j=0; j<N; j++) { x[i][j] = 0.0; for (k=0; k<N; k++) { x[i][j] += y[i][k]*z[k][j]; }

57 Multidimensional Arrays
Lecture 20 4/3/2002

58 Multidimensional Arrays
double a[100]; int b[4][6]; char c[5][4][9]; A k-dimensional array has a size for each dimensions. Let si be the size of the ith dimension. If array elements are of type T and v=sizeof(T), the array declaration will allocate space for s1*s2*...*sk elements which is s1*s2*...*sk*v bytes.

59 2-dimensional Arrays It is convenient to think of a 2-d array as a rectangular collection of elements . int a[3][5] col0 col1 col2 col3 col4 row0 a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] row1 a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] row2 a[2][0] a[2][1] a[2][2] a[2][3] a[2][4] row3 a[3][0] a[3][1] a[3][2] a[3][3] a[3][4]

60 Pointers and multi-d arrays
There are numerous ways to access elements of a 2-d array. a[i][j] is equivalent to: *(a[i]+j) (*(a+i)[j]) *((*(a+i))+j) *(&a[0][0] + 5*i + j)

61 Pointers and multi-d arrays
We can think of a[i] as the ith row of a. We can think of a[i][j] as the element in the ith row, jth column. The array name, a (&a[0]) is a pointer to an array of 5 integers. The base address of the array is &a[0][0]. Starting at the base address the compiler allocates contiguous space for 15 ints.

62 The storage mapping function
(The mapping between pointer values and array indices.) int a[M][N]; The storage mapping function : a[i][j] is equivalent to *(&a[0][0] + N*i + j)

63 Formal parameter declarations
When a multi-dimensional array is a formal parameter in a function definition, all sizes except the first must be specified so that the compiler can determine the correct storage mapping function. In the header of the function definition, the following 3 parameter declarations are equivalent: int a[][5] int a[3][5] int (*a)[5] int sum ( int a[][5] ) { int i, j, sum=0; for (i=0; i<3; i++) for (j=0; j<5; j++) sum += a[i][j]; return sum; }

64 3-dimensional arrays int a[X][Y][Z];
The compiler will allocate X*Y*Z contiguous ints. The base address of the array is &a[0][0][0] Storage mapping function : a[i][j][k]  *(&a[0][0][0] + Y*Z*i +Z*j + k) In the header of the function definition, the following 3 parameter declarations are equivalent: int a[][Y][Z], int a[X][Y][Z], int (*a)[Y][Z]

65 Initialization : multi-d arrays
int a[2][3] = {1,2,3,4,5,6}; int a[2][3] = {{1,2,3}, {4,5,6}}; int a[][3] = {{1,2,3}, {4,5,6}};

66 The use of typedef #define N 4 typedef double scalar;
typedef scalar vector[N]; typedef scalar matrix[N][N]; or typedef vector matrix[N];

67 void add (vector x, vector y, vector z) {
int i; for (i=0; i<N; i++) x[i] = y[i]+z[i]; } scalar dot_product (vector x, vector y) { scalar sum = 0.0; sum += x[i]*y[i]; return sum;

68 void multiply (matrix x, matrix y, matrix z) {
int i, j, k; for (i=0; i<N; i++) { for (j=0; j<N; j++) { x[i][j] = 0.0; for (k=0; k<N; k++) { x[i][j] += y[i][k]*z[k][j]; }


Download ppt "Arrays and Pointers."

Similar presentations


Ads by Google