270 likes | 419 Views
Arrays of Arrays:. We can have arrays of any type, even arrays whose elements are themselves arrays. With two bracket pairs, we obtain a two-dimensional array. To obtain arrays of higher dimension, we simply continue to add brackets. int a[100]; // an one-dimensional array
E N D
Arrays of Arrays: • We can have arrays of any type, even arrays whose elements are themselves arrays. • With two bracket pairs, we obtain a two-dimensional array. To obtain arrays of higher dimension, we simply continue to add brackets. int a[100]; // an one-dimensional array int b[2][7]; // a two-dimensional array int c[5][4][3]; // a three-dimensional array Arrays and Pointers
Size of a Multi-dimensional Array: • A k-dimensional array has a size for each of its k dimensions. Let si represent the size of the array’s ith dimension, such as int a[s1][s2]…[sk]; then the declaration of the array a allocates space for s1 s2 … sk elements. Arrays and Pointers
Example: int a[3][5]; Arrays and Pointers
#define ROWS 3 #define COLS 4 int main(){ int a[ROWS][COLS], i, j, sum = 0; for (i = 0; i < ROWS; ++i) /* fill the array */ for (j = 0; j < COLS; ++j) a[i][j] = i + j; for (i = 0; i < ROWS; ++i){ /* print the array */ for (j = 0; j < COLS; ++j) printf(“a[%d][%d] = %d ”, i, j, a[i][j]); printf(“\n”); } for (i = 0; i < ROWS; ++i) /* sum the array */ for (j = 0; j < COLS; ++j) sum += a[i][j]; printf(“\nsum = %d\n”, sum); } Arrays and Pointers
Relationship between pointers and arrays: int a[3][5]; Arrays and Pointers
Storage Mapping Function: • For any array, the mapping between pointer values and array indices is called the storage mapping function. For example: int a[ROWS][COLS]; a[i][j] *(&a[0][0] + i*COLS + j) Note: the array name a by itself is equivalent to &a[0], a pointer to an array of COLS ints. The base address of the array is &a[0][0], not a. Arrays and Pointers
Multi-dimensional Arrays as Formal Parameters: • In a function definition, a multi-dimensional array argument must be specified by all sizes except the first dimension. int sum(int a[][5]) int i, j, sum = 0; for (i = 0; i < ROWS; ++i) for (j = 0; j < 5; ++j) sum += a[i][j]; return sum; } Note: the following parameter declarations are equivalent: int a[][5] int (*a)[5] int a[3][5] Arrays and Pointers
Initialization: The following three initializations are equivalent. 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}}; • If there are no inner braces, then each array elements is initialized in turn (row-wise). • If there are fewer values than elements in the array, then the remaining elements are initialized to zero. • If the first bracket pair is empty, then the compiler takes the size from the number of inner brace pairs. • All sizes except the first must be given explicitly. Arrays and Pointers
Another Example: int a[2][2][3] = { {{1, 1, 0}, {2, 0, 0}}, {{3, 0, 0}, {4, 4, 0}} }; /* or equivalently */ int a[][2][3] = { {{1, 1}, {2}}, {{3}, {4, 4}} }; Arrays and Pointers
Dynamic Allocation: • Suppose we want to build a student name list. The program must read its input from keyboard (by calling getline function) and store the input into some kind of table. What king of table? • If we use an array of pointers, how to allocate space for each entry? Arrays and Pointers
Arrays of Pointers: • 2-D arrays contain the same number of elements in each row. For example: char days[][10] = { {‘m’,’o’,’n’,’d’,’a’,’y’,’\0’}, {‘t’,’u’,’e’,’s’,’d’,’a’,’y’,’\0’}, … }; Space is wasted in the rows containing shorter strings. Can we build an array whose rows can vary in length? Arrays and Pointers
Ragged Array: • A ragged array is an array of pointers where each entry in the array is a pointer to a string (arbitrary length). For example: char *days[] = { “monday”, “tuesday”, “wednesday”, “thursday”, “friday”, “saturday”, “sunday” }; The compiler allocates an array containing 7 elements and assigns each element a pointer to the corresponding string. Arrays and Pointers
2-D Array: Array of pointers: …… Arrays and Pointers
Accessing Elements: • Elements in a ragged array can be access in either pointer-based access or array-based access. For example, char *days[] = { “monday”, “tuesday”, “wednesday”, “thursday”, “friday”, “saturday”, “sunday” }; Suppose we want to access the third char of “wednesday”, the following are equivalent: days[2][2] *(days[2] + 2) *(*(days + 2) + 2) days is the base-address of the array of pointers days[k] is the pointer to the kth string Arrays and Pointers
Self-Test: char *days[] = { “monday”, “tuesday”, “wednesday”, “thursday”, “friday”, “saturday”, “sunday” }; Arrays and Pointers
Traversing an Array of pointers: #include <stdio.h> /* array-based (index) */ void printStrs1(char *s[], int n){ int i; for (i = 0; i < n; i++) printf(“%s\n”, s[i]); } /* pointer-based */ void printStrs2(char **sp, int n){ char ** ep = sp + n; for ( ; sp < ep; sp++) printf(“%s\n”, *sp); } Arrays and Pointers
#include <stdio.h> #include <string.h> #include <stddef.h> #include <stdlib.h> #define MAXLEN 80 #define MAXNAMES 100 static char *newStr(char *str){ // a static function will be handled as an inline function char * newstr = malloc(strlen(str) + 1); if (newstr != NULL) strcpy(newstr, str); return newstr; } int main(){ int k; char *nameTable[MAXNAMES], name[MAXLEN + 1], *sp; for (k = 0; getline(name, MAXLEN) != -1 && k < MAXAMES; k++){ if ((sp = newStr(name)) != NULL) nameTable[k] =sp; else { printf(“Memory run out\n”); break; } } printStr(nameTable, k); } Arrays and Pointers
Command-line Arguments: • When we run a program, we often provide some initial values the program will work with. For Example: $myprogram filename 222 • Two arguments, argc and argv, can be used with the main() to communicate with the operating system, where argc is the number of arguments on the command-line, and argv is an array of pointers to strings containing the various arguments. • For the above example: argc == 3 argv[0] == “myprogram” argv[1] == “filename” argv[2] == “222” Arrays and Pointers
Passing Arguments to main(): #include <stdio.h> int main(int argc, char *argv[]){ int k; printf(“argc = %d\n”, argc); for (k = 0; k < argc; k++) printf(“argv[%d] = %s\n”, k, argv[k]); } $ mytest –o try this argc = 4 argv[0] = mytest argv[1] = -o argv[2] = try argv[3] = this Arrays and Pointers
Self-Test: char s1[] = “beautiful big sky country”, s2[] = “how now brown cow”; Arrays and Pointers
Self-Test: char *p[2][3] = {{“abc”, “defg”, “hi”}, {““jklmno”, “pqrstuvw”, “xyz”}}; Arrays and Pointers
A Union and Structure Example: typedef enum {AUTO, BOAT, PLANE, SHIP} VTYPE; typedef struct { /* structure for an automobile */ int tires; int fenders; int doors; } AUTOTYPE; typedef struct { /* structure for a boat or ship */ int displacement; char length; } BOATTYPE; Arrays and Pointers
typedef struct { char engines; int wingspan; } PLANETYPE; typedef struct { VTYPE vehicle; /* what type of vehicle? */ int weight; /* gross weight of vehicle */ union { /* type-dependent data */ AUTOTYPE car; /* part 1 of the union */ BOATTYPE boat; /* part 2 of the union */ PLANETYPE airplane; /* part 3 of the union */ BOATTYPE ship; /* part 4 of the union */ } vehicle_type; int value; /* value of vehicle in dollars */ char owner[32]; /* owners name */ } VEHICLE; Arrays and Pointers
void print_auto(VEHICLE * pv){ printf(“Auto weight = %d\n”, pv->weight); printf(“# of tires: %d\n, # of fenders: %d\n, # of doors: %d\n”, pv->vehicle_type.car.tires, pv->vehicle_type.car.fenders, pv->vehicle_type.car.doors); printf(“Cost = $%d\n”, pv->value); printf(“Owned by %s\n”, pv->owner); /* owners name */ } void print_plane(VEHICLE * pv){ …}; void print_boat(VEHICLE * pv){ …}; void print_ship(VEHICLE * pv){ …}; Arrays and Pointers
void print_vehicle(VEHICLE * pv){ switch (pv->vehicle){ case AUTO: print_auto(pv); break; case PLANE: print_plane(pv); break; case BOAT: print_boat(pv); break; case SHIP: print_ship(pv); break; default: printf(“Unknown vehicle type\n”); } } Arrays and Pointers
void main() { VEHICLE v[2], *piper_cub; v[0].vehicle = AUTO; v[0].weight = 2742; /* with a full gas tank */ v[0].vehicle_type.car.tires = 5; /* including the spare */ v[0]. v[0].vehicle_type.car.doors = 2; /* … other initialization of v[0] */ v[1].vehicle = BOAT; v[1].value = 3742; /* trailer not included */ v[1].vehicle_type.boat.length = 20; /* … other initialization of v[1] */ piper_cub = (vehicle*) malloc(sizeof(VEHICLE)); piper_cub->vehicle = PLANE; piper_cub->vehicle_type.airplane.wingspan = 27; /* … other initialization of piper_cub */ print_vehicle(v); print_vehicle(&v[1]); print_vehicle(piper_cub); /* piper_cub is a pointer to VEHICLE */ } Arrays and Pointers