21
ABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array is a variable with in an index or subscript. int a[size] a[0], a[1], … , a[size-1] The index always starts from zero. It is recommended to define the size of an array as a symbolic constant #define N 100 int a[N] ; /* a[0], a[1], …. a[99] */ Initialization Arrays may be automatic, external, or static but not register. Explicit initialization (1)float f[5] = {0.0, 1.0, 2.0, 3.0, 4.0} ; f[0]=0.0, f[1]=1.0, … (2)int a[100] = {0} ; All the elements are initialized to zero. (3)int a[] = {2, 3, 5, -7} ; int a[4] = {2, 3, 5, -7} ; (4)char s[] = “abc” ; char s[] = {‘a’, ‘b’, ‘c’, ‘\0’} External and static arrays are initialized to zero by the system. Automatic arrays usually start with ‘garbage’ values. Subscripting int i, a[N] ; Any element of the array can be accessed by a[i]. Index, or subscript 6.2 Pointers A variable is stored in a certain number of bytes at a particular memory location. Pointers are used to access memory and manipulate addresses. (Pointers take addresses as values) /* Declare p to be of type pointer to int */ int *p ; Assignement to the pointer p p = 0 ; P = NULL ; /* same as p = 0 */ P = (int *) 1776 /* an absolute address in memory */ P = &i ; address of i , referring to i , pointing to i If p is a pointer, *p is the value at the address that p is pointing to. p contains address. *p is the value at the address. indirect value of p direct value of p

Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-1

Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array is a variable with in an index or subscript. int a[size] → a[0], a[1], … , a[size-1] ↑ The index always starts from zero. It is recommended to define the size of an array as a symbolic constant #define N 100 int a[N] ; /* a[0], a[1], …. a[99] */ Initialization

Arrays may be automatic, external, or static but not register. Explicit initialization (1)float f[5] = {0.0, 1.0, 2.0, 3.0, 4.0} ; → f[0]=0.0, f[1]=1.0, … (2)int a[100] = {0} ; → All the elements are initialized to zero. (3)int a[] = {2, 3, 5, -7} ; ↔ int a[4] = {2, 3, 5, -7} ; (4)char s[] = “abc” ; ↔ char s[] = {‘a’, ‘b’, ‘c’, ‘\0’} External and static arrays are initialized to zero by the system. Automatic arrays usually start with ‘garbage’ values.

Subscripting

int i, a[N] ; → Any element of the array can be accessed by a[i]. ↑ Index, or subscript 6.2 Pointers A variable is stored in a certain number of bytes at a particular memory location. Pointers are used to access memory and manipulate addresses. (Pointers take addresses as values) /* Declare p to be of type pointer to int */ int *p ; Assignement to the pointer p p = 0 ; P = NULL ; /* same as p = 0 */ P = (int *) 1776 /* an absolute address in memory */ P = &i ; ↑ address of i, referring to i, pointing to i If p is a pointer, *p is the value at the address that p is pointing to. → p contains address. *p is the value at the address. ↑ ↑ indirect value of p direct value of p

Page 2: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-2

Example int a = 1, b = 2, *p ;

P = &a ;

b = *p ; ←⎯⎯⎯⎯→equivalent b = a ; Example /* Printing an address */ ⎡ #include <stdio.h> int main(void) { int i = 7, *p = &i ; ↑ It is of type int * printf(“%s%d\n%s%p\n”, “Value of i: “, *p, “Location of i: “, p) ; return 0 ; ↑ ⎣ } Format to print a pointer in hexadecimal The output screen ⎡ Value of i: 7 ⎣ Location of i: effffb24 Example

↑ j becomes 15

Page 3: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-3

Conversions between differenet pointer types → One of the types should be either 0 or of type void * during assignment Example

p = v = q ; produces an error in MS C++. It should be either v = q ; or p = (int *)v ; Example The followings are illegal &3 : pointing at a constant &(k+99) : pointing at an expression register v; &v : pointing at a register variable But these are legal &a[0], &a[i+j+3] 6.3 Call-by-Reference Call-by-value : No change of the variables in the calling environment by calling a function. Call-by-reference : The variables in the calling environment can be changed by a function. Example ⎡ #include <stdio.h> void swap(int *, int *) ; int main(void) { int i = 3, j = 5 ; swap(&i, &j) ; printf(“%d %d\n”, i, j ) ; /* 5 3 is printed */ return 0 ; } void swap(int *p, int *q) { int tmp ; tmp = *p ; *p = *q ; *q = tmp ; ⎣ }

