You are on page 1of 13

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

Pointers
A pointer is a memory variable that stores a memory address. Pointer can have any name that is legal fro other variable and it is declared in the same fashion like other variables but it is always denoted by

* operator.

Features
1. Pointers save the memory space. 2. Execution time with pointer is faster because data is manipulated with the address i.e. direct access to memory location. 3. Pointers reduce the length and complexity of a program. 4. The memory is accessed efficiently with the pointers. The pointer assigns the memory space and it also releases. Dynamically memory is allocated. 5. Pointers are used with data structures. They are useful for representing tow-dimensional and multi dimensional arrays, structures.

Pointer Declaration
The declaration of pointer is as follows data type *pt_name; This tells the compiler three things about the variable pt_name 1. The asterisk (*) tells that the variable pt_name is a pointer variable. 2. pt_name needs a memory location. 3. pt_name points to variable of type data type Example: int *p; In the above example, the variable p as a pointer variable that points to an integer data type. Remember that the type int refers to the data type of the variable being pointed to by p and not the type of the value of the pointer. Similarly, the following declares character and floating pointers. char *ch; float *x; Once the pointer variable is declared, it can be made to a point to a variable using an assignment statement.

Accessing the Address of a Variable


The actual location of a variable in the memory is system dependent and therefore, the address of a variable is not known to us immediately. The address can be known with help of operator & available in C. The operator & immediately preceding a variable returns the address of the variable associated with it. Example : &a; would give the address of variable location . The & operator can be used only with simple variable or an array elements. If x is an array, then expressions &x[0] , &x[i+3] represent the address of 0th and (i+30th elements of array x.

I YEAR B.TECH CSE

Page 1

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

Initializing a Pointer
After declaration of pointer, it can be initialized with an address of another variable. The assignment statement is as follows int *p, a; p = &a; In the above statements, a is an integer variable. p is a integer pointing variable.i.e. &a gets the address of variable a and assigns to the pointer variable p.

Accessing a variable through its Pointer


Once the pointer has been assigned address of a variable, accessing the value of the variable using the pointer is important. This is done y using unary operator * (asterisk), usually known as the indirection operator. Ex. int a, *p, n; a = 10; p = &a; n = *p; The first line declares integer variables a and n, also declares a pointer variable p. Second line assigns value 10 to the variable a. Third line gets the address of variable of a and stores in the value in pointer p. Fourth line access the value of a with help of pointer p and stores in variable n. /*Program to demonstrate the accessing of pointer*/
#include <graphics.h> void main() { int x,y, *ptr; clrscr(); x=10; ptr=&x; y=*ptr; printf("Value of x = %d",x); printf("\nAddress of x = %u",&x); printf("\nValue stored pointer = %u",ptr); printf("\nAccessed value by pointer = %d",*ptr); printf("\nAddress of pointer = %u",&ptr); printf("\nValue of y = %d",y); getch(); } Output Value of x = 10 Address of x = 65524 Value stored in pointer = 65524 Accessed value by pointer = 10

I YEAR B.TECH CSE

Page 2

N.Vamshi Krishna

Computer Programming and Data Structures Technology Address of pointer = 65520 Value of y = 10

Unit IV

Vignana Bharathi Institute of

Pointers for Inter Function Communication


In upward communication and bi-directional communication address is being passed and using this address the data is referred back to the calling program. When we pass an address, we are actually passing a pointer to a variable. Passing Addresses Rather than passing data to the called function, we pass addresses (pointers). Once we have a pointer to a variable, it doesnt make any difference if it is local to the active function, defined in main, or even if it is a global variable we can change it. To create the pointers, the address operator(&) is used in the function call. To pass addresses, the formal parameters in the called function are defined as pointer to variables. Every time we want a called function to have access to a variable in the calling function, we pass the address of that variable to the called function and indirection operator is used to access it. /* Program to exchange two numbers using functions*/ void xChange(int*,int*); void main() { int a,b; clrscr(); printf("Enter two numbers :); scanf(%d%d,&a,&b); printf(\nBefore Function : a = %d, b= %d,a,b); xChange(&a,&b); printf("\nAfter Function : a = %d, b = %d",a,b); } void xChange(int *x, int *y) { int temp; printf("\nIn function before operation: *x = %d, *y = %d",*x,*y); temp = *x; *x = *y; *y = temp; printf("\nIn function after operation: *x = %d, *y = %d ",*x,*y); } Output: Enter two numbers : 44 55 Before Function : a = 44, b = 55 In function before operation : *x = 44, *y = 55 In function after operation : *x = 55, *y = 44 After Function : a = 55 , b = 44 Functions returning Pointers Nothing prevents a function from returning a pointer to the calling function. When we return a pointer, it must point to data in the calling function or a higher level function. It is an error to return a pointer to a local variable in the called function, because when the function terminates its memory may be used by other parts of the program.
I YEAR B.TECH CSE

Page 3

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

/*Program to find smallest of two numbers using function returning pointers*/ int* smaller(int* , int*); void main() { int a,b,*p; printf(Enter values of a and b :); scanf(%d%d,&a,&b); p = smaller(&a, &b); printf(Smaller number = %d,*p); } int* smaller(int* px, int* py) { return ( *px < *py ? px : py); } Output : Enter values of a and b : 67 89 Smallest number = 67

Pointers to Pointers
A pointer to a pointer in C can be used to indirectly point to the memory address of a variable. A pointer is a variable that contains the address of another variable. As a result, pointer to pointer contains the memory address of a pointer, which holds the memory address of a variable. The declaration is done as follows Data type **pointer name Ex : int **ptr;*p, a=10; p = &a; ptr = &p; In the above example, a is a normal variable storing the value 10. p is a pointer variable which stores the address of a and ptr is the pointer to pointer which stores the address of pointer p. /*Program to demonstrate the usage of pointers to pointers*/ #include<stdio.h> void main() { int a=10,*ptr1,**ptr2; clrscr(); ptr1 = &a; ptr2 = &ptr1; printf("\na= %d",a); printf("\n&a = %u",&a); printf("\nptr1 = %u",ptr1); printf("\n*ptr1 = %d",*ptr1); printf("\n&ptr1 = %u",&ptr1); printf("\nptr2 = %u",ptr2); printf("\n*ptr2 = %u",*ptr2); printf("\n**ptr2 = %d",**ptr2); getch(); } Output a = 10 &a = 65524 ptr1 = 65524 *ptr1 = 10
I YEAR B.TECH CSE

Page 4

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

&ptr1 = 65522 ptr2 = 65522 *ptr2 = 65524 **ptr2 = 10

Compatibility
Pointers have a type associated with them. They are no just pointer types, but rather are pointers to a specific type. Each pointer therefore takes on the attributes of the type to which it refers in addition to its own attributes. Pointer Size Compatibility The size of all pointers is the same. Every pointer variable holds the address of one memory location in the computer. The size of the variable that the pointer references can be different; it takes the attributes of the type being referenced. All computers today have more than 65,535 bytes, which is the maximum address that could be stored in 2 bytes. So pointers size is 2 bytes in this case. Dereference Type Compatibility The deference type is the type of the variable that the pointer is referencing. With one exception, it is invalid to assign a pointer of one type to a pointer of another type, even thought he values in both cases are memory addresses and would therefore seem to be fully compatible. Although addresses may be compatible because they are drawn from the same set, what is not compatible is the underlying data type of the referencing object. In C we cant use the assignment operator with pointers to different types. If we try to, we get compile error. Ex: A pointer to char is only compatible with pointer to char and a pointer to an int is only compatible with pointer to int. We cannot assign a pointer to a char to a pointer to an int. A pointer to void is a generic type that is not associated with a reference type; that is, it is not the address of a character, an integer, a real or any other type. So, it is compatible for assignment purpose only with all the other pointer types. Thus, a pointer of any reference type can be assigned to a pointer to void type and a pointer to void pointer can be assigned to pointer of any reference type. Ex : void* ptr; Casting Pointers The problem of type incompatibility can be solved using casing. We can make an explicit assignment between incompatible pointer types by using a cast, just as we can cast int to char. Another use of the cast is to provide a type for void pointer. When we cast it, however, we provide the type. Ex: void* ptr; char* cptr; int* iptr; ptr = cptr; iptr = ptr; iptr = (int*) cptr;

I YEAR B.TECH CSE

Page 5

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

Note : Compatibility also includes dereference level compatibility. Ex: a pointer to int is not compatible with a pointerto-pointer to int.

Pointer Expressions
Like other variables pointer variables can also be used in expressions. If p1 and p2 are properly declared and initialized pointers, then the following expressions are valid *p1 * *p2 *p1 / *p2
*p1 > *p2

(Performs multiplication of values accessed by pointer variables) (Performs division of values accessed by pointer variables)
(Checks whether the first value accessed is greater than second variable accessed) etc.

/*Program to demonstrate pointers and expressions*/ #include <stdio.h> void main() { int a=12, b=4, *p1, *p2; clrscr(); p1=&a; p2=&b; printf(" *p1 + *p2 = %d",*p1+*p2); printf("\n*p1 - *p2 = %d",*p1-*p2); printf("\n*p1 * *p2 = %d",*p1* *p2); printf("\n*p1/*p2 = %d",*p1/ *p2); if(*p1 > *p2) printf("\n*p1=%d value is greater",*p1); else printf("\n*p2=%d value is greater",*p2); getch(); } Output *p1 + * p2 = 16 *p1 - *p2 = 8 *p1 * *p2 = 48 *p1 / *p2 = 3 *p1 =12 is greater

Pointer Increments and Scale Factor


Let us consider an expression like p++; will cause the pointer p to point to the next value of its type. For example p is an integer pointer with an initial value, say 6500, then after the operation p++ i.e. p = p+1, the value of p will be 6502, but not 6501. That is, when we increment a pointer, its value is increased by the length of the data type that points to. This is called scale factor. The number of bytes used to store various data types depends on the system and can be found by making use of the sizeof operator. Generally, the character (1 byte), integer (2 bytes), float ( 4 bytes) etc.

Pointer and Arrays

I YEAR B.TECH CSE

Page 6

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

When we declare an array, the compiler allocates a base address and sufficient amount of storage to contain all the elements of the array in the contiguous memory locations. The base address is the location of first element (index 0) of an array. The compiler also defines the array name as a constant pointer to first element. For example if we consider int x[10]; here, x is an integer array. The base address will be the address of x[0]. As per the compiler the name x is defined as constant pointer pointing to the first element x[0] and therefore x = &x; If we declare a pointer p as an integer pointer, then we can make the pointer p to point to array x by the following statement int x[10], *p; p = x; (this is equivalent to p = &x[0]); p = &x[0] (=6500) Now we can access every value of x by using p++ to move from one element to another . Like p+1 = &x[1] (=6502) p+2 = &x[2] (=6504) Instead of using array indexing, we can use pointers to access array elements. *(p+2) gives the value stored in x[2].. The pointer accessing method is much faster than array indexing. It is possible to avoid the loop control variable i as shown below p = x; while (p <= p+4) { Sum = sum + *p; p++; } We know that in one dimensional array x, the expression x[i] is equivalent to *(p+i) Pointers can be used to manipulate two-dimensional arrays as well. x[i][j] is represented as *(*(p+i)+j) The base address of the array &x[0][0] , the compiler allocates contiguous space for all elements row-wise. /*Program to demonstrate pointer and arrays */ #include<stdio.h> void main() { int a[5], *p, sum=0, i; clrscr(); p=a; printf("Enter 5 numbers :"); for(i=0; i<5; i++) { scanf("%d",p+i); sum = sum + *(p+i); } printf("Sum = %d", sum); getch(); } Output
I YEAR B.TECH CSE

Page 7

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

Enter 5 numbers : 1 2 3 4 5 Sum = 15

Passing an array to a function The name of an array is actually a pointer to the first element, so in a function call sending an array we send array name instead of address for processing. When we pass the array, we do not use the address operator. Remember, the array name is pointer constant, so the name is already the address of the first element in array Ex : int doIt(int[]); void main() { int arrName[100]; ---------; doIt(arrName); } int doIt(int* arrSalary) { ------------; }

Memory Allocation Functions


In C, reserving memory locations for an object can be done in two ways : static allocation and dynamic allocation. Memory Usage Conceptually memory is divided into program memory and data memory. Program memory consists of the memory used for main and functions. Data memory consists of permanent definitions, such as global data and constants, local declarations and dynamic data memory. Exactly how C handles these different needs is a function of operating system and the compiler writers skills. Although the program code for a function may be in memory at all times, the local variables for function are available only when it is active. Furthermore, more than one version of the function can be active at a time. In this case, multiple copies of the local variables are allocated, although only one copy of the function is present. The memory facility for these capabilities is known as stack memory. In addition to stack, a memory allocation known as heap is available. Heap memory is unused memory allocated to the program and available to be assigned during its execution. It is the memory pool from which memory is allocated when requested by the memory allocation functions.

Main

Function Program Memory

I YEAR B.TECH CSE

Page 8

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV
Heap Data Memory Conceptual View of Memory

Vignana Bharathi Institute of

Global

Stack

Static Memory Allocation Static memory allocation requires that the declaration and definition of memory be fully specified in the source program. The number of bytes reserved cannot be changed during run time. This is the technique we have used to this point to define variables, arrays, pointers, and streams. Dynamic Memory Allocation Dynamic memory allocation uses predefined functions to allocate and release memory for data while the program is running. It effectively postpones the data definition, but not the data declaration, to run time. Memory Allocation Functions Four memory management functions are used with dynamic memory. They are malloc, calloc, realloc and free. First three are used for memory allocation and fourth is used for return memory when it is no longer needed. All the memory management functions are found in the standard library file stdlib.h. Block Memory Allocation (malloc) The malloc function allocates a block of memory that contains the number of bytes specified in its parameters. It returns a void pointer to the first byte of the allocated memory. The allocated memory is not initialized. Function prototype is void* malloc(size_t size); The type, size_t is defined in several header files including stdio.h. The type is usually an unsigned integer. To provide portability, the size specification in mallocs actual parameter is generally computed using the sizeof operator. For example, if we want to allocate an integer in the heap, then we call as follows pInt = malloc(sizeof(int)); malloc function returns the address of the first byte in the memory space allocated. If it is not successful, it return NULL pointer. An attempt to allocate memory from the heap when the memory is insufficient is known as overflow. It is up to the program to check for memory overflow. If it doesnt the program produces the invalid results or aborts with an invalid address the first time the pointer is used. If we call malloc with a zero size, the results are unpredictable. It may return NULL pointer or it may return some other implementation dependent value. Note : Never call malloc with a zero size

I YEAR B.TECH CSE

Page 9

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

Prior to C99, it was necessary to cast the pointer returned from a memory allocation function. The casting format is pointer = (type*) malloc(size); Ex: pInt = (int*)malloc(4);

Contiguous Memory Allocation (calloc) calloc is primarily used to allocate memory for arrays. It differs from malloc only in that it sets memory to null characters. The declaration is as follows void *calloc(size_t element_count, size_t element_size); Example : ptr = (int*) calloc(200, sizeof(int)); Reallocation of memory (realloc) It is highly efficient function. When given a memory pointer to a previously allocated block of memory, realloc changes the size of the block by deleting or extending the memory at the end of block. If the memory cannot be extended because of other allocations, realloc allocates a completely new block, copies the existing memory allocation to the new allocation and deletes the old allocation. The declaration is as follows void *realloc(void* ptr, size_t newSize); Example ptr = realloc(ptr, 15*sizeof(int)); Releasing Memory (free) When memory locations allocated by malloc, calloc or realloc are no longer needed, they should be freed using predefined function free. It is an error to free memory with a null pointer, a pointer to other than the first element of an allocated bloc, a pointer that is a different type than the pointer that allocated the memory, it is also a potential error to refer to memory after it has been released. The function declaration is void free(void* ptr); Example free(ptr); Releasing memory does no change the value in the pointer. It still contains the address in the heap. It is logic error to use the pointer after memory has been released. Note : The pointer used to free memory must be of the same type as the pointer used to allocate memory.

Array of Pointers
Array of pointers is especially helpful when the number of elements in the array is variable. Consider the following two dimensional array 32 13 22
I YEAR B.TECH CSE

18 11

12 16

24 12 42 19 14

Page 10

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

13 11

13 18

14

If we use two-dimensional array for storing these numbers, we are wasting a lot of memory. This array is also known as ragged array. The solution in this case is to create five one-dimensional arrays that are joined through an array of pointers. One implementation is as follows

int** table; table = (int**) calloc(rowNum+1, sizeof(int)); table[0] = (int*) calloc (4, sizeof(int)); table[1] = (int*) calloc (7, sizeof(int)); table[2] = (int*) calloc (1, sizeof(int)); table[3] = (int*) calloc (3, sizeof(int)); table[4] = (int*) calloc (2, sizeof(int)); table[5] = NULL;

Pointers to Void and Functions


Pointer to void A pointer to void is a generic pointer that can be used to represent any data type during compilation or run time. Note that a pointer to void is not a null pointer; it is pointing to a generic data type (void). Example: /* Program to demonstrate pointer to void*/ #include<stdio.h> void main() { void* p; int i=7; float f=23.5; p=&i; printf( i contains : %d\n, *((int*)p)); printf( f contains : %f\n,*((float*)f)); } Output i contains 7 f contains 23.500000 Note : A pointer to void cannot be dereferenced unless it is cast. Pointer to Function A function, like a variable, has an address location in the memory. It is therefore, possible to declare a pointer to function, which can then be used as an argument in another function. A function to a pointer is declared as follows: type (fptr)(); This tells the compiler that fptr is a pointer to a function which returns type value. Example double (*p1)(), mul(); p1 = mul;

I YEAR B.TECH CSE

Page 11

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

The above statement declares p1 as a pointer to a function and mul as a function and then make p1 to point to the function mul.

Command Line Arguments


When main have parameters, they are known as command line arguments. The function main can be defined either with no argument (void) or with two arguments : one an integer and other an array of pointers to char (strings) that represent user-determined values to be passed to main. The two different formats are 1. void main() { -----; } 2. void main(int argc, char *argv[]) { ----} The names of the arguments are our choice, traditionally they are called argc(argument count) and argv (argument vector). The first argument defines the number of elements in the array identified in the second argument. The value for this argument is not entered using the keyboard; the system determines it from the arguments the user types. The argc array has several elements. The first element points to the name of the program (its filename). It is provided automatically by the program. The last element contains NULL and may be used to identify the end of the list. The rest of the elements contain pointers to the user-entered string values. /* Program to demonstrate command line arguments*/ #include<stdio.h> #include<string.h> #include<stdlib.h> void main(int argc, char* argv[]) { int i; printf(The number of arguments = %d\n,argc); printf(The name of the program = %s\n,argv[0]); for(i=1; i<argc; i++) printf(User value No. %d= %s\n,i,argv[i]); } Output C:/> cmdLine it is the time The number of arguments =5 The name of the program = CMDLINE User value No.1 = it User value No.2 = is User value No.3 = the User value No.4 = time -o0o-

I YEAR B.TECH CSE

Page 12

N.Vamshi Krishna

Computer Programming and Data Structures Technology

Unit IV

Vignana Bharathi Institute of

Strings

I YEAR B.TECH CSE

Page 13

N.Vamshi Krishna

You might also like