C programming language Tutorial-Page3

Pointers

We studied the different data-types in the previous section. Let's consider an example These variables are stored in different memory locations. In programming, we would require to know the address of the locations where these variables are stored. The address of these variables is decided by the runtime.

Consider a scenario where these addresses are themselves stored in different memory locations. If we associate an entity with these memory locations where "X" and "Y" are stored, these entities would be termed Pointers. Pointers are variables which store the address of other variables.

Reference Operator

In C language, to retrieve the address of a variable, we employ the reference operator "&" (ampersand). By preceding the identifier of the variable with an ampersand sign, we can obtain the address off the variable.
integerPointer = &someNum;
charPointer = &someChar;
In this example, the values of different pointers would be
integerPointer = 1000 and charPointer = 1004

The ampersand operator assigns the address of "someNum" to "integerPointer" and "integerPointer" is said to point to "someNum".

Note: Though "someChar" is a character variable, it's address is an integer. Hence, the value of "charPointer" is an integer i.e. 1004.

Indirection / Dereferencing Operator

The pointers are declared as shown in the code segment below.

int *integerPointer;
char *charPointer;

If we wish to access the contents of the location pointed by the pointer variable, we would have to employ the dereferencing operator, the unary asterix "*"

int newNum;
newNum = *integerPointer;

To summarize
- "&" is the reference operator and can be read as "address of"
- "*" is the dereferencing operator and can be read as "value pointed by"
- The pointer is defined as type * name

Pointer Concepts

An example illustrating the different pointer concepts is as below.

int var1 = 5, var2, arr[10];
int *intPtr;

intPtr = &var1; /* intPtr now points to var1 */
var2 = *intPtr; /* var2 is now 5 */
*intPtr = 20; /* var1 is now 20, var2 = ?? */
intPtr = &arr[0]; /* intPtr now points to arr[0] */

Pointers and Functions

{
int var1 = 5, var2 = 6;
swap(&var1,&var2);
/* What is the value of var1 and var2? */
}

void swap(int *inp1,int *inp2)
{
int temp;
temp=*inp1;
*inp1=*inp2;
*inp2=temp;
}
Here in this example,pointer arguments enable a function to access and change objects in the function that called it

In last section, we observed pointers to variables.
It is possible to create pointer to pointers too.
Add one asterix * for every level of reference.

int var1 = 100, *ptr1, **pptr1;
ptr1 = &var1;
pptr1 = &ptr1;

Void pointers

void represents a variable that has no specific type. Hence, the size and dereferencing properties are underdetermined. Data pointed by the void pointers can't be directly dereferenced. The "void" pointers are special pointers. "void" pointers are widely employed to pass data of any data type from a "caller" function to the "called" function. Called function type casts the pointers and de-references the same.

EXAMPLE:

{ unsigned char var1 = 5, var2 = 6;
int iVar1 = 255, iVar2 = 312;
// Swap the character variable values
swap((void *)(&var1), (void *)(&var2));
// Swap the integer values
swap((void *)(&iVar1), (void *)(&iVar2));
}

void swap(void *inp1, void *inp2)
{
int *ptr1 = (int *)(inp1);
int *ptr2 = (int *)(inp2);
int temp;

temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}

Function Pointers

•  In C, function itself is not a variable. •  But, it is possible to define pointers to functions, which can be assigned, passed to functions, returned from functions,...
•  The declaration of a pointer to a function would look as
int (*compute)(void *, void *); •  This declaration defines "compute" to be a pointer to a function which takes 2 void pointers as input and returns an integer •  "compute" is a pointer to a function, *compute is the actual function. The parentheses are extremely important here. •  The following code has a different meaning int *compute(void *, void *); •  This declaration defines "compute" to be a function which takes 2 void pointers as input and returns an integer pointer

Function pointers are employed very extensively across different types of implementations, especially state machine implementation, conditional switches etc..

Lists and Arrays

The difference between list and array in C language is summarized below.
•List:
  •It is a collection of heterogeneous elements
  •Size of the list could be random and is determined at run-time
  •Memory for lists could be random
  •Example: Shopping lists, document list, etc
•Array:
  •It is a collection of homogeneous elements
  •Usually, the size of the array is deterministic
  •Memory for array is contiguous i.e. successive elements are stored in successive order in memory
  •Example: Array of marks for all students in a subject

Array

Array is defined to be a collection of homogeneous elements and of a definitive size.
int aData[20];
This defines 'aData' to be an integer array of 20 elements length.

An array's name can be employed as a pointer also

int *ptr1;
ptr1 = &aData[0];

The value of variable "ptr1" and array name "aData" would exactly be same.

Dynamic Memory Allocation

In all our previous examples and illustrations, the sizes of the array were fixed constants It is possible to allocate a storage space to store an array through pointers using dynamic memory allocation schemes "malloc" allocates the requested memory space in heap and returns a void * pointer, which is type-casted and stored into the pointer variable

int *ptr1; /* Pointer to an integer array */

/* Allocate space to store 10 integers / an array of 10 integers */ ptr1 = (int *) malloc(10 * sizeof(int));

The calloc() function allocates a block of memory and clears it to all zeros which may be useful in some circumstances. malloc function does not clear the assigned memory to zero and junk data lies there. This is the difference between malloc and calloc. Also malloc takes only one argument, size of memory to be allocated for use. While calloc takes two arguments as mentioned below. One how much data to be allocated and data type size to be stored.
calloc(n,sizeof(object))