Page 4: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-4

6.4 The Relationship Between Arrays and Pointers An array name is an address, or a pointer. ↑ fixed address Pointers can be subscripted as arrays. ↑ different addresses Example a is an array a[i] ←⎯⎯⎯⎯→equivalent *(a+i) p is a pointer *(p+i) ←⎯⎯⎯⎯→equivalent p[i] Example ⎡ #define N 100 int a[N], i, *p, sum = 0 ; // Assume the system assigns 300 as the base address of the array a // → 300, 304, 308,…696 are addresses of a[0], a[1], a[2],…a[99]

// when 4 bytes are used for int p = a ; ←⎯⎯⎯⎯→equivalent p = &a[0] ; ⎣ p = a + 1 ; ←⎯⎯⎯⎯→equivalent p = &a[1] ;

Different ways of summing the array For(p = a; p < &a[N]; ++p) Sum += *p ; For(i = 0; i < N; ++i) Sum += *(a+i) ; P = a ; For(i = 0; i < N; ++i) Sum += p[i] ;

In this example, a is a constant pointer. Therefore followings are illegal. a = p, ++a, a += 2, &a 6.5 Pointer Arithmetic and Element Size p is a pointer → p + 1 means address of the next storage → These are all possible: p + i, ++p, p += i, ⎡ double a[2], *p, *q; p = a ; /* points to the array */ q = p + 1 ; /* q = &a[1] */ printf(“%d\n”, q - p) ; /* 1 is printed */ ⎣ printf(“%d\n”, (int)q – (int)p) ; /* 8 is printed */ A double is stored in 8 bytes. p points to a double, q points to the next double. → Difference in array elements is 1, but difference in memory location is 8.

Page 5: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-5

6.6 Arrays as Function Arguments An array is a pointer → When an array is passed to a function, the base address of the array is passed by “call-by-value” (Array elements are not copied to the function) Example ⎡ double sum(double a[], int n) // Equivalent to double sum(double *a, int n) { int i ; double sum = 0.0 ; for ( i = 0; i < n; ++i) sum += a[i] ; return sum ; } void main (void) { double v[100] ; . . . sum(v, 100) ; → v[0] + v[1] + … + v[99] sum(v, 88) ; → v[0] + v[1] + … + v[87] sum(&v[7], k - 7) ; → v[7] + v[8] + … + v[k - 1] sum(v + 7, 2*k) ; → v[7] + v[8] + … + v[2*k + 6] . . . ⎣ } 6.7 An Example: Bubble Sort Move small values to the front ⎡ void swap( int *, int *) ; void bubble( int a[], int n) /* n is the size of a[] */ { int i, j ; for( i = 0; i < n – 1; ++i ) for( j = n - 1; j > i; --j ) if ( a[j-1] > a[j] ) swap( &a[j-1], &a[j] ) ; } void main(void) { int a[]={7, 3, 66, 3, -5, 22, 77, 2} . . . bubble(a, 8) ; . . . ⎣ }

Page 6: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-6

6.8 Dynamic Memory Allocaton with calloc( ) and malloc( ) ↑ ↑ memory allocation contiguous allocation Their function prototypes are in stdlib.h They are used to create memory space for arrays, structures, and unions. calloc(n, el_size)

↑ ↑ Size of an element in bytes n elements → The memory is initialized to zero. It returns a pointer of type void * pointing the base of the array. (Otherwise it returns NULL) malloc(size_t)

↑ Memory space of size size_t. → It returns a pointer of type void * pointing the base of the array The space is not initialized(it takes less time). calloc(n, el_size) ←⎯⎯⎯⎯→equivalent malloc(n * el_size) The memory space should be released to the system manually upon exiting a function. free(ptr) ; /* ptr is the pointer pointing the base address of the memory */ Example ⎡ #include <stdio.h> #include <stdlib.h> int main(void) { int *a ; int n ; . . . a = calloc(n, sizeof(int) ) ; /* a becomes an array with size of n */ . . . ⎣ } Offsetting the Pointer We want to index an array from 1 instead of 0. Method 1 int n ; double *a ; . . . a = calloc( n + 1, sizeof(double) ) ; Then use a[1]…a[n] Method 2 a = calloc( n, sizeof(double) ) ; --a ; /* offset the pointer */ . . . free( a + 1 ) ; /* To deallocate the space */

