pointers and arrays in C
EX: output? void square_it(int k) { k = k*k } int n=5; square_it(n); printf("%d", n);
"5" because void returns nothing when square_it() is called
declare a pointer (of type int)
*int *p;* declared to store the location of an integer that is stored elsewhere
EX: output? int *p, n=2; *p = 15; *p?
*p is undefined statement **p=15* says that the value in p represents the address of a memory location into which the integer 15 should be stored
EX: output? int *p = NULL; printf("%d", *p);
*run-time error* because there is an attempt to retrieve an integer value from a NULL address
create a flexible multidimensional array and initialize elements to 0:
int *matrix[10]; /* allocate storage for a 10x10 matrix */ for(i=0; i<10; i++) matrix[i]=malloc(10*sizeof(int)); /* initialize elements of matrix to 0 */ for(i=0; i<10; i++) for(j=0; j<10; j++) matrix[i][j]=0;
set pointer (*p) equal to integer (n)
int *p, n=2; p=&n; places the *address* of int n into the pointer variable p: makes p a *reference* to n
EX: function int *createIntArray(int size) to allocate arrays with size (100) stored in it
int i, *array; /* space for an extra int is added */ array = malloc(101*sizeof(int)); array[0] = 100; array = array + 1; /* initialize elements to 0 */ for(i=0; i<100; i++) array[i]=0 /* print size of 100 */ printf("Size of array: %d\n", array[-1]);
declare multidimensional arrays
int matrix[10][10], cube[5][12][4]; for(i=0; i<10; i++) for(j=0; j<10; j++) matrix[i][j]=0; for(i=0; i<5; i++) for(j=0; j<12; j++) for(k=0; k<4; k++) cube[i][j][k]=0;
value
how every parameter to a function in C is passed by.
EX: assignment and error check of *malloc* int*p, n=1000;
if(p = malloc(n*(sizeof(int))) { ... } /* can reference p */ else { ... } /* malloc failed */
advantages to array-of-arrays structure (2D arrays as 1D-arrays-of-pointers-to-1D-arrays)
1. allows the creation of matrices in which each row can be of a different size 2. can be passed as an argument to a function without providing an other information 3.can be extended easily to higher dimensions
EX: output? void square_it(int *k) { *k = (*k)*(*k) } int n=5; square_it(&n); printf("%d", n);
25 passed by reference: the value of n is changed
EX: output? int *p; p = NULL; if(p! = NULL) printf("%d", *p);
ERROR: referencing through a *NULL* or uninitialized pointer produces an error
EX: valid? p = malloc(sizeof(int)); if(p=NULL) { ... } else { ... }
NO: code will always execute else clause because if test is an *assignment operator* (*=*) rather than an *equality comparison operator* (*==*)
T/F? notation array[k] can be thought of as shorthand for *(array+k)
TRUE
T/F? array[5]=0 is equivalent to *(array+5)=0
TRUE: array[5] = 0 creates its own pointer (*p) initialized to p = array + 5 where pointer p is equal to the address of the array + 5 (contains the 5th element of the array). *p = 0 puts 0 at the address location of the 5th element of the array *(array+5)=0 takes the address of the beginning of the array and adds 5 to it -- result: address of the 5th element of the array. * operator refers to the content of that location and the *assignment operator* = set the content of that location to 0
T/F? following are equivalent void clear2D(int a[][], int m, int n) void clear2D(int *a[], int m, int n) void clear2D(int **a, int m, int n)
TRUE: all are creating 2D arrays by allocating a 1D array of pointers to 1D arrays are NOT valid for passing an array declared as int array[10][10]
T/F? int *array; array = malloc(7 * sizeof(int)); array = &(array[0])?
TRUE: array contains the address of the memory location of the first integer element = array[0]
T/F? void clear2D(int a[][5], int m, int n) { int i, j; for(i=0; i<m; i++) for(j=0; j<n; j++) a[i][j]=0; } works
TRUE: implementation works because the number of columns is explicitly specified
T/F? int p[10] declares p to be an int pointer but uses brackets instead of *
TRUE: int p and int *p are different data types but are declared using the same keyword int. the only different is the * operator - not used in this case
EX: valid? int *array, i; array = malloc(1000*int); for(i=0; i<1000; i++) *(array+i)=0;
YES: because array[k] can always be written as *(array+k)
EX: valid? int m; *(&m)=3;
YES: valid assignment of setting integer m = 3
passing array of numbers to a function: int array[100], n=100, minval, maxval;
[minval, maxval] = getStatistics(array, n, &minval, &maxval) function is able to change the variables in calling program: requires the calling program to pass *pointers* to the variables it wants the function to change
int array[4][8]
allocates storage/memory for a 2-D array of integer elements: defines 4 1-D arrays of length 8
EX: allocate the memory of an array[7] to have an extra 8th element and store the size there int *array;
array = malloc(8*sizeof(int)); array[0] = 7; array++; allocate memory 1 element bigger and then increment array so that it correctly points to the 1st element of the "real" array *(array-1) = array[-1] = size of the array = 7
NULL
built-in constant that can be assigned to any pointer variable to signify that it doesn't yet contain a valid address
EX: array[10][5]; how is address of array computed?
computed as the address of the array plus (10 x NumberOfColumns + 5) times array element of size
malloc function
defines the amount of memory/storage to be allocated dynamically -returns a NULL pointer if can't allocate the requested amount of storage
EX: initializing elements of an array through pointer p to 0 int *p, n=1000, i;
for(i=0; i<n; i++) p[i]=0;
EX: allocate memory for a pointer to an array of size n int *p, n=1000;
p = malloc(n*sizeof(int));
pointer
references the location (or *address*) of a variable -necessary in order to access information from storage locations for which there's no explicit variable name
EX: output? int *p; float *q; p=q;
results in a *compile-time error* because p and q are not of the same type: pointers to different data types are themselves different data types p=(int*)q; works because q has been cast to the type of p
sizeof() function
returns the size of any standard or user-defined data types (*int*, *float*, and *char*)
what does the statement *int array[1000]* do?
the compiler treats array[1000] as defining a variable called array as an int pointer initialized to the address of a chunk of memory big enough to hold 1000 integers array is similar to an ordinary integer pointer
disadvantage of array-of-arrays structure
the resulting 2D array is not allocated in a single chunk of contiguous memory
*&* operator
used to obtain the address of variable assigned to pointer
free() function
used to return memory back to the *operating system* (*OP*) - done after allocating memory (*malloc*) by the OP
function to find minval and maxval in array of numbers: int array[100], n=100, minval, maxval; getStatistics(array, n, &minval, &maxval);
void getStatistics(float array[], int n, float *minp, float *maxp) { int i; float min, max; min = max = array[0]; for(i=1; i<n; i++) { if(array[i]<min) min=array[i]; if(array[i]>max) max=array[i]; } *minp = min; *maxp = max; return; }