500 likes | 739 Views
Programming Fundamentals using C Arrays and Pointers. By TungTT2. Training objectives. Arrays Array Definition & Declaration Array Representation Multi-dimensional Arrays Passing arrays to function. Training objectives. Pointers Pointer Arithmetic Swap Example w/Pointers Null Pointers
E N D
Programming Fundamentals using CArrays and Pointers By TungTT2
Training objectives • Arrays • Array Definition & Declaration • Array Representation • Multi-dimensional Arrays • Passing arrays to function
Training objectives • Pointers • Pointer Arithmetic • Swap Example w/Pointers • Null Pointers • Arrays and Pointers • Pointers to Pointers • Function Pointers • Dynamic Memory Allocation
Arrays • A data structure is a collection of data types designed to store information in some optimal way. • Data structures improve readability and simplify coding considerably. • The simplest example of a data structure is an array.
The solution without array syntax (4) What are the disadvantages of this solution?
Arrays in C Compare: C: int array[10]; Java: int[] array = new int[10]; All elements of same type – homogenous Unlike Java, array size in declaration int array[10]; int b; array[0] = 3; array[9] = 4; array[10] = 5; array[-1] = 6; First element (index 0) Last element (index size - 1) No bounds checking! Allowed – usually causes no error array[10] may overwrite b
Array Representation a[2] 0x1008 a[1] 0x1004 a[0] 0x1000 • Homogeneous Each element same size – s bytes • An array of m data values is a sequence of ms bytes • Indexing: 0th value at byte s0, 1st value at byte s1, … • m and s are not part of representation • Unlike in some other languages • s known by compiler – usually irrelevant to programmer • m often known by compiler – if not, must be saved by programmer int a[3];
Array Representation i 0x1014 c2 0x1010 a[2] 0x100C a[1] 0x1008 a[0] 0x1004 c1 0x1000 char c1; int a[3]; char c2; int i; Could be optimized by making these adjacent, and reducing padding (by default, not) Array aligned by size of elements
Array Sizes • What is • sizeof(array[3])? • sizeof(array)? int array[10]; 4 returns the size of an object in bytes 40
Multi-Dimensional Arrays • Multi-dimensional arrays declared with multiple indexes • arr[i][j] /* RIGHT*/ • arr] /* WRONG! */ • Array elements are stored by rows • The rightmost subscript varies the fastest • Array name “points” to 1st element
Multi-Dimensional Arrays matrix[1][2] 0x1014 matrix[1][1] 0x1010 matrix[1][0] 0x100C matrix[0][2] 0x1008 matrix[0][1] 0x1004 matrix[0][0] 0x1000 int matrix[2][3]; matrix[1][0] = 17; Recall: no bounds checking What happens when you write: matrix[0][3] = 42; “Row Major” Organization
Passing Arrays To Functions (1) Arguments • The syntax of a function call that passes an array is functionIdentifier (arrayIdentifier, ... ) • Where functionIdentifier is the name of the function and arrayIdentifier is the array name without brackets.
Passing Arrays To Functions (2) Parameters • The syntax of a function header that receives an array address is dataType functionIdentifier ( dataType arrayIdentifier [ ], ... ) • The brackets following arrayIdentifier inform the compiler that the parameter holds the address of a one-dimensional array • Multi-dimensional arrays passed to a function must declare the number of elements for every subscript except the first dataType functionIdentifier ( dataType arrayIdentifier [ ][13], ... )
Pointers • A pointer is a variable that contains 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. • Array pointers enable us to conveniently process groups of data such as vectors, lists, and strings.
Pointers • Special case of bounded-size natural numbers • Maximum memory limited by processor word-size • 232 bytes = 4GB, 264 bytes = 16 exabytes • A pointer is just another kind of value • A basic type in C int *ptr; The variable “ptr” is a pointer to an “int”.
Pointer Operations in C • Creation &variable Returns variable’s memory address • Dereference *pointer Returns contents stored at address • Indirect assignment *pointer=val Stores value at address • Assignment pointer=ptr Stores pointer in another variable
Using Pointers … 0x1014 ptr2: 0x1010 … 0x100C ptr1: 0x1008 i2: 0x1004 i1: 0x1000 int i1; int i2; int *ptr1; int *ptr2; i1 = 1; i2 = 2; ptr1 = &i1; ptr2 = ptr1; *ptr1 = 3; i2 = *ptr2; 0x1000 0x1000 2 3 3 1
Using Pointers (cont.) int int1 = 1036; /* some data to point to */ int int2 = 8; int *int_ptr1 = &int1; /* get addresses of data */ int *int_ptr2 = &int2; *int_ptr1 = int_ptr2; *int_ptr1 = int2; What happens? Type check warning: int_ptr2 is not an int int1 becomes 8
Using Pointers (cont.) int int1 = 1036; /* some data to point to */ int int2 = 8; int *int_ptr1 = &int1; /* get addresses of data */ int *int_ptr2 = &int2; int_ptr1 = *int_ptr2; int_ptr1 = int_ptr2; What happens? Type check warning: *int_ptr2 is not an int * Changes int_ptr1 – doesn’t change int1
Pointer Arithmetic char *p; char a; char b; p = &a; p += 1; int *p; int a; int b; p = &a; p += 1; pointer + numberpointer – number E.g., pointer+ 1 adds 1 something to a pointer In each, p now points to b (Assuming compiler doesn’t reorder variables in memory) Adds 1*sizeof(char) to the memory address Adds 1*sizeof(int) to the memory address Pointer arithmetic should be used cautiously
The Simplest Pointer in C • Special constant pointer NULL • Points to no data • Dereferencing illegal – causes segmentation fault • To define, include <stdlib.h> or <stdio.h>
Generic Pointers • void *: a “pointer to anything” • Lose all information about what type of thing is pointed to • Reduces effectiveness of compiler’s type-checking • Can’t use pointer arithmetic type cast: tells the compiler to “change” an object’s type (for type checking purposes – does not modify the object in any way) Dangerous! Sometimes necessary… void *p; int i; char c; p = &i; p = &c; putchar(*(char *)p);
Pass-by-Reference 1 a 2 b x y 1001 1002 void set_x_and_y(int *x, int *y) { *x = 1001; *y = 1002; } void f(void) { int a = 1; int b = 2; set_x_and_y(&a,&b); }
Dirty “secret”: Array pointer to the initial (0th) array element a[i] *(a+i) An array is passed to a function as a pointer The array size is lost! Usually bad style to interchange arrays and pointers Avoid pointer arithmetic! Arrays and Pointers Passing arrays: Must explicitly pass the size Really int *array int foo(int array[], unsigned int size) { … array[size - 1] … } int main(void) { int a[10], b[5]; … foo(a, 10)… foo(b, 5) … }
Arrays and Pointers int foo(int array[], unsigned int size) { … printf(“%d\n”, sizeof(array)); } int main(void) { int a[10], b[5]; … foo(a, 10)… foo(b, 5) … printf(“%d\n”, sizeof(a)); } What does this print? 8 ... because array is really a pointer What does this print? 40
Arrays and Pointers • Given the previous declarations, each of the following lines are equal. char word[10]; char *cptr; cptr = word; // points to word[0] cptr word &word[0] address of word[0] (cptr + n) word + n &word[n] address of word[n] *cptr *word word[0] value of word[0] *(cptr + n) *(word + n) word[n] value of word[n]
Arrays and Pointers int i; int array[10]; for (i = 0; i < 10; i++) { array[i] = …; } int *p; int array[10]; for (p = array; p < &array[10]; p++) { *p = …; } These two blocks of code are functionally equivalent
Strings • In C, strings are just an array of characters • Terminated with ‘\0’ character • Arrays for bounded-length strings • Pointer for constant strings (or unknown length) char str1[15] = “Hello, world!\n”; char *str2 = “Hello, world!\n”; C, … H e l l o , w o r l d ! \n terminator C terminator:’\0’ length H e l l o , w o r l d ! \n Pascal, Java, …
String length • Must calculate length: • Provided by standard C library: #include <string.h> can pass an array or pointer int strlen(char str[]) { int len = 0; while (str[len] != ‘\0’) len++; return (len); } Check for terminator array access to pointer! What is the size of the array???
Pointers to Pointers ptrArr[0] ptrArr[0] FSO FSO ptrArr[1] ptrArr[1] 123 123 ptrArr[2] ptrArr[2] abc abc … … Pointers to Pointers • Since pointers are variables themselves, they can be stored in arrays just as other variables can. Example: char* ptrArr[8];
Pointers of Pointers int var = 5; int* ptr; int** pptr; int*** ppptr; int**** pppptr; ptr = &var; pptr = &ptr; ppptr = &pptr; pppptr = &ppptr; var, *ptr, **pptr, ***ppptr, ****pppptr all = 5 &var=? &ptr = ? *ptr = ? &pptr = ? *pptr = ? &ppptr = ? *ppptr = ? &pppptr = ? *pppptr = ?
Pointer to Pointer (char **argv) Passing arguments to main: size of the argv array/vector int main(int argc, char **argv) { ... } an array/vector of char * Recall when passing an array, a pointer to the first element is passed Suppose you run the program this way UNIX% ./program hello 1 2 3 argc == 5 (five strings on the command line)
char **argv “3” argv[4] 0x1020 These are strings!! Not integers! “2” argv[3] 0x1018 argv[2] “1” 0x1010 argv[1] 0x1008 “hello” argv[0] 0x1000 “./program”
Function Pointers Function Pointers • In C, a function is not a variable, but it is possible to define pointers to functions which can be: • assigned, • placed in arrays, • passed to functions, • returned by functions, and so on. int function1(int a, char* s) { … } int function2(int a, char* s) { … } int (*f[2])(int, char*); f[0] = function1; f[1] = function2; (*f[n])(10, "hello");
Complicated Declarations Function Pointers • C is sometimes castigated for the syntax of declarations, particularly ones that involve pointers to functions: int *f(); // f: function returning pointer to int int (*pf)(); // pf: pointer to function returning int • What do these do? char **argvargv: pointer to pointer to char int (*daytab)[13]daytab: pointer to array[13] of int int *daytab[13]daytab: array[13] of pointer to int char (*(*x())[])()x: function returning pointer to array[ ] of pointers to function returning char char (*(*x[3])())[5]x: array[3] of pointer to function returning pointer to array[5] of char
Definition — The Heap • A region of memory provided by most operating systems for allocating storage not in Last in, First out discipline • I.e., not a stack • Must be explicitly allocated and released • May be accessed only with pointers • Remember, an array is equivalent to a pointer • Many hazards to the C programmer
Static Data Allocation 0xFFFFFFFF stack (dynamically allocated) SP heap (dynamically allocated) address space static data program code (text) PC 0x00000000
Allocating Memory in The Heap • See <stdlib.h> void *malloc(size_t size); void free(void *ptr); void *calloc(size_t nmemb, size_t size); void *realloc(void *ptr, size_t size); • malloc() — allocates size bytes of memory from the heap and returns a pointer to it. • NULL pointer if allocation fails for any reason • free() — returns the chunk of memory pointed to by ptr • Must have been allocated by malloc or calloc
Notes • calloc() is just a variant of malloc() • malloc() is analogous to new in C++ and Java • new in C++ actually calls malloc() • free() is analogous to delete in C++ • delete in C++ actually calls free() • Java does not have delete — uses garbage collection to recover memory no longer in use
Typical usage of malloc() and free() char *getTextFromSomewhere(…); int main(){ char * txt; …; txt = getTextFromSomewhere(…); …; printf("The text returned is %s.", txt); free(txt); }
Typical usage of malloc() and free() char * getTextFromSomewhere(…){char *t;...t = malloc(stringLength);...return t; } int main(){ char * txt; …; txt = getTextFromSomewhere(…); …; printf("The text returned is %s.", txt); free(txt); }
Definition – Memory Leak • The steady loss of available memory due to forgetting to free() everything that was malloc’ed. • Bug-a-boo of most large C and C++ programs • If you “forget” the value of a pointer to a piece of malloc’ed memory, there is no way to find it again! • Killing the program frees all memory!