(November 10, 2009 2.1 ) Arrays An array is a collection of several elements of the same type. An array variable is declared as type array name[size] I The elements are numbered as 0, 1, 2... size-1 I The size has to be a constant (not required in the C99-standard) I All elements is of the same type I The index operator [] is used to address single elements I Arrays are allocated in contigous memory
(November 10, 2009 2.2 ) Example: /* Read 100 positive floating point numbers and print them normalized */ int main() { int i; float x[100], max=0; for ( i=0; i<=99; i++ ) { scanf( "%f", &x[i] ); if ( x[i] > max ) max = x[i]; for ( i=0; i<=99; i++ ) printf( "%f", x[i]/max ); return 0;
(November 10, 2009 2.3 ) Arrays as inparameters Example: #include <stdio.h> #include <math.h> double scalprod(double u[], double v[], int n) { double result = 0; int i; for (i= 0; i<n; i++) result += u[i]*v[i]; return result; int main() { double a[] ={3., 4.; printf("the norm is: %6.2f\n", sqrt(scalprod(a, a, 2)));
Arrays as outparameters #include <stdio.h> void sort(int v[], int n) { int i; for (i=0; i<n-1; i++) { int min = i; int j; int temp = v[i]; for (j=i+1; j<n; j++) { if ( v[j]<v[min] ) min = j; v[i] = v[min]; v[min] = temp; // simple selections sort int main() { int i, a[] = {3, 1, 2, 5, 8, 4; sort(a,6); for(i=0; i<6; i++) printf("%3d", a[i]); printf("\n"); (November 10, 2009 2.4 )
(November 10, 2009 2.5 ) Character strings I No String-type! They are stored in arrays of char I At the end a NULL-character is stored (convention) I Can be initialized at declaration time I Can not be moved with an assignment or be compared with relational operators I string.h contains string functions I Format code %s to printf and scanf
(November 10, 2009 2.6 ) Example of string functions int strlen( char s[] ) { int n=0; while ( s[n]!= '\0' ) n++; return n;
(November 10, 2009 2.7 ) Alternative code int strlen( char s[] ) { int n=0; while ( s[n++] ) ; return n-1; Good or bad?
(November 10, 2009 2.8 ) The library string.h A library with functions for string handling. Some of these are: int void void void void int strlen (char s[]); strcpy (char s1[], char s2[]); strncpy(char s1[], char s2[], int n); strcat (char s1[], char s2[]); strncat(char s1[], char s2[], int n); strcmp (char s1[], char s2[]); (Somewhat simplied regarding parameter types and return values...)
(November 10, 2009 2.9 ) Exercises 1. Write a function double enorm(double x[], int n) that computes and returns the euclidic vector norm of the vector x with n elements. The vector norm of a vector x 1 ; x 2 ; : : : x n is dened as vu u t X n i=1 x i 2 2. Write the functions int isvowel(char c) and int isconsonant(char c) that returns 1 if the parameter c is a vowel respective a consonant, 0 otherwise. Also write a main function that reads character from standard input and that counts vowels and consonants. 3. Write a program that reads standard input, nds and prints the longest word. 4. Write a function int match(char m[], char s[]) that returns the index of the rst occurance of the string m in the string s. If the string is not found -1 should be returned.
(November 10, 2009 2.10 ) 5. Write a function int nmatch(char m[], char s[]) that counts and returns the number of occurances of the string m in the string s. 6. Write a program that reads standard input and count the occurrences of each (english) letter. Hint: Use an array of integers with 26 elements. Use place 0 to counts the a, place 1 for b etc. 7. Write a program that counts the frequence of pair of letters. 8. An array contains integer numbers sorted in ascending order. The array has a certain declared size, but it is not required to use all of it. Therefore you have do keep track of the actual use also. Write a function that adds a new number to the array so that the sorting is maintained. What parameters should be used? How should we keep track of both size and actual usage. Also write a function that searches the array for a given key.
(November 10, 2009 2.11 ) Pointers I A variable has an address in memory I A variables address is given by the unary address operator & I Addresses is treated as any value and can be stored in variables (pointer variables) I The unary dereferencing operator * is used at at declaration of pointer variables and to access the item that is referred to by the pointer. I You can do arithmetic on a pointer I The pointer constant NULL (always 0)
(November 10, 2009 2.12 ) Pointers as parameters void swap( int *x, int *y ) { int temp = *x; *x = *y; *y = temp; Called as: int a, b;... swap( &a, &b);
(November 10, 2009 2.13 ) Example: int x = 1, y = 2; int a[] = {4, 3, 2, 1; int *ip, *jp; ip = &x; // ip points to x y = *ip; // as y = x *ip = 3; // as x = 3 jp = ip; // jp also points to x *jp = *jp + 5; // as x = x + 5 (*ip)++; // as x++ jp = NULL; // null reference. Same as jp = 0 *jp = 2; // illegal! ip = &a[0]; // points to the first element in a jp = ip + 1; // points to the second elementet in a *jp = 0; // as a[1] = 0 *(ip+3) = *(ip+1) + 2; // as a[3] = a[1] + 2 ip = a; // as ip = &a[0]
Arrays as parameters - again int strlen( char *s ) { int n=0; while ( *s!= '\0' ) { s++; n++; return n; Alternative: int strlen( char *s ) { char *p = s; while ( *p!= '\0' ) p++; return p - s; OBS 1: Called in the same way as before! OBS 2: NO information of the array size! (November 10, 2009 2.14 )
(November 10, 2009 2.15 ) Four versions of a string copy void strcpy( char *s, char *t ) { int i = 0; while ((s[i] = t[i])!= '\0') i++; 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 ) { while (*s++ = *t++) ;
(November 10, 2009 2.16 ) Arrays with pointers int main( int argc, char *argv[] ) { int i; for ( i = 0; i < argc; i++ ) printf( "%s%s", argv[i], (i < argc-1)? "_" : "" ); printf( "\n" ); return 0; (Note the conditional expression u 1? u 2 : u 3 ) If the program is saved in a le with the name eka a test execution can look like $ eka My God, it is full of stars! eka_my_god,_it_is_full_of_stars! $
(November 10, 2009 2.17 ) Pointers as the value of a function char *findblank(char *s) { /* Searches for the first space character in a string Pre: s - pointer to the first character in a NULL-terminated string Returns: The address of the first space character, or NULL if there is no spaces. */ while ( *s!= ' ' && *s!= '\0' ) s++; if ( *s == '\0' ) return NULL; else return s; Which value will p have after executing this code? char a[] = {'a', 'b', 'c'; char *p = findblank(a);
(November 10, 2009 2.18 ) Multidimensional arrays A matrix, i. e. a two dimensional array is used as double m[10][10]; int i, j; for(i = 0; i < 10; i++) for(j = 0; j < 10; j++) m[i][j] = 0; m[2][4] = 12; The rst number in the declaration is the number of rows, the second is the number of columns, they are numbered from zero and up.
(November 10, 2009 2.19 ) Multidimensional arrays, cont. Alternative, create a memory area of correct size, address yourself using index arithmetics. double *m; int i, j; m = (double *) malloc(100*sizeof(double)); for(i = 0; i < 10; i++) for(j = 0; j < 10; j++) *(m + 10*i + j) = 0; // find the proper element *(m + 10*2 + 4) = 12; Note that you cannot use m[2][4] here, because there is no information about the linelength, therefore C cannot orientate itself in the array.
Multidimensional arrays as parameters When using a multidimensional array as a parameter, all dimensions except the rst have to be specied (as a constant). This information is needed for navigation purposes. If you don't know the linelength, how do you nd the next line? void clear(double m[][10], int l) { // l is number of lines int i,j; for (i = 0; i < l; i++) for (j = 0; j < 10; j++) m[i][j] = 0; m[2][4] = 12; int main() { double m[10][10]; // matrix created here int i,j; clear(m, 10); for (i = 0; i < 10; i++){ for (j = 0; j < 10; j++) printf("%5.2f ", m[i][j]); printf("\n"); return 0; (November 10, 2009 2.20 )
(November 10, 2009 2.21 ) Multidimensional arrays as parameters, cont. Can also be formulated like this. Here m is a pointer to an array of 10 doubles, i. e a pointer to the rst line. void clear(double (*m)[10], int l) { int i,j; for (i = 0; i < l; i++) for (j = 0; j < 10; j++) *(m[i] + j) = 0; *(m[2] + 4) = 12; int main() { double m[10][10]; // matrix created here int i,j; clear(m, 10); for (i = 0; i < 10; i++){ for (j = 0; j < 10; j++) printf("%5.2f ", m[i][j]); printf("\n"); return 0;
Multidimensional arrays as parameters, cont. We can also see a matrix as an array of pointers, each pointer will refer to a line. This gives us void clear(double *m[], int k, int l) { int i,j; for (i = 0; i < l; i++) { m[i] = malloc(k*sizeof(double)); // create a line for (j = 0; j < k; j++) *(m[i] + j) = 0; // initialize it *(m[2] + 4) = 12; // set m[2][4] int main() { double *m[10]; // an array with 10 pointers is created int i,j; clear(m, 10, 10); for (i = 0; i < 10; i++){ for (j = 0; j < 10; j++) printf("%5.2f ", m[i][j]); printf("\n"); return 0; (November 10, 2009 2.22 )
Multidimensional arrays as parameters, cont. A pointer to a pointer can of course be dereferred using. #include <stdio.h> #include <stdlib.h> void clear(double **m, int k, int l) { int i,j; for (i = 0; i < l; i++) { *(m+i) = malloc(k*sizeof(double)); // create one line for (j = 0; j < k; j++) *(*(m+i) + j) = 0; // initialize it *(*(m+2) + 4) = 12; // set m[2][4] int main() { double **m; // just a pointer, no space is created int i,j; m = (double **) malloc(10*sizeof(double *)); // an array with 10 pointers clear(m, 10, 10); for (i = 0; i < 10; i++){ for (j = 0; j < 10; j++) printf("%5.2f ", m[i][j]); printf("\n"); (November 10, 2009 2.23 )
(November 10, 2009 2.24 ) Warnings Incorrect usage of pointers is a common cause of errors that is extremely hard to nd.! Some common errors: I Trying to dereference the NULL-pointer I Use of undened pointers I Use of pointers to memoryareas that are no longer allocated I Several pointers that uninentionally references the same object
(November 10, 2009 2.25 ) Denition of own types: typedef Example typedef float Real; typedef unsigned char Digit; typedef char String[100]; typedef int * IntPointer; Real x; String name, adress; IntPointer ip, jp; I typedef denes a new datatype I The syntax follows the syntax of declarations I Makes it easy to introduce new types I Use typedef!
(November 10, 2009 2.26 ) Compound data types: struct Example struct Point { double x, y; ; // Note the semicolon! typedef struct Point Point; typedef struct Triangle {// Can be done directly Point a, b, c; Triangle; Point p1 = {0, 0; Point p2; Triangle t; p2.x = 1.; p2.y = 0.; t.a = p1; t.b = p2; t.c.x = p1.x + 2; t.c.y = t.a.x + 1;
(November 10, 2009 2.27 ) Dynamic memory handling: malloc and free Example #include <stdlib.h> #include <stdio.h> int i, n, *buffer; printf( "How many number do you need to treat?"); scanf( "%d", &n ); buffer = (int *) malloc( sizeof(int)*n ); for ( i = 0; i < n; i++ ) { buffer[i] = i*i;... free(buffer);
(November 10, 2009 2.28 ) Observe I The operator sizeof that returns the size in bytes of any type I malloc returns NULL if the allocation failed I The type cast (int *) malloc returns the type void * I Memory is returned with free no automatic GBC I The array notation I All possibilities to produce errors...
(November 10, 2009 2.29 ) Exercises 1. Write a function that solves the equation The solution is given by ax 2 + bx + c = 0 x 1;2 = b p b 2 4ac 2a The coecients a, b and c should be sent to the function as parameters. Write three dierent version to return the solutions in diernet ways a) using two parameters b) as a struct (value of the function) c) as a pointer to a struct Also, write a main function that tests your function with a series of dierent coecients.
(November 10, 2009 2.30 ) 2. The following struct is used to store a varying number of integer numbers struct container { int *buffer; /* Pointer to storage area */ int size; /* Allocated size */ int number; /* Actual usage */ ; typedef struct container container; Write a function int store(int data, container *c) that stores data in the rst free position and that returns the index of that position. If the container is full (ie if size==number) a new container should be created, twice the size of the old one. All data should then be moved to the new one, and the new onw replaces the old one. Also write a function that returns the number that is stored in a given position. What parameters should such a function take? 3. Same as above, but using text strings instead of integer numbers.
(November 10, 2009 2.31 ) Linked structures: a list of integers #include <stdio.h> #include <stdlib.h> struct listelem { int item; struct listelem *next; ; typedef struct listelem listelem; typedef struct listelem *link;
(November 10, 2009 2.32 ) link cons( int it, link nx ) { /* Create a list node Pre: it - an int nx - pointer to a list node or NULL Return: A pointer to the new node or NULL if the allocation failed */ link l = (link) malloc( sizeof(listelem) ); if (l==null) { return NULL; else { l->item = it; l->next = nx; return l; Obs: The operator ->. The expression x->y is equivalent to (*x).y
(November 10, 2009 2.33 ) int head( link l ) { /* Returns the stored value Pre: l - pointer to a list node */ return l->item; link tail( link l ) { /* Returns a pointer to the first node in the rest of the list Pre: l - pointer to a list node */ return l->next;
(November 10, 2009 2.34 ) void print( link l ) { /* Prints the list on standard output Pre: l - pointer to the first node in the list or NULL */ printf("["); while (l) { printf( "%d", l->item ); if ( l->next ) printf( ", " ); l = l->next; printf("]"); int main() { int i; link list=null; for ( i = 10; i >0; i-- ) list = cons( i, list ); print(list); printf("\n"); return 0;
(November 10, 2009 2.35 ) Exercises on linked lists Given the following declarations: struct listelem { int item; struct listelem *next; ; typedef struct listelem listelem; typedef struct listelem *link; link cons( int it, link nx ) { link l = (link) malloc( sizeof(listelem) ); l->item = it; l->next = nx; return l; void print( link l ) { putchar( '[' ); while (l) { printf( "%d", l->item); if (l->next ) putchar(','); l = l->next; putchar( ']' );
(November 10, 2009 2.36 ) Exercises on linked lists 1. Write a function that tests if a given value is found in the list. 2. Write a function that stores a value at the end of the list. 3. Write a function that removes all elements of a certain value. 4. Use this list structure to implement a stack and a queue.
(November 10, 2009 2.37 ) Exercises on binary trees 1. Declare a struct to represent a node in a binary tree and write a cons-function to initialize your struct. 2. Write a function that computes the number of nodes in the tree and the height of the tree. The functions should have a pointer to the root node as parameter 3. Write a function that test if two trees are isomorph (have the same structure) 4. Write a function that prints a tree in pre order with one node per line and indentation that shows the structure of the tree, i. e. proportional the depth of the node.