Page 7: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-7

6.9 An Example: Merge and Merge Sort Two arrays a[] and b[] are in ascending order. Merge these into c[] in ascending order. File mergesort.h #include <assert.h> #include <stdio.h> #include <stdlib.h> void merge(int a[], int b[], int c[], int m, int n) ; void mergesort(int key[], int n) ; void wrt(int key[], int sz) ; File of merge.c #include “mergesort.h” void merge(int a[], int b[], int c[], int m, int n) { int i = 0, j = 0, k = 0 ; /* size of a[] is m, size of b[] is n */ while ( i < m && j < n ) if ( a[i] < b[j] ) c[k++] = a[i++] ; else c[k++] = b[j++] ; while ( i < m ) c[k++] = a[i++] ; while ( j < n ) c[k++] = b[j++] ; } File of mergesort.c #include “mergesort.h” void mergesort(int key[], int n) { int j, k, m, *w ; for (m = 1; m < n; m *= 2) ; /* after the loop m is a power of 2 that is greater than or equal to n */

if ( n < m ) /* if n is not a power of 2, exit the program */ { printf(“Error: Array size is not a power of 2”) ; exit(1) ; } w = calloc( n, sizeof(int) ) ; /* allocate memory space for n intergers. /* it returns a pointer of type void * to the space, otherwise NULL */ assert( w != NULL ) ; /* if calloc is failed, the program stops here */ for ( k=1; k<n; k*=2 ) { for ( j=0; j<n–k; j+=2*k ) merge( key+j, key+j+k, w+j, k, k ) ; for ( j=0; j<n; ++j ) key[j] = w[j] ; } free (w) ; }

Page 8: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-8

When k=1, the first call to merge() → merge( key+0, key+0+1, w+0, 1, 1 ) ; key[0] and key[1] are sorted and merged into w[0] and w[1] The second call to merge() → merge( key+2, key+2+1, w+2, 1, 1 ) ; key[2] and key[3] are sorted and merged into w[2] and w[3] … When k=2, the first call to merge() → merge( key+0, key+0+2, w+0, 2, 2 ) ; The first array : key[0], key[1] The second array : key[2], key[3] The second call to merge() → merge( key+4, key+4+2, w+4, 2, 2 ) ; The first array : key[4], key[5] The second array : key[6], key[7] …

Merge sort is faster than the bubble sort.

Page 9: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-9

6.10 Strings A string is an 1-D array of characters. A string is terminated by null character or ‘\0’ ↑ a byte with all bits zero (= zero decimal value) A string is written between double quotes Example: “abc” “a” = ’a’ + ’\0’ ↑ ↑ character string A string is treated as a pointer char *p = ”abc” ; printf( “%s %s\n”, p, p+1 ) ; /* abc bc is printed */ Differences between pointers and arrays

Both are possible (1)char *p = ”abcde” ;

Computer stores ”abcde” in the memory. Computer allocates memory for p and store the base address of the string. ↑ A pointer is stored in a word(2 or 4 bytes) (2)char s[]=”abcde” ; ←⎯⎯⎯⎯→equivalent char s[]={‘a’, ’b’, ’c’, ’d’, ’e’, ’\0’} ; ↑ 6 bytes are used 6.11 String-Handling Functions in the Standard Library The function prototypes are in the header file string.h

const char * → The character pointed to should not be changed. int strcmp(const char *s1, const char *s2) ;

It returns an integer less than zero when s1 < s2. “ greater than zero when s1>s2. “ zero when s1 = s2.

size_t strlen(const char *s) ; ↑ of type unsigned int The number of characters before \0 is returned.

char *strcpy(char *s1, const char *s2) ;

