370 likes | 510 Views
Lecture 15. What will I learn in this lecture?. Know how to declare arrays, access elements of an array. Understand how character arrays can represent strings. Use compact C notation such as assignment operators or the increment and decrement operators . Two dimensional arrays
E N D
What will I learn in this lecture? • Know how to declare arrays, access elements of an array. • Understand how character arrays can represent strings. • Use compact C notation such as assignment operators or the increment and decrementoperators. • Two dimensional arrays • Related Chapters: ABC Chapter 6.1, 6.2, 6.12
What is an Array? A one dimensional array is a list of data values, with all values having the same data type(the base type), such as: • integer • float • double • char Technically, an array is a uniform data structure. Individual array elements are referenced using the array name and a subscript that identifies the element position in the array.
Declaring an Array For a one dimensional array, we specify the array name, its base data type, and the number of storage locations required using declarations such as int a[25]; float x[100], y[100]; which specifies 25 integer locations for a and 100 floating-point locations for arrays x and y. Storage for array elements are in contiguous locations in memory, referenced by subscript(or index) values starting at 0. Thus for array a above, the storage is RAM . . . a[0] a[1] a[24]
Declaring and initializing an Array The array size could also be specified using a symbolic constant: #define ARRAY_SIZE 25 int a[ARRAY_SIZE]; . . . We can initialize array elements in declaration statements; e.g., int counts[5] = {1, 2, 3, 4, 5}; int evens[] = {2, 4, 6, 8}; /* evens has 4 elements */ We cannot specify more initial values than there are array elements, but we can specify fewer initial values, and the remaining elements will be initialized to 0. e.g., int b[10] = {2}; double x[250] = {0};
Arrays - subscripting Given that the array x is declared as: int x[250]; To initialize a large array to a nonzero value - say 10, we can use a loop. e.g., for (k = 0; k <= 249; k = k+1) x[k] = 10; k is a subscript Note: when referencing a particular element of an array use square brackets, not parenthesis or curly braces.
Arrays - subscripting A subscript value for an array element can be specified as any integer expression. For example, given the following declarations: double y[4] = {-1.0, 12.0, 3.5, 3.2e-2}; int c = 2; the following statement would assign the value of 5.5 to y[1] y[2 * c - 3] = 5.5;
Example - Fibonacci Numbers 1. Problem Definition Write a program “fib” that prompts the user for an integer n. The program prints the first n Fibonacci numbers. 2. Refine, Generalize, Decompose the problem definition (i.e., identify sub-problems, I/O, etc.) Input = n - the count of Fibonacci Numbers to be printed Output= Fib Numbers printed to screen. 3. Develop Algorithm Use the formula: fib0= 1, fib1 =1 and for k > 1 fibk = fibk-1 + fibk-2
#include <stdio.h> /* C program to print the first n Fibonacci Numbers. */void main(void){ int k,n; int fib[100] = {1,1};/* note: n must be <= 100 , why ? */ printf("How many Fibonacci number do you want listed? "); scanf("%i",&n); for (k = 2; k < n; k++)/* the ++ is the increment operator */ fib[k] = fib[k-1] + fib[k-2]; /* print the results, four per line */ for (k = 0; k < n;++k) { if (k % 4 == 0) printf(“\n”); printf("%8i", fib[k]); /* that’s 8 ints */ } /* end of for loop */ printf("\n");} /* end of main */ (For large values of parameter n, we would need more space for each printed column. Also, the calculated values may become too large for the allocated storage space for a datatype int.)
Increment and Decrement Operators ++k; Since incrementing and decrementing (negative increments) are common programming operations, the C language provides shortcutIncrement/ Decrementoperators. : ++k Increment k by 1 and use incremented value in expression containing ++k. k++ Use the current value of k then increment by 1. --k Decrement k by 1 and use decremented value in expression containing --k. k-- Use current value of k then decrement by 1. .
Increment and Decrement Operators - Examples ++k; /*C statement k = k + 1; */ int x,z;int y = 1;int a = 2;x = y + a++;/* now x = 3 , y = 1 , a = 3 */z = x + --a;/* now a = 2, z = 5, x = 3, y = 1 */ z = --x * ++y;/* now x = 2, y = 2, z = 4, a = 2 */x = a++ / --y;/* now y = 1, x = 2, a = 3, z = 4 */ Note: The increment/decrement operators can be applied only to single variables. They cannot be applied to expressions.
Example - Average and Difference List 1. Problem Definition Write a program that inputs a list of numbers into an array. The program then calculates the average value, and then prints a list of differences. The differences are computed by taking the original values in the list minus the average. 2. Refine, Generalize, Decompose the problem definition (i.e., identify sub-problems, I/O, etc.) Input = list of reals in a file “input.dat” . We will use Unix redirection to read values from this file. Output= The average and the list of differences.
Example - Average and Difference List #include <stdio.h>void main(void) { int counter,k; double datAve, sum = 0.0, datVal[500]; /* 500 element max */ /* read the file and compute the average */ counter = 0; while (EOF != scanf("%lf", &datVal[counter])) { sum += datVal[counter]; /* += is an assignment operator */ counter++; } /* compute and print the average */ datAve = sum /counter; printf("The average is:%lf \n", datAve); /* compute and print the diff list */ for(k=0;k<counter;++k) printf("%lf\n", datVal[k]-datAve); }
Assignment Operators sum += datVal[counter]; - a shortcut method for writing assignment statements of the form var1=var1opexpression; Using an "assignment operator", we can rewrite the above as var1op=expression; whereopcan be any one of the arithmetic binary operators: + - * / %
Assignment Operators - Examples sum += datVal[counter]; or sum = sum + datVal[counter]; k += 5; or k = k +5; n -= 4; or n = n -4; a *= 2.0; or a = a*2.0; x /= b; or x = x/b; remainder %= 6; or remainder = remainder % 6; newValue += (a-b)/(2*c); or newValue = newValue + (a-b)/(2*c);
Character Arrays Unlike many other languages, there is no data type for character strings in C. We will implement strings in C by using a one dimensional array of characters where the last character is the “NULL” character ‘\0’.
Declaring a Character Array Declaring a string array with character constants char aString[ ] = {'Z', 'i', 'p', '!‘, '\0'}; Declaring character arrays with a string constant char aString[5] = "Zip!"; char atomic[ ] = "hydrogen"; IMPORTANT!!! In C, you must always terminate a character array with the NULL character, ‘\0’ . Therefore, the array size of your character array should be one plus the maximum length of the string you want to store. Example: In the declarationchar atomic[ ] = "hydrogen"; “atomic” is an array of nine elements, the last being ‘\0’
Declaring a Character Array You may declare and initialize a character arrays with a string constant as in, char atomic[ ] = "hydrogen"; but you cannot assign an array in the same manner, e.g. , not legal in C! atomic = "carbon"; however you may use the strcpy function (found in the string.h library). strcpy(atomic, "carbon");
Input and Ouput of Strings Use the %s conversion specifier to read in a string of characters. Blanks in the input are considered delimiters. That is, any blank character input such as in the string “Hello World”, would indicate two strings “Hello” and “World”. For security reasons it’s good to use %9s rather than %s in the following example for scanf. char strArray [10]; printf("Input a string with at most nine characters ”); printf("with no blanks in the string: \n"); scanf("%s", strArray); /* Notice: No & is used for an array argument! */ printf("\n%s", strArray);
Outputing a String You can use the %c conversion specifier to output the string character by character. k = 0;while (strArray[k] != ‘\0’) printf("%c", strArray[k++]);
string.h Library Functions #include <string.h> Arguments str1 and str2 in the following functions can be character array names, string pointers(discussed in a future lecture), or string constants. • strlen(str) - string length, not counting the ‘\0’ char. • strcpy(str1, str2) - copy string2 to string1. • strcmp(str1, str2) - returns a negative , zero or positive int depending on whether str1 is lexicographically less than, equal or greater than str2 respectively. • strstr(str1,str2) – if str2 is NOT a substring of str1 this function returns the NULL value. See Chapter 6.11 for examples. There are many other string functions (see Appendix G p. 1036 for a complete list).
Example – Hand Calculator 1. Problem Definition Write a hand calculator program using the operators +, -, *, / for a simple calculator. The input from the calculator will be in the Reverse Polish Notation format. For example, 2 3 + is equivalent to 2+3 and 3 5 + 2 * is equivalent to (3+5)*2 Note that RPN doesn’t require parenthesis. 2. Refine, Generalize, Decompose the problem definition (i.e., identify sub-problems, I/O, etc.) Input = list of reals and operators in a file “input.dat” . We will use Unix redirection to read values from this file. Output= The result of the calculation as a real number.
Example – Hand Calculator 3. Develop Algorithm A LIFO (last in first out) Stack is like a spring loaded plate dispenser found in a cafeteria. The last (clean) plate that goes into the dispenser is the first one to be selected by a customer. We will use an array named 'stack' to implement the stack in our program. Here is how our calculator works with a Stack to compute: (3 + 5)*21) Push the 3 on the stack.stack[0] 3 top of stack 2) Next push the 5 on the top of the stack. stack[1] 5 top of stack stack[0] 3
Example – Hand Calculator 3. Develop Algorithm 3)Pop the two values off of the stack and push the result (3+5) back on the stack. stack[0] 8 top of stack 4) Next, push the 2 on the stack. stack[1] 2 top of stack stack[0] 8 5) Now pop the two values and * them (8 * 2) and put the result on the stack. stack[0] 16 top of stack
#include <stdio.h> #include <string.h> /* for strcmp function */ #include <stdlib.h> /* for atof function */ void main(void) { char input[32]; double stack[64]; int top = -1; /* shouldn’t this be 0 ? */ while (EOF != scanf("%s", input)) { if ( strcmp(input,"+") == 0) { stack[top-1] += stack[top]; top--; } else if ( strcmp(input,"-") == 0) { stack[top-1] -= stack[top]; top--; } else if ( strcmp(input,"*") == 0) { stack[top-1] *= stack[top]; top--; } else if ( strcmp(input,"/") == 0) { stack[top-1] /= stack[top]; top--; } else { top++; stack[top] = atof(input); } } printf("result = %lf \n", stack[0]); }
stdlib.h Library Functions #include <stdlib.h> • atof(str) – converts alpha (string) to float (double) • qsort(array, num_elements, bytes_per_element, aux_function) See Lecture 21 slides 7-16 for an example of the use of qsort. There are many other functions in stdlib.h, (see Appendix A.13 p. 663 for a complete list).
Two-Dimensional Arrays - Two dimensional arrays are declared similarly to one dimensional arrays: char t[20][10]; (and referred to as a matrix, or as a "table") The first subscript gives the row number, and the second subscript specifies column number.
Declaration and Initialization We can also initialize a two-dimensional array in a declaration statement; E.g., int m[2][3] = {{1, 2, 3}, {4, 5, 6}}; which specifies the elements in each row of the array (the interior braces around each row of values could be omitted). The matrix for this example is
Declaration and Initialization Specification of the number of rows could be omitted. But other subscript specifications can not be omitted. So, we could also write the initialization as int m[ ][3] = {{1, 2, 3}, {4, 5, 6}};
Memory Storage for a Two Dimensional Array int a[2][3]= {1,2,3,4,5,6}; specifies 6 integer locations. Storage for array elements are in contiguous locations in memory in row major order (unlike column major order in Fortran), referenced by subscripts(or index) values starting at 0 for both rows and columns. RAM 1 2 3 4 5 6 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]
Example - Maximum Value 1. Problem Definition Assume we have a file “in.dat” (located in the pwd) consisting of 10 rows of 10 integers per row (100 integers total). Write a C program which reads from the file and stores the numbers in a two dimensional array named ‘mat’, computes the largest of all of these numbers and prints the largest value to the screen. 2. Refine, Generalize, Decompose the problem definition (i.e., identify sub-problems, I/O, etc.) Input = from file “in.dat” Output= Largest of the 100 integers printed to screen. 3. Develop Algorithm Use Unix redirection to read file “in.dat”. Use nested for loop to go through two dimensional array to find the largest value.
#include <stdio.h> void main(void){ int row, col, maximum; /* Declare a 2-D array called ‘mat’ which can hold a 10-by-10 */ /* matrix of integers */ int mat[10][10]; /* Write code here to read from the file ‘in.dat’ */ for(row=0;row<10;++row) for(col=0;col<10;++col) scanf("%i",&mat[row][col]); /* Write code to find the largest value in the array ‘mat’ */ maximum = mat[0][0]; /* why ??? */ for(row=0;row<10;++row) /* How does this work??? */ for(col=0;col<10;++col) if (mat[row][col] > maximum) maximum = mat[row][col]; /* Print the largest value to the screen */ printf(" max value in the array = %i\n",maximum); }
typedef The typedef mechanism in C allows us to define our own data types. For example, typedef double matrix[10][20]; In this example we create a new data-type named matrix. We can declare a variable of data-type matrix by matrix a; and this declaration is equivalent to double a[10][20];
typedef Other examples of the use of typedef are, typedef int blah; /* don’t do this !!!!! */ typedef char string[5]; In the first example we give another name or alias to the data type int . In the second example we create a new data-type named string.
typedef To declare a variable of data-type blah , blah x; this declaration is equivalent to int x; To declare a variable of data-type string , string var ="init"; /* declare and initialize */scanf("%s",var); /* read in a string of chars */ strcpy(var , "next"); Thedeclaration string morse[26]; declares morse as an array of 26 elements. Each element has data-type string.
typedef The declaration and initialization: stringmorse[26] ={".-","-...","-.-.", "-..", ".", "..-.", "--.", "....", "..",".---", "-.-", ".-..", "--", "-.", "---",".--.", "--.-",".-.", "...", "-", "..-","...-", ".--", "-..-", "-.--", "--.. " }; declares morse as an array of 26 elements with morse[0] = ".-" morse[1] = "-..." and so on...
Higher Dimensional Arrays We can also use 3, 4, … dimensional arrays, e.g., threeDArray [i][j][k]; Standard (ANSI) C allows up to 12 dimension. But more computation is required by the system to locate elements in multi-subscripted arrays. Therefore, in problems involving intensive numerical calculations, we should use arrays with fewer dimension.