Friday, January 11, 2013

Null pointer context

(char *)0 as a NULL pointer

When function prototype is in scope, argument passing becomes "assignment context" and most casts can be safely omitted since the prototype tells the compiler that a pointer type is required and of which type.
Function prototypes cannot provide the types for variable arguments in a variable length argument list and explicit casts are still required.

Macro NULL;


ANSI C Rationale - http://www.lysator.liu.se/c/rat/title.html




"Equivalence" refers to the following key definition:
(The exceptions are when the array is the operand of a sizeof or & operator, or is a literal string initializer for a character array.)
An lvalue [see question 2.5] of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.
-- from http://www.lysator.liu.se/c/c-faq/c-2.html


Arrays and pointers


 int array[NROWS][NCOLUMNS];
 f(array);
the function's declaration should match:

 f(int a[][NCOLUMNS]) {...}
or
 f(int (*ap)[NCOLUMNS]) {...}   /* ap is a pointer to an array */

Pointer at the whole array - int (*ap)[N]


Dynamic Multidimensional array


It is usually best to allocate an array of pointers, and then initialize each pointer to a dynamically-allocated "row."  Here is a two-dimensional example:


 int **array1 = (int **)malloc(nrows * sizeof(int *));
 for(i = 0; i < nrows; i++)
  array1[i] = (int *)malloc(ncolumns * sizeof(int));

(In "real" code, of course, malloc would be declared correctly, and each return value checked.)
You can keep the array's contents contiguous, while making later reallocation of individual rows difficult, with a bit of explicit pointer arithmetic:


 int **array2 = (int **)malloc(nrows * sizeof(int *));
 array2[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
 for(i = 1; i < nrows; i++)
  array2[i] = array2[0] + i * ncolumns;