The characters in s2 are copied to s1. ⎡ char *strcpy(char *s1, register const char *s2) { register char *p = s1 ; // Pointer p( not *p) is initialized to pointer s1 // p and s1 point to the same memory while (*p++ = *s2++) // *p++ = *(p++) ≠ (*p)++ ; ↑ ↑ ↑ Increment what p points to, return s1 ; ↑ ↑ but no change in p itself ⎣ } ↑ p itself is incremented The value pointed to by s2 is assigned to the value pointed to by p, then p and s2 are incremented. When the null character is copied, while loop ends.

Page 10: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-10

↑ value 0 char *strcat(char *s1, const char *s2) ;

Take two strings s1 and s2, concatenate them, and put the result in s1. The function returns s1.

⎡ char *strcat(char *s1, register const char *s2) { register char *p = s1 ; // p (not *p) is initialized to s1 while (*p) // Equivalent to while( *p != ‘\0’) ++p ; // p points the end of s1 while (*p++ = *s2++) // Null char. of p is overwritten by the first char. of s2 ; return s1 ; ⎣ } Example

Page 11: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-11

6.12 Multidimensional Arrrays int a[100] ; // one dimensional array int b[2][7] ; // two dimensional array int c[5][3][2] ; // three dimensional array Two-dimensional Arrays int a[3][5] ; // Elements are stored contiguously in memory space // For convinience, imagine 3-row 5-column array

Different way to access a[i][j] *( a[i] + j ) // a[i]= i –th row of a ( *(a + i) )[j] // a = &a[0] *( ( *(a + i) ) + j ) *( &a[0][0] + 5*i + j ) // &a[0][0] is the base address of the array The Storage Mapping Function It is the mapping between pointer values and array indices a[i][j] ←⎯⎯⎯⎯→equivalent *( &a[0][0] + 5*i + j ) The compiler uses a storage mapping function to access a[i][j]. Formal Parameter Declarations When a multidimensional array is used as a function parameter, all sizes except the first must be specified. (Multidimensional arrays are often inappropriate in mathematical programming) int a[3][5] ; . . . int sum( int a[][5] ) // int a[3][5], 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 ; } These are equivalent in function arguments

int b[] ←⎯⎯⎯⎯→equivalent int b[3] ←⎯⎯⎯⎯→equivalent int *b char *argv[] ←⎯⎯⎯⎯→equivalent char *argv[3] ←⎯⎯⎯⎯→equivalent char **argv

Page 12: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-12

Three Dimensional Arrays int a[7][9][2] ; The base address is &a[0][0][0] Storage mapping a[i][j][k] ←⎯⎯⎯⎯→equivalent (&a[0][0][0] + 9*2*i + 2*j + k) int sum( int a[][9][2] ) // All except the first must be specified { // int a[7][9][2] or int (*a)[9][2] int i, j, k, sum = 0 ; for (i = 0; i < 7; ++i) for (j = 0; j < 9; ++j) for (k = 0; k < 2; ++k) sum+=a[i][j][k] ; return sum ; } Initialization In general, an array of storage class automatic contains garbage values. Static and external arrays are initialized to zero by default. Different methods of initialization int a[2][3] = {1, 2, 3, 4, 5, 6} ; // a[0][0]=1, a[0][1]=2, . . . int a[2][3] = {{1, 2, 3}, {4, 5, 6}} ; int a[][3] = {{1, 2, 3}, {4, 5, 6}} ; int a[2][2][3] = { {{1, 1, 0}, {2, 0, 0}}, {{3, 0, 0}, {4, 4, 0}} } ; ←⎯⎯⎯⎯→equivalent int a[][2][3] = { {{1, 1}, {2} }, {{3}, {4, 4} } } ; int a[2][2][3] = {0} ; // all elements are zero The Use of typedef #define N 3 typedef double scalar ; typedef scalar vector[N] ; typedef scalar matrix[N][N] ; void add(vector x, vector y, vector z) { . . . } scalar dot_product(vector x, vector y) { . . . } void multiply(matrix a, matrix b, matrix c) { . . . }

Page 13: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-13

6.13 Array of Pointers In file sort.h ⎡ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXWORD 50 #define N 300 . . . ⎣ In file main.c ⎡ #include “sort.h” int main(void) { char word[MAXWORD] ; char *w[N] ; // Array of pointers, *(w[N]) int n, i ; for(i = 0; scanf(“%s”, word) == 1; ++i) { . . . w[i] = (char *)calloc( strlen(word) + 1, sizeof(char) ) ; ↑ ↑ needed in MS C++ required for the end-of-string . . . strcpy( w[i], word ) ; } n = i ; sort_words(w, n) ; wrt_words(w, n) ; return 0; ⎣ } The input: A is for apple or alphabet pie Which all get a slice of, come taste it and try. After execution of strcpy( w[i], word ) ;

Page 14: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-14

In file sort.c ⎡ #include “sort.h” void sort_words(char *w[], int n) {

. . . if( strcmp(w[i], w[j]) > 0 ) swap(&w[i], &w[j]) ; // Two pointer values are interchanged ⎣ } ↑ an address of a pointer to char, a pointer to pointer to char In file swap.c ⎡ #include “sort.h” void swap(char **p, char **q) { ↑ a pointer to pointer to char char *tmp ; tmp = *p ; *p = *q ; *q = tmp ; ⎣ }

Page 15: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-15

6.14 Arguments to main() Two arguments, argc and argv, are used to communicate with the computer ↑ ↑ an array of pointers to char, number of command line arguments File my_echo ⎡ #include <stdio.h> int main(int argc, char *argv[]) { int i ; printf(“argc=%d\n”, argc) ; for(i = 0; i < argc; ++i) printf(“argv[%d]=%s\n”, i, argv[i]) ; return 0; ⎣ } In command line: my_echo a is for apple The following is printed: argc=5 argv[0]=my_echo argv[1]=a argv[2]=is argv[3]=for argv[4]=apple 6.15 Ragged Array It contains different sizes of rows Compare 2-D array of type char and 1-D array of pointers to char. ⎡ #include <stdio.h> int main(void) { char a[2][15]={“abc:”, “a is for apple”} ; // 2-D array of type char char *p[2]={“abc:”, “a is for apple”} ; // 1-D array of pointers to char printf(“%c%c%c %s %s\n”, a[0][0], a[0][1], a[0][2], a[0], a[1]) ; printf(“%c%c%c %s %s\n”, p[0][0], p[0][1], p[0][2], p[0], p[1]) ; ⎣ } The same output: abc abc: a is for apple abc abc: a is for apple

Page 16: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-16

Differences: (1) a is a 2-D array 15 chars for a[0], and 15 chars for a[1] a[0] has only 5 elements and is initialized to {‘a’, ‘b’, ‘c’, ‘:’, ‘\0’} → The rest are all zero. a[0][14] is still OK The compiler uses a storage mapping function to access a[i][j] → One multiplication and one addition The strings pointed to by a[0] and a[1] can be changed (2) p is an 1-D array of pointers to char

Two memory spaces for two pointers (4 byte each) P[0] is initialized to point at “abc:”(5 chars) → P[0][14] is not OK P[1] is initialized to point at “a is ..” (15 chars)

No need for a code for a storage mapping function

→ p works faster than a The strings pointed to by p[0] and p[1] are constant strings → They cannot be changed Sizes of p[0] and p[1] are different → ragged array 6.16 Functions as Arguments

A program for a computation of =∑ 2( )n

k mf k

In file sum_sqr.c ⎡ #include “sum_sqr.h” double sum_square(double f(double x), int m, int n) { ↑ f is a func. taking a double and returns a double. double f(double), double (*f)(double) . . . ↑ When a func. is used as a parameter, it is treated as a pointer by computer. for (k = m; k <= n; ++k) sum += f(k) * f(k); ←⎯⎯⎯⎯→equivalent sum += (*f)(k) * (*f)(k); return sum; ⎣ } Note the difference double (*f)(double) : f is a pointer to function that takes a double and returns a double double *f(double) : f is a function that takes a double and returns a pointer to double Note f : pointer to a function *f : function itself (*f)(k) : function call

Page 17: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-17

In file sum_sqr.h ⎡ #include <math.h> #include <stdio.h> double f(double x); double sum_square(double f(double x), int m, int n); // function prototype ←⎯⎯⎯⎯→equivalent double sum_square(double f(double x ), int m, int n); double sum_square(double f(double ), int m, int n); double sum_square(double f(double ), int, int ); double sum_square(double (*f)(double), int, int ); double sum_square(double (*)(double), int, int ); ⎣ double sum_square(double g(double y ), int a, int b); In file main.c ⎡ #inclbue “sum_sqr.h” int main(void) { printf(“%s%.7f\n%s.7f\n”, “ First computation: “, sum_square(f, 1, 10000), “Second computation: “, sum_square(sin, 2, 13)); return 0; ⎣ } In file fct.c ⎡ #include “sum_sqr.h” double f(double x) { return 1.0 / x; ⎣ }

Page 18: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-18

6.17 An Example: Using Bisection to find the root of a function

The root is between a and b → f(a) and f(b) have opposite sign Take the midpoint m

→ If f(m) = 0, then m is the root. If not, either f(a) and f(m) or f(m) and f(b) are of opposite sign ⎡ Program to find the root of − − =5 7 3 0x x In file find_root.h #include <assert.h> #include <stdio.h> typedef double dbl; extern int cnt; extern const dbl eps; dbl bisection(dbl f(dbl x), dbl a, dbl b) ; dbl f(dbl x) ; In file main.c #include “find_root.h” int cnt = 0; const dbl eps = 1e-13 ; /* epsilon, a small value */ int main(void) { dbl a = -10.0 ; dbl b = +10.0 ; dbl root ; assert( f(a)*f(b) <= 0.0 ) ; /* The root is between a and b */ root = bisection(f, a, b) ; printf(“%d\n% .15f\n% .15f\n”, cnt, root, f(root)); return 0 ; }

Page 19: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-19

In file bisection.c #include “find_root.h” dbl bisection(dbl f(dbl x), dbl a, dbl b) { dbl m = (a+b)/2.0 ; ++cnt; if (f(m) == 0.0 || b-a < eps) return m; else if (f(a)*f(m) < 0.0) return bisection(f, a, m); else return bisection(f, m, b); } In file fct.c #include “find_root.h” dbl f(dbl x) { return(x*x*x*x*x – 7.0*x – 3.0); } The output: 49 1.719628091484431 -0.000000000000977 ⎣ The Kepler Equation

Page 20: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-20

6.18 Arrays of Pointers to Function A function name is treated as a pointer to the function

An example: f(x) → f is a function name. f is a pointer to the function. → Different expressions are possible when an array of functions is used.

/* Use bisection to find roots. */ In file find_roots.h ⎡ . . . #define N 4 typedef double dbl; typedef dbl (*pfdd)(dbl); // Create the type “pointer to function // taking a dbl and returning a dbl” . . . dbl bisection(pfdd f, dbl a, dbl b); // function prototype, ⎣ . . . // pfdd f = double f(double x) In file mail.c ⎡ #include “find_roots.h” . . . int main(void) { . . . pfdd f[N]= {NULL, f1, f2, f3}; /* f is an array of N elements of type pfdd that is equivalent to dbl (*f[N])(dbl)={NULL, f1, f2, f3}; f1 is a pointer to function. dbl (*f[N])(dbl)={NULL, &f1, &f2, &f3}; f1 is a function name. pfdd f[N] ={NULL, &f1, &f2, &f3}; */ for (i = 1; i < N; ++i) { . . . root = bisection(f[i], a, b); /* function call equivalent to root = bisection(*f[i], a, b); */ . . . val= f[i](root); /* function call equivalent to val= (*f[i])(root); */ } ⎣ } In file bisection.c ⎡ . . . dbl bisection(pfdd f, dbl a, dbl b) ⎣ { . . . } In file fct.c ⎡ . . . dbl f1(dbl x) { . . . } dbl f2(dbl x) { . . . } dbl f3(dbl x) ⎣ { . . . }

Page 21: Chapter 6 Arrays, Pointers, and Strings 6.1 One ...icc.skku.ac.kr/~yeonlee/C/ABC06.pdfABC; 11/1/2004; 6-1 Chapter 6 Arrays, Pointers, and Strings 6.1 One-dimensional Arrays An array

ABC; 11/1/2004; 6-21

6.19 The Type Qualifiers const and volatile They restrict the way an identifier is used

const int k = 3 ; /* k can be initialized but cannot be modified thereafter */

int v[k] ; /* A variable specifies the array size, OK in C++, NOT OK in C */ Other examples: [1] const int a = 7 ; int *p = &a ; It may cause a compiler error since p is an ordinary pointer to int. For example, ++*p is trying to chane the value of a [2] const int a = 7 ; const int *p = &a ; /* p is a pointer to a constant int */ It is OK. Note p is not constant → We may assign an address to p. But we cannot assign a value to *p. [3] int a ; int * const p = &a ; /* p is a constant poniter to int */ p cannot be changed, but *p can be changed. [4] const int a = 7 ; const int * const p = &a ; /* p is a constant pointer to a constant int */ Neither p nor *p can be changed. A volatile object is what is modified by the hardwave

extern const volatile int real_time_clock ; ↑ ↑ ↑ It is acted on by the hardwave Look for it in this of other file It cannot be changed by the program