S08: Arrays and Pointers Required: PM: Ch 6.5, pgs 73-75 Arrays Pointer Basics Pointer Tutorial (Chps 1-4) Recommended: K&R, Chapter 5 CS 224 Chapter Lab HW / Quiz L01: Data Types L02: FSM HW01/Quiz #1 HW02/Quiz #2 L03: Blinky L04: Microarch L05b: Traffic Light L06a: Morse Code HW03/Quiz #3 HW04/Quiz #4 HW05/Quiz #5 HW06/Quiz #6 L07b: Morse II L08a: Life (Bonus) L09b: Snake L10a: Threads HW07/Quiz #7 HW08/Quiz #8 HW09/Quiz #9 HW10/Quiz #10 S00: Introduction Unit 1: Digital Logic S01: Data Types S02: Digital Logic Unit 2: ISA S03: ISA S04: Microarchitecture S05: Stacks / Interrupts S06: Assembly Unit 3: C S07: C Language S08: Pointers S09: Structs S10: Threads S11: I/O BYU CS 224 Pointers and Arrays 2 Arrays Arrays An array is a sequence (in memory) of like items. Arrays are NOT data types. Arrays must be declared before they are used. General form: type variable-name[number_of_elements]; The array size must be explicit at compile time – needed to reserve memory space Array elements individually accessed with index. General form: variable-name[index]; Zero based subscripts No compile-time or run-time limit checking BYU CS 224 Pointers and Arrays 4 Arrays Initialization of Arrays Elements can be initialized when they are declared in the same way as local and global variables. type array_name[size] = { list of values separated by commas }; int number[3] = {0, 0, 0}; Unspecified elements will be set to zero automatically. Array declarations may omit the size. int counter[] = {1, 1, 1, 1}; char RGB_image[][3] = {{255,0,255}, {0,255,0}}; Arays must be statically declared. void SomeFunction(int num_elements) { int temp[num_elements]; // error } BYU CS 224 Pointers and Arrays 5 Arrays Local Array Example SP int main() { int array[10]; int x; for (x = 0; x < 10; x++) { array[x] = x; main: } 0x8040: 8031 return 0; 0x8044: 4381 0x8048: 90B1 } 0x804e: 340D 0x8050: 0x8054: 0x8056: 0x8058: 0x805e: 0x8062: 0x8068: 0x806a: 0x806c: 0x8070: BYU CS 224 SP 0016 0014 000A 0014 SUB.W CLR.W CMP.W JGE C$DW$L$main$2$B, C$L1: 411F 0014 MOV.W 5F0F RLA.W 510F ADD.W 419F 0014 0000 MOV.W 5391 0014 INC.W 90B1 000A 0014 CMP.W 3BF3 JL C$L2, C$DW$L$main$2$E: 430C CLR.W 5031 0016 ADD.W 4130 RET Pointers and Arrays x array[9] array[8] array[7] array[6] array[5] array[4] array[3] array[2] array[1] array[0] 0x0014(SP) 0x0012(SP) 0x0010(SP) 0x000e(SP) 0x000c(SP) 0x000a(SP) 0x0008(SP) 0x0006(SP) 0x0004(SP) 0x0002(SP) 0x0000(SP) #0x0016,SP 0x0014(SP) #0x000a,0x0014(SP) (C$DW$L$main$2$E) 0x0014(SP),R15 R15 SP,R15 0x0014(SP),0x0000(R15) 0x0014(SP) #0x000a,0x0014(SP) (C$L1) R12 #0x0016,SP 6 Arrays Global Array Example int array[10]; int x; int main() { for (x = 0; x < 10; x++) { array[x] = x; main: } 0x806a: 4382 return 0; 0x806e: 90B2 0x8074: 340C } 0x8076: 0x807a: 0x807c: 0x8082: 0x8086: 0x808c: 0x808e: 0x8090: BYU CS 224 0214 000A 0214 CLR.W CMP.W JGE C$DW$L$main$2$B, C$L1: 421F 0214 MOV.W 5F0F RLA.W 429F 0214 0200 MOV.W 5392 0214 INC.W 90B2 000A 0214 CMP.W 3BF4 JL C$L2, C$DW$L$main$2$E: 430C CLR.W 4130 RET Pointers and Arrays &x #0x000a,&x (C$DW$L$main$2$E) &x,R15 R15 &x,0x0200(R15) &x #0x000a,&x (C$L1) R12 7 C Strings C Strings A C string is an array of characters, terminated with a zero byte. C strings can be initialized when defined: char outputString[] = "Cow"; same as: outputString[0] outputString[1] outputString[2] outputString[3] = = = = 'C'; 'o'; 'w'; 0; Compiler computes the size of the array (3 + 1 = 4 bytes) Since arrays are not data types, C has no string operators. There is no boundary checking in C. int array[10], i; for (i = 0; i <= 10; i++) { array[i] = 0; } BYU CS 224 Pointers and Arrays 8 Array Arguments Passing Arrays as Arguments C passes parameters to functions by value. C passes the address of the 1st element of an array. #define MAX_NUMS 5 int average(int values[]) { int i, sum = 0; for (i = 0; i < MAX_NUMS; i++) sum = sum + values[i]; return (sum / MAX_NUMS); } int main() { int nums[MAX_NUMS] = { 1, 2, 3, 4, 5 }; int mean = average(nums); return 0; } BYU CS 224 0x05e8 SP SP values 0x05ea i 0x05ec sum 0x05ee 0x05f2 5 15 0x05f0 Return Adr nums[0] 0x05f2 nums[1] 0x05f4 nums[2] 0x05f6 nums[3] 0x05f8 nums[4] 0x05fa mean 0x05fc Pointers and Arrays 0x05fe 1 2 3 4 5 3 Return Adr 0x0600 9 Exercise 8.1 1. How big is the activation record for the function average? // quiz 8.1 #define NUMS 5 int average(int data[]) { int i, sum = 0; for (i = 0; i < NUMS; i++) sum = sum + data[i]; return (sum / NUMS); } 2. How much, where, and when is memory allocated for the variable data? int nums[NUMS] = {1, 2, 3, 4, 5}; int main() { printf("%d", average(nums)); return 0; } BYU CS 224 3. How much, where, and when is memory allocated for the variable sum? 4. How much, where, and when is memory allocated for nums? Pointers and Arrays 10 Pointers Pointers Swap Function Example int main() { int a = 3; int b = 4; swap(a, b); } void swap(int a, int b) { int temp = a; a = b; b = temp; } BYU CS 224 Stack after call to swap(): 0x05ea 0x05ec 0x05ee 0x05f0 0x05f8 4 3 3 Return Adr a 0x05fa 3 b 0x05fc 4 0x05fe Return Adr a b swap temp main 0x05f2 0x05f4 0x05f6 0x0600 Pointers and Arrays 12 Pointers Pointers A pointer is an address With pointers functions can indirectly access variables. functions can modify the arguments passed by the caller function. sophisticated data structures can grow and shrink at run-time. Arrays and pointers are closely related. int* ptr; char* cp; double* dp; int** p_ptr = &ptr; char *strings[10]; Array pointers enable us to conveniently process groups of data such as vectors, lists, and strings. A pointer variable contains a memory address Associated with a pointer variable is the type of value to which it points. The asterisk (*) indicates that the following identifier is a pointer variable. The ampersand (&) returns a pointer (address) to the following identifier. BYU CS 224 Pointers and Arrays 13 Pointers Pointer Operators A pointer variable is declared with the asterisk operator (*) type *var; type* var; // same - whitespace doesn’t matter Dereferencing any expression returns a value *var returns contents of the memory location pointed to by var **var returns contents of the memory location pointed to by the memory location pointed to by var *3 returns the contents of memory location 3 A pointer is created with the reference operator (&) &var Reference must be applied to a memory object &3 is illegal as it would return a pointer to a constant BYU CS 224 Pointers and Arrays 14 Pointers Operator Precedence and Associativity * =dereference & = reference OPERATORS ( ) [ ] -> . ! ~ ++ -+ * & (type) sizeof * / % + << >> < <= > >= == != & ^ | && || ?: = += -= *= /= %= &= ^= |= <<= >>= , BYU CS 224 Pointers and Arrays ASSOCIATIVITY left to right right to left left to right left to right left to right left to right left to right left to right left to right left to right left to right left to right left to right right to left left to right 15 Pointers Examples of Pointers int *ptr1; int *ptr2; Int **ptr3; int i = 4; int j; ptr1 = &i; ptr2 = &j; ptr3 = &ptr1 0x05ea 0x05ec 0x05ee 0x05f0 0x05f2 ptr1 0x05f4 ptr2 0x05f6 ptr3 0x05f8 i 0x05fa j 0x05fc 0x05fa 0x05fc 0x05f4 4 4 0x05fe Return Adr printf("%04x", ptr1); 05fa printf("%04x", ptr2); 05fc printf("%04x", *ptr1); 0004 printf("%04x", *ptr2); ???? j = *ptr1; printf("%04x", j); 0004 printf("%04x %04x", *ptr3, **ptr3); BYU CS 224 Pointers and Arrays 0x0600 05fa 0004 16 Swap Example w/Pointers Swap Example Fixed! Stack after call to swap() int main() { int a = 3; int b = 4; swap(&a, &b); } 0x05ea 0x05ec 0x05ee 0x05f0 a b swap temp void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } BYU CS 224 0x05f2 0x05f4 0x05f6 0x05f8 main Pointers and Arrays a 0x05fa b 0x05fc 0x05fe 0x05fa 0x05fc 3 Return Adr 3 4 4 3 Return Adr 0x0600 17 Null Pointers Null Pointers Sometimes we want a pointer that points to nothing. Used for invalid pointer error returns Used to catch errors NULL is a predefined macro that contains a value that non-null pointer should never hold, usually NULL=0. int *p; p = NULL; BYU CS 224 // p is a null pointer Pointers and Arrays 18 Pointer Arithmetic Pointer Arithmetic Pointer Arithmetic Address calculations depend on size of elements ints are 16-bits or 2 bytes per element. e.g., to find 4th element (x[3]), we add 3*2 to base address If double, we'd have to add 12 (3*4) to find address of 4th element. C does size calculations under the covers, depending on size of item being pointed to: double x[10]; double *y = x; *(y + 3) = 13; y++; *y = 3.1415926; Allocates 40 bytes (4 per element) Same as x[3] (base address plus 12) x[1] = 3.1415926 BYU CS 224 Pointers and Arrays 20 Pointer Arithmetic Incrementing Pointers A pointer increments according to its type. The unary operators * and & bind more tightly than arithmetic operators. 0x05ee int y = 0; int a[5] = {1, 5, 9, 13, 17}; int* ip = &a[0]; y = *ip y = y = y = *ip + 1; += 1; ++*ip; *ip++; (*ip)++; BYU CS 224 // y = a[0]+1 // a[0] = a[0]+1 // y = ++a[0] // y = a[0], ip++ // y=a[1], a[1]++ y=2, ip=0x05f2 y=2, ip=0x05f2 y=3, ip=0x05f2 y=3, ip=0x05f4 y=5, ip=0x05f4 Pointers and Arrays y 0x05f0 a[0] 0x05f2 a[1] 0x05f4 a[2] 0x05f6 a[3] 0x05f8 a[4] 0x05fa ip 0x05fc 0 2 5 3 1 2 3 5 6 9 13 17 0x05f4 0x05f2 0x05fe Return Adr 0x0600 21 Exercise 8.2 1. What is output? // quiz 8.2 void main(void) { char dog[] = {1, 2, 3, 4, 5, 6}; int cat[] = {1, 2, 3, 4, 5, 6); long pig[] = {1, 2, 3, 4, 5, 6); char* apple = dog; int* orange = cat; long* banana = pig; printf("\n%d", printf("\n%d", printf("\n%d", printf("\n%d", printf("\n%d", *(++apple + 2)); &orange[5] - cat); (int)&orange[5] - (int)cat); (pig + 2) - banana); (int)(pig + 2) - (int)&banana[0]); } BYU CS 224 Pointers and Arrays 22 Pointer Arithmetic *ip++ Form used by “experienced” C programmers // strcpy: copy s to d; version 1 void strcpy(char* d, char* s) { while ((*d = *s) != ‘\0’) { d++; s++; } } // strcpy: copy s to d; version 2 void strcpy(char* d, char* s) { while ((*d++ = *s++) != ‘\0’); } The value of *s++ is the character that s pointed to before s was incremented; the postfix ++ does not change s until after this character has been fetched. BYU CS 224 Pointers and Arrays 23 Parsing String Parsing 1. What is the value of X? char str[] = "Point X = 100"; 2. Find token: char* ptr = str; int number = 0; Walk the array until token or NULL terminator. (Token must be unique) while (*ptr && (*ptr++ != 'X')); 3. Find beginning of number: while (*ptr && !isdigit(*ptr)) ++ptr; 4. Convert to decimal: isdigit returns 0 or 1 while (isdigit(*ptr)) number = number * 10 + (*ptr++ - '0'); 5. Proceed with parsing of line. BYU CS 224 Pointers and Arrays Return result in number 24 Arrays and Pointers Array names are NOT pointer variables char a[6]; char *p; Requests memory for 6 characters, to be known by the name “a”. “a” is not a variable and known only at compile time (ie. defined in the compiler symbol table). Requests memory for a single pointer variable, to be known by the name “p”. “p” can point to any char (or contiguous array of chars). Example: char a[] = "hello"; a: char *p = "world"; h e p: BYU CS 224 Pointers and Arrays l l w o o \0 r l d \0 25 Arrays and Pointers Arrays and Pointers An array name (at compile time) is essentially a pointer to the first element in an array. Can change the value (contents) of a pointer. char arr[10]; char *cptr = arr; char c = *(cptr+2); c = 4[cptr]; // points to arr[0] // arr[2] // arr[4] Each of the following lines evaluate the same: cptr (cptr + n) *cptr *(cptr + n) BYU CS 224 arr (arr + n) *arr *(arr + n) &0[arr] &n[arr] 0[arr] n[arr] &arr[0] &arr[n] arr[0] arr[n] Pointers and Arrays address of arr[0] address of arr[n] value of arr[0] value of arr[n] 26 Exercise 8.3 Show 3 different ways to access the character 'o' in the array x without using brackets. char x[] = "Hello"; char* y = x; char** z = &y; BYU CS 224 Pointers and Arrays 27 Pointers and More… const const Pointers In C, const is a type qualifier keyword applied to a data type (to its right) that indicates to the compiler that the data is constant (does not vary). ptr1 is a (mutable) pointer to an int ptr2 is a pointer to a (non-mutable) int ptr3 is a (non-mutable) pointer to an int ptr4 is a (non-mutable) pointer to a (non-mutable) int BYU CS 224 Pointers and Arrays 29 C I/O Formatted Input/Output The printf function outputs formatted values to the stdout stream using putc Output x and y as an ASCII strings printf( const char *format, ... ); printf("\nX = %d, Y = %d", x, y); The function scanf is similar to printf, providing many of the same conversion facilities in the opposite direction: scanf( const char *format, ... ); scanf("%s = %f", name, &cost); Decimal String Character Hexadecimal Unsigned decimal BYU CS 224 "%d" or "%i" "%s" "%c“ "%x“ "%u name and cost MUST be pointers Floating point Scientific notation Pointer % Pointers and Arrays "%f" "%e" "%p" "%%" 30 Function Pointers Function Pointers In C, a function name is an label (address). As such, it is possible to define pointers to functions which can be: assigned, changed, placed in arrays, passed and returned from functions, used as “callbacks” to other functions, and so on. The format of a function pointer looks like: <type> (*POINTER_NAME)(<parameters...>) To write and use a function pointer: 1. Normal function declaration: 2. Wrap function name: 3. Use new syntax function call: BYU CS 224 int myFunc(int a, int b); int (*myFunc)(int a, int b); dog = (*myFunc)(10, 20); Pointers and Arrays 32 Function Pointers Function Pointers In C, a function name is an address. As such, it is possible to define pointers to functions which can be: assigned, changed, placed in arrays, passed to functions, returned by functions, and so on. int funcAdd(int a, int b) { return a + b; } int funcSub(int a, int b) { return a – b; } int (*f[2])(int, char*); f[0] = funcAdd; f[1] = funcSub; // array of function pointers result = (*f[0])(20, 10); result = (*f[1])(20, 10); // call funcAdd // call funcSub BYU CS 224 Pointers and Arrays 33 Function Pointers Function pointers can be passed as function parameters and used as “call-backs”. A function name (label) is converted to a pointer to itself and can be used where function pointers are required as input. Example: int add(int x, int y) { return x + y; } int subtract(int x, int y) { return x - y; } int domath(int (*mathop)(int, int), int x, int y) { return (*mathop)(x, y); } int main() { printf("Add: %d\n", domath(add, 10, 2)); printf("Subtract: %d\n", domath(subtract, 10, 2)); } BYU CS 224 Pointers and Arrays 34 Static Variables Static Variables Static functions are local to a file. Static variables are “global local” variables. May be declared inside a C function. Like local variables, a static variable cannot be referred from outside the function. However, unlike a local variable, the value continues to exist even after the function exits. The value comes back into scope when the function is called again (value retained). A function can pass out a pointer to a static variable and dereference the value. static int sum = 0; BYU CS 224 Pointers and Arrays 35 Static Variables Static Function Variables What does this function do? Does it compile? Work as intended? How would you fix it? int next_Factorial(void) { int current = 1; static int current = 1; int next = 1; static int next = 1; current *= next++; return current; } // next_Factorial printf("%d ", next_Factorial()); printf("%d ", next_Factorial()); ... BYU CS 224 Pointers and Arrays 36 Pointers to Pointers Pointers to Pointers Since pointers are variables themselves, they can be stored in arrays just as other variables can. char* lines[8]; Example: //char** linesptr = &lines[0]; //char** linesptr = &*lines; char* lines[8]; char** linesptr = lines; char** linesptr = lines; linesptr[0][0] = 'c'; linesptr[0] linesptr[1] linesptr[2] … BYU CS 224 defghi lmnopqrstuvwxyz abc Pointers and Arrays 37 Pointers to Pointers Pointers to Pointers Since pointers are variables themselves, they can be stored in arrays just as other variables can. Example: char* lines[8]; char** linesptr = lines; linesptr[0] linesptr[1] linesptr[2] … BYU CS 224 defghi lmnopqrstuvwxyz abc Pointers and Arrays 38 Multi-dimensional Arrays Multi-dimensional Arrays Multi-dimensional arrays declared with multiple indexes /* [row][col] */ /* Syntax Error! */ Array elements are stored by rows Pointers to pointers… day[i][j] day[i,j] The rightmost subscript varies the fastest Array name “points” to 1st element Multi-dimensional arrays passed to a function by value (address of 1st element in 1st row, 1st column… must declare the number of elements for every subscript except the first func(int day[ ][13]) {…} BYU CS 224 Pointers and Arrays 39 main Function The main Function The main function Return code for system must be present in every C program. is “called” by the operating system. exits the program with a return statement. # of command line arguments The prototype of main is pre-declared as: int main (int argc, char *argv[]); The definition doesn’t have to match. int main() { ... } main() { ... } These are OK The return statement can be omitted. BYU CS 224 Pointers and Arrays 40 The main Function What is the output of the following echo C program as called by: >>echo Good Morning America Good Morning America >> int main(int argc, char* argv[ ]) { while (--argc > 0) { printf("%s%s", *++argv, (argc > 1) ? " " : ""); } printf("\n"); return 0; } BYU CS 224 Pointers and Arrays 41 main Function C main to Assembly int main(int argc, char** argv) { unsigned int x = 7; unsigned int y = 5; unsigned int z; z = x * y; return 0; } SP x05f4 argc (r12) x05f6 argv (r13) x05f8 x x05fa y x05fc z x05fe ret adr x0600 Stack BYU CS 224 0x8040: 0x8044: 0x8048: 0x804c: 0x8052: 0x8058: 0x805c: 0x8060: 0x8064: 0x8068: 0x806a: 0x806e: main: 8031 000A 4D81 0002 4C81 0000 40B1 0007 0004 40B1 0005 0006 411C 0004 411D 0006 12B0 80DA 4C81 0008 430C 5031 000A 4130 __mpyi: 0x80da: 430E mpyi_add_loop: 0x80dc: C312 0x80de: 100C 0x80e0: 2801 0x80e2: 5D0E shift_test_mpyi: 0x80e4: 5D0D 0x80e6: 930C 0x80e8: 23F9 0x80ea: 4E0C 0x80ec: 4130 Pointers and Arrays SUB.W MOV.W MOV.W MOV.W MOV.W MOV.W MOV.W CALL MOV.W CLR.W ADD.W RET #0x000a,SP R13,0x0002(SP) R12,0x0000(SP) #0x0007,0x0004(SP) #0x0005,0x0006(SP) 0x0004(SP),R12 0x0006(SP),R13 #__mpyi R12,0x0008(SP) R12 #0x000a,SP CLR.W R14 CLRC RRC JLO ADD.W R12 shift_test_mpyi R13,R14 RLA.W TST.W JNE MOV.W RET R13 R12 mpyi_add_loop R14,R12 42 Exercise 8.4 How would you call the function doDaw with parameter 10 via function foo? void doDaw(int x) { return; } void foo(void (*f)(int), int i) { (*f)(i); } int main(void) { ??????? return 0; } BYU CS 224 Pointers and Arrays 43 BYU CS 224 Pointers and Arrays 44