1 / 55

Arrays

Arrays. Arrays and Strings. Arrays Pointers Dynamic arrays Multidimensional arrays Strings Character Arrays String Functions. Arrays and Pointers. Array Declaration Review . To declare an array specify the type, its name, and its size in []s int arr1[10]; //or

oded
Download Presentation

Arrays

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Arrays

  2. Arrays and Strings • Arrays • Pointers • Dynamic arrays • Multidimensional arrays • Strings • Character Arrays • String Functions

  3. Arrays and Pointers

  4. Array Declaration Review • To declare an array specify the type, its name, and its size in []s • int arr1[10]; //or • int arr2[] = {1,2,3,4,5,6,7,8}; • arr2 has 8 elements • The size must be a literal or a constant • int arr3[ARR_SIZE]; • The size cannot be a variable assuming ARR_SIZE is a constant #define ARR_SIZE 10

  5. Array Indexing Review • To access the contents of an array use the array name and an index • intarr[ARR_SIZE]; • arr[0] = 1; • To iterate through an array use a loop • for(inti = 0; i < ARR_SIZE; ++i) • { • printf(“arr[i] = %d\n”, arr[i]); • } assuming ARR_SIZE is a constant arr has been declared and initialized

  6. Initializing Arrays • If an array is not initialized it will contain garbage values • The bit pattern that happens to be stored in the array elements memory locations intarr[10]; for(inti = 0; i < sizeof(arr) / sizeof(int); ++i){ printf("arr[%d] = %d\n", i, arr[i]); }

  7. Array Bounds • Be careful not to access an array using an index that is out of bounds • Less than zero or greater than array size - 1 • The sizeof function can be used to find the length of an array • But only for static arrays for(inti = 0; i < sizeof(arr) / sizeof(int); ++i){ printf("arr[%d] = %d\n", i, arr[i]); }

  8. Using an Invalid Index voidarrayBoundsTest() { int x; charstr[20]; intarr[10]; double d; strcpy(str, "Hi, my name is Bob"); arr[12] = 1148153709; printf("address of x = %d\n", &x); printf("address of str = %d\n", str); printf("address of arr[0] = %d\n", arr); printf("address of arr[12] = %d\n", &arr[12]); printf("arr[12] = %d\n", arr[12]); printf("address of str[8] = %d\n", &str[8]); printf("address of d = %d\n\n", &d); printf("str = %s\n", str); }

  9. Arrays and Functions • Arrays can be passed to functions • The parameter specifies an array • intsumArray(intarr[], int size) {... • It is common to pass the size of the array • Array arguments are passed as normal • int sum = sumArray(arr, ARR_SIZE); • Arrays can also be returned from functions • But not like this arr[] foo()

  10. Arrays are Pointers • If an array is passed to a function, changes made to it within the function will persist • Because an array variable is a constant pointer to the first element of the array • So an array parameter actually specifies the address of the array

  11. Passing Arrays to Functions intsumArray(intarr[], int size) { int sum = 0; for(inti=0; i < size; ++i){ sum += arr[i]; } return sum; } the function could also have been written like this intsumArray(int*arr, int size) { int sum = 0; for(inti=0; i < size; ++i){ sum += arr[i]; } return sum; } since an array variable is a pointer the two function headers are essentially identical

  12. More About Pointers voidprintArray(intarr[], int size) { int* p; for(p = arr; p < arr + size; p++){ printf("%d\n",*p); } } this correctly prints an array – why? dereference p to access the value it points to this seems OK, assign the address of the first element of the array to p what’s going on here?

  13. Pointer Arithmetic • The preceding example included this statement • p++; // p is a pointer to an int • This is an example of pointer arithmetic • The statement looks like it should add one to the address that p stores • Making it point to an address that doesn’t match a variable • However it does not do this, instead it adds the size of an int to the address stored in p • i.e. 4 • This is another example of operations that behave differently based on operand type

  14. Pointer Arithmetic Example Pointer arithmetic intarr[] = {1,2,3,4}; int* p = arr; symbol table next free byte call stack

  15. Pointer Arithmetic Example Pointer arithmetic intarr[] = {1,2,3,4}; int* p = arr; symbol table p++; it looks like this should add one to the value of p, making it point to the int at address 2049 next free byte call stack Fortunately this is not what happens

  16. Pointer Arithmetic Example Pointer arithmetic intarr[] = {1,2,3,4}; int* p = arr; symbol table p++; instead, the size of the type of data that p points to is added to p, making it point to the next int next free byte call stack

  17. Another Sum Function Here is another example of using pointer arithmetic to iterate through an array int sumArray2(int* start,int* end) { int sum = 0; while(start < end){ sum += *start++; } return sum; } the function would be called like this sumArray2(arr2, arr2 + ARR_SIZE) dereferences start, adds the value to sum then increments start Note that I don’t see any real value in writing the function like this, and it is fairly hard to understand unless you have a good knowledge of pointers

  18. Pointer Operations • Assignment, e.g. p = &x • Pointer type should be compatible with variable • Dereferencing , e.g. *p = 12 • The *operator accesses the variable that is pointed to • Arithmetic , e.g. ++p, p += 4, p-- • The amount added to or subtracted from the address is multiplied by the size (in bytes) of the variable pointed to • Differencing , e.g. int x = p – q • The difference in elements between the pointers • i.e. the difference in the addresses of p and q, divided by the size of the variable pointed to

  19. Valid and Invalid Operations intarr[4]; int* p; int* q;

  20. Dereferening Pointers • Be careful when dereferencing pointers • If the pointer has not been first assigned a valid address it could cause problems • Since the address stored in the pointer will contain garbage values • Attempting to dereference an unassigned pointer may cause an error • It depends on the development environment

  21. Returning Arrays • Let’s assume that we would like to write a function that returns an integer sequence • Like {1,2,3,4,5} • The return type might be int[] • The implication here is that the function is returning a constant (array) pointer • Which presumably would be assigned to another constant pointer • Which is illegal – why?

  22. Stack Problems • There is one big issue with stack memory • Because memory is allocated in sequence it is not possible to change the size of a variable (in bytes) • This isn’t a problem that applies to single base typed variables (int, double etc.) • But we might want to change the size of an array

  23. Changing an Array’s Size • int[] sequence(int start, int end){ • intarr[end – start + 1]; • inti; • for(i=0; i <= end - start; i++){ • arr[i] = start + i; • } • return arr; • } • intmain(){ • intarr[3]; • arr [0] = 1; • arr [1] = 2; • arr [2] = 3; • doublevid = 2.397; • arr = sequence(5, 8); statements in red are illegal stack memory 1 2 3 2.397 arr vid* *very important double 

  24. Changing an Array’s Size • int[] sequence(int start, int end){ • intarr[end – start + 1]; • inti; • for(i=0; i <= end - start; i++){ • arr[i] = start + i; • } • return arr; • } • intmain(){ • intarr[3]; • arr [0] = 1; • arr [1] = 2; • arr [2] = 3; • doublevid = 2.397; • arr = sequence(5, 8); statements in red are illegal main memory This is a problem, we've just corrupted the first 4 bytes of vid 1 5 6 2 7 3 8 2.397 5 8 arr vid* start end … which is why you can’t do this …

  25. Returning an Array • To return an array you return a non-constant pointer of the appropriate type • e.g. int* sequence(int start, int end) • The new array should be assigned space in dynamic memory in the function • Dynamic memory is a section of main memory that is separate from stack memory

  26. Allocating Dynamic Memory Here is a function that returns a sequence of values to a pointer the function would be called like this int* p; int size = 11; p = sequence(10, 20); int* sequence(int start,int end) { int size = end – start + 1; int* arr = malloc(size * sizeof(int)); for(inti = 0; i < size; ++i){ arr[i] = start + i; } returnarr; } Note that the elements of the array that p points to are indexed just like a static array malloc allocates space in dynamic memory for the new array We will discuss dynamic memory more in a later section

  27. Multi-Dimensional Arrays

  28. Multi Dimensional Arrays • Assume we want to store monthly rainfall in Vancouver for five years • So sixty data points, in an array of size 60 • What is the index for September of year 3? • It would be more convenient to store the data in a table • With years as columns and months as rows • This is possible using a multidimensional array

  29. Declaring Multidimensional Arrays • To declare a multidimensional array you declare an array of arrays • float rainfall[5][12]; • It is an array of 5 arrays of size 12 • Where rainfall[0] is the first array of size 12 • To access elements of the inner array, use two indices • So September of year 3 is rainfall[2][8] • Remember 0 based indexing

  30. Initializing Multidimensional Arrays • To initialize a multidimensional array use nested for loops • Or the same initialization syntax as regular arrays • Note that multidimensional arrays are not limited to two dimensions

  31. Multidimensional Array Example voidtestMatrix() { int matrix[3][5] = { {1,2,3,4,5}, {11,12,13,14,15}, {21,22,23,24,25} }; int row, column; for(row = 0; row < 3; ++row){ for(column = 0; column < 5; ++column){ printf("%4d", matrix[row][column]); } printf("\n"); } } don’t need the inner brackets

  32. Multidimensional Arrays and Pointers • A multidimensional array is an array of arrays • It can also be thought of as a pointer to an array of pointers • In the preceding example we could print the first value in matrix like this • printf("**matrix = %d\n", **matrix); • To declare a pointer to a multidimensional array, declare a pointer to an array • int (* p)[5]; • A pointer to an array of five integers

  33. Pointer to Multidimensional Array Example int matrix[3][5] = { {1,2,3,4,5}, {11,12,13,14,15}, {21,22,23,24,25} }; int (* p)[5]; p = matrix; printf("%-10s%d\n", "matrix =", matrix); printf("%-10s%d\n", "p =", p); printf("%-10s%d\n", "p+1 =", p+1); note the 20 byte difference

  34. Strings and String Functions

  35. String Review • A string is a null terminated character array • An array of characters • Where the end of the meaningful data is indicated by a null character • The length of a string can be determined by using the strlen function • charstr[20] = "bob"; • printf("%d\n", strlen(str)); • printf("%d\n", sizeof(str));

  36. Initializing Strings • A string can be initialized by assigning a string literal to a character array • A string literal is text enclosed in double quotes • If the size of the string is not specified it is set to be the number of characters (+1) • Since a string is an array of characters a string can be assigned to a char pointer

  37. String Examples inti; char name[20]; char line[] = "Now is the winter of my discontent"; char* singer = "Roger Daltrey"; char* verse[6] = {"We'll be fighting in the streets", "With our children at our feet", "And the morals that they worship will be gone", "And the men who spurred us on", "Sit in judgment of all wrong", "They decide and the shotgun sings the song"}; printf("What's your name? "); gets(name); puts(name); printf("sizeof(name) = %d, strlen(name) = %d\n\n", sizeof(name), strlen(name)); puts(line); printf("sizeof(line) = %d, strlen(line) = %d\n\n", sizeof(line), strlen(line)); puts(singer); printf("sizeof(singer) = %d, strlen(singer) = %d\n\n", sizeof(singer), strlen(singer)); for(i = 0; i < 6; i++){ puts(verse[i]); printf("sizeof(verse[%d]) = %d, strlen(verse[%d]) = %d\n\n", i, sizeof(verse[i]), i, strlen(verse[i]))

  38. String Examples char name[20]; printf("What's your name? "); gets(name); puts(name); printf("sizeof(name) = %d, strlen(name) = %d\n\n", sizeof(name), strlen(name)); get string (string input) put string (prints string) you can't enter strings with spaces using scanf

  39. String Examples char line[] = "Now is the winter of my discontent"; puts(line); printf("sizeof(line) = %d, strlen(line) = %d\n\n", sizeof(line), strlen(line)); The size of the array is exactly the size required to contain the characters and the terminating null character

  40. String Examples char* singer = "Roger Daltrey"; puts(singer); printf("sizeof(singer) = %d, strlen(singer) = %d\n\n", sizeof(singer), strlen(singer)); not the size of the array but the size of a pointer the length of the string

  41. String Examples note the indexing of the pointer to pointers (arrays) char* verse[6] = {"We'll be fighting in the streets", "With our children at our feet", "And the morals that they worship will be gone", "And the men who spurred us on", "Sit in judgment of all wrong", "They decide and the shotgun sings the song"}; for(i = 0; i < 6; i++){ puts(verse[i]); printf("sizeof(verse[%d]) = %d, strlen(verse[%d]) = %d\n\n", i, sizeof(verse[i]), i, strlen(verse[i]));

  42. Strings are Arrays • Since a string is a character array the elements can be accessed using indices char line[] = "Now is the winter of my discontent"; printf("sizeof(line) = %d, strlen(line) = %d\n\n", sizeof(line), strlen(line)); for (i = 0; i < strlen(line); ++i){ if(isVowel(line[i])){ line[i] = toupper(line[i]); } } puts(line); intisVowel(charch){ returnch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'; }

  43. Arrays and Pointers • Array variables and pointer variables are similar but have important differences • Both can be accessed using either indexing or pointers and pointer arithmetic • An array variable creates an array of characters with a fixed length • That can only be assigned a value (using =) when it is initialized • A pointer can be assigned a new string

  44. String Input • Be careful when getting input for strings • Whether they are character arrays or pointers • Input functions like scanf do not check that there is room in an array for input • So may overwrite other data if the input string is larger than the array that it is assigned to • Be very careful when using character pointers • If a character pointer has not been initialized to an array it may point anywhere

  45. Input with gets • The gets function reads a string from standard input into its argument • Standard input is usually the keyboard • The argument must be an address • Characters are read until a newline character is reached • The null character is inserted at the end • And the newline character is read and discarded

  46. Return Value of gets • The gets function returns a pointer to a character • If the read was successful it returns the address of the string that was read • If the read failed then it returns null • The null address is referred to as the null pointer • It is represented by the defined constant NULL • Defined in stdio.h

  47. Input with fgets • The gets function does not check to see if the input fits in the array • Extra characters write over adjoining bytes • The fgets function is designed for use with files and takes two additional arguments • The maximum number of characters to read • The file to be read, use stdin for the keyboard • Newline characters are read instead of being discarded

  48. Input with scanf • The scanf function reads up to the first whitespace character • In addition to this a field width can be set that specifies the maximum number of characters • It stops when it has read the number of characters or reaches whitespace, whichever comes first • It is often preferable to use gets or fgets for string input

  49. Output with puts • The puts function prints a string, and should be given the address of a string • It adds a newline when it displays a string • Note that string constants are treated as addresses • puts("Hello World"); //is OK • puts stops when it reaches the null character • So it is important that strings are terminated correctly

  50. Output with fputs • The fputs function is similar to puts but is designed for use with files • It takes a second argument indicating the file to be written to (use stdout for the display) • It does not add a newline to the output • puts and fputs are more efficient than printf

More Related