[go: up one dir, main page]

0% found this document useful (0 votes)
6 views15 pages

Pointers

Uploaded by

Maniacal Danger
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views15 pages

Pointers

Uploaded by

Maniacal Danger
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

POINTERS

Dept. of Computer Science and Engineering


National Institute of Technology, Durgapur
West Bengal, India
Point to here, point to there, point to that,
point to this, and point to nothing!
well, they are just memory addresses!!??
WHAT IS A POINTER
• The Pointer in C, is a variable that stores address of another variable.
• A pointer can also be used to refer to another pointer function.
• A pointer can be incremented/decremented, i.e., to point to the next/ previous memory location.
• The purpose of pointer is to save memory space and achieve faster execution time.
• Pointers are used in C program to access the memory and manipulate the address.
• A pointer is a variable that represents the location (rather than the value) of a data item.
• They have a number of useful applications.
• Enables us to access a variable that is defined outside the function.
• Can be used to pass information back and forth between a function and its reference point.
• More efficient in handling data tables.
• Reduces the length and complexity of a program.
• Sometimes also increases the execution speed.

POINTER
• When declaring a variable, the compiler sets aside memory storage
with a unique address to store that variable.
• The compiler associates that address with the variable’s name.
• When the program uses the variable name, it automatically
accesses a proper memory location.
• No need to concern which address.
• But we can manipulate the memory address by using pointers.
DECLARATION OF A POINTER
• A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location.
• Like any variable or constant, a pointer must be declared before using it to store any variable address.
• The general form of a pointer variable declaration is −
• type *var-name;
• Here, type is the pointer's base type; it must be a valid C data type.
• var-name is the name of the pointer variable.
• The asterisk * used to declare a pointer is the same asterisk used for multiplication.
• However, in this statement the asterisk is being used to designate a variable as a pointer.
• Take a look at some of the valid pointer declarations −
• int *ip; /* pointer to an integer */
• double *dp; /* pointer to a double */
• float *fp; /* pointer to a float */
• char *ch /* pointer to a character */
• int* p1, p2; /*Here, we have declared a pointer p1 and a normal variable p2/*

Assigning addresses to Pointers


• Let's take an example.
int* pc, c;
c = 5;
pc = &c;
• Here, 5 is assigned to the c variable. And, the address of c is assigned to
the pc pointer.
• To get the value of the thing pointed by the pointers, we use
the * operator. For example:
• int* pc, c; c = 5; pc = &c; printf("%d", *pc); // Output: 5
• Here, the address of c is assigned to the pc pointer. To get the value
stored in that address, we used *pc.
• In the above example, pc is a pointer, not *pc. You cannot and
should not do something like *pc = &c;
• By the way, * is called the dereference operator (when working
with pointers). It operates on a pointer and gives the value stored in
that pointer.
C POINTERS – OPERATORS THAT ARE USED WITH POINTERS
Lets discuss the operators & and * that are used with Pointers in C.
• “Address of”(&) Operator
• We have already seen in the first example that we can display the address of a variable using ampersand sign.
• We have used &num to access the address of variable num.
• The & operator is also known as “Address of” Operator.
• printf("Address of var is: %p", &num);
• Point to note: %p is a format specifier which is used for displaying the address in hex format.
Now that we know how to get the address of a variable
• How to store that address in some other variable?
• That’s where pointers comes into picture.
• As mentioned pointers in C programming are used for holding the address of another variables.
• Pointer is just like another variable, the main difference is that it stores address of another variable rather than a value.
• “Value at Address”(*) Operator
• The * Operator is also known as Value at address operator.
• Example of Pointer demonstrating the use of & and *
#include <stdio.h>
int main()
{
/* Pointer of integer type, this can hold the * address of a integer type variable. */
int *p;
int var = 10; /* Assigning the address of variable var to the pointer * p. The p can hold the address of var because var is * an integer type variable. */
p= &var;
printf("Value of variable var is: %d", var);
printf("\nValue of variable var is: %d", *p);
printf("\nAddress of variable var is: %p", &var);
printf("\nAddress of variable var is: %p", p);
printf("\nAddress of pointer p is: %p", &p);
return 0;
}
• Output:
Value of variable var is: 10
Value of variable var is: 10
Address of variable var is: 0x7fff5ed98c4c
Address of variable var is: 0x7fff5ed98c4c
Address of pointer p is: 0x7fff5ed98c50
HOW TO USE POINTERS?
• There are a few important operations, which we will do with the help of pointers very frequently.
• We define a pointer variable,
• Assign the address of a variable to a pointer and
• Finally access the value at the address available in the pointer variable.
• This is done by using unary operator * that returns the value of the variable located at the address specified by its operand.
• The following example makes use of these operations −
#include <stdio.h>
int main ()
{
int var = 20; /* actual variable declaration */
int *ip; /* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/
printf("Address of var variable: %x\n", &var ); /* address stored in pointer variable */
printf("Address stored in ip variable: %x\n", ip ); /* access the value using the pointer*/
printf("Value of *ip variable: %d\n", *ip );
return 0;
}

When the above code is compiled and executed, it produces the following result −
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
TYPES OF POINTERS IN C
• Null Pointer
• We can create a null pointer by assigning null value during the pointer declaration.
• This method is useful when you do not have any address assigned to the pointer.
• A null pointer always contains value 0.
• Following program illustrates the use of a null pointer:
• #include <stdio.h>
int main()
{
int *p = NULL; //null pointer
printf(“The value inside variable p is:\n%x”,p);
return 0;
}
• Output:
• The value inside variable p is: 0
• Void Pointer
• In C programming, a void pointer is also called as a generic pointer.
• It does not have any standard data type.
• A void pointer is created by using the keyword void.
• It can be used to store an address of any variable.
• Following program illustrates the use of a void pointer:
#include <stdio.h>
int main()
{
void *p = NULL; //void pointer
printf("The size of pointer is:%d\n",sizeof(p));
return 0;
}
Output:
• The size of pointer is:4
• Wild pointer
• A pointer is said to be a wild pointer if it is not being initialized to anything.
• These types of C pointers are not efficient because they may point to some unknown memory location which may cause problems in our program and it may lead to crashing of the
program.
• One should always be careful while working with wild pointers.
• Following program illustrates the use of wild pointer:
#include <stdio.h>
int main()
{ int *p; //wild pointer
printf("\n%d",*p);
return 0;
}
Output
timeout: the monitored command dumped core sh: line 1: 95298 Segmentation fault timeout 10s main
POINTER ARITHMETICS IN C
The pointer operations are summarized in the figure
Priority operation (precedence)
• When working with C pointers, we must observe the following priority rules:
• The operators * and & have the same priority as the unary operators (the negation!, the incrementation
++, decrement--).
• In the same expression, the unary operators *, &,!, ++, - are evaluated from right to left.
• If a P pointer points to an X variable, then * P can be used wherever X can be written.
• The following expressions are equivalent:
• int X =10
int *P = &Y; For this code, below expressions are true

Expression Equivalent Expression

Y=*P+1 Y=X+1

*P=*P+10 X=X+10

*P+=2 X+=2
++X
++*P
X++
(*P)++

• In the latter case, parentheses are needed: as the unary operators * and ++ are evaluated from right to
left, without the parentheses the pointer P would be incremented, not the object on which P points.
• Below table shows the arithmetic and basic operation that can be used when dealing with C pointers

Operation Explanation

Assignment int *P1,*P2 P1=P2; P1 and P2 point to the


same integer variable

Incrementation and decrementation Int *P1; P1++;P1-- ;

Adding an offset (Constant) This allows the pointer to move N


elements in a table. The pointer will be
increased or decreased by N times the
number of byte (s) of the type of the
variable. P1+5;
CHAIN OF POINTERS
• A pointer is used to point to a memory location of a variable. Syntax:
• A pointer stores the address of a variable. // level-1 pointer declaration datatype *pointer;
• Similarly, a chain of pointers is when there are multiple levels of pointers. // level-2 pointer declaration datatype **pointer;
• Simplifying, a pointer points to address of a variable,
• Double-pointer points to a variable and so on.
// level-3 pointer declaration datatype ***pointer;
• This is called multiple indirections. .
• The level of the pointer depends on how many asterisks the pointer variable is preceded with at the time and so on
of declaration.
• As shown in the diagram, variable ‘a’ is a normal integer variable which stores integer value 10 and is
at location 2006. ‘ptr1’ is a pointer variable which points to integer variable ‘a’ and stores its location
i.e. 2006, as its value. Similarly ptr2 points to pointer variable ptr1 and ptr3 points at pointer variable
ptr2. As every pointer is directly or indirectly pointing to the variable ‘a’, they all have the same integer
value as variable ‘a’, i.e. 10
• Updating variable using chained pointer
• As we already know that a pointer points to address location of a variab le so when we access the value of pointer it’ll
point to the variable’s value.
• Now to update the value o f variab le, we can use any level of pointer as u ltimately every pointer is directly o r
indirectly pointing to that variable only.
• It’ll directly change the value present at the address location of variable.
#include <stdio.h>
int main()
{
int var = 10;
int *ptr1, **ptr2, ***ptr3;
ptr1 = &var;
ptr2 = &ptr1;
ptr3 = &ptr2;
printf("Before:\n");
printf("Value of var = %d\n", var);
printf("Value of var using level-1"" pointer = %d\n", *ptr1);
printf("Value of var using level-2"" pointer = %d\n", **ptr2); Before: Value of var = 10; Value of var using
printf("Value of var using level-3"" pointer = %d\n", ***ptr3);
// Updating var's value using level-3 pointer
level-1 pointer = 10; Value of var using level-2 • Level-N pointer can only be used to point level-(N-1)
***ptr3 = 35; pointer = 10; Value of var using level-3 pointer
// Printing values AFTER updation = 10;
pointer.
printf("After:\n"); After: Value of var = 35 Value of var using • Except for Level-1 pointer. The level-1 pointer will always
printf("Value of var = %d\n", var);
printf("Value of var using level-1"" pointer = %d\n", *ptr1); level-1 pointer = 35 Value of var using level-2 point to the variable.
printf("Value of var using level-2"" pointer = %d\n", **ptr2); pointer = 35 Value of var using level-3 pointer
printf("Value of var using level-3"" pointer = %d\n", ***ptr3); = 35
return 0;
}
POINTER TO AN ARRAY AND ARRAY OF POINTERS
POINTER TO AN ARRAY ARRAY OF POINTERS
• The way we have pointer to an integer or a pointer to a float we can have a pointer to an • “Array of pointers” is an array of the pointer variables.
array. • It is also known as pointer arrays.
• Pointer to an array is also known as array pointer. • Syntax:
• We are using the pointer to access the components of the array.
• int *var_name[array_size];
• Declaration of a pointer to an array is a little clumsy.
• For example the declaration int (*q)[4] means that q is a pointer to an array of 4 integers. • Declaration of an array of pointers:
• int a[3] = {3, 4, 5 }; int *ptr = a; • int *ptr[3];
• We have a pointer ptr that focuses to the 0th component of the array. We can likewise • We can make separate pointer variables which can point to the different values or we can
declare a pointer that can point to whole array rather than just a single component of the make one integer array of pointers that can point to all the values.
array. // C program to demonstrate example of array of pointers.
#include <stdio.h>
• Syntax: const int SIZE = 3;
• data type (*var name)[size of array]; void main()
{
• Declaration of the pointer to an array: int arr[] = { 1, 2, 3 };
• // pointer to an array of five numbers // we can make an integer pointer array to store the address of array elements
• int (* ptr)[5] = NULL; int i, *ptr[SIZE];
• The above declaration is the pointer to an array of five integers. for (i = 0; i < SIZE; i++) {
// assigning the address of integer. Output:
• We use parenthesis to pronounce pointer to an array. ptr[i] = &arr[i]; }
• Since subscript has higher priority than indirection, it is crucial to encase the indirection operator // printing values using pointer
Value of arr[0] = 1
and pointer name inside brackets. for (i = 0; i < SIZE; i++) { Value of arr[1] = 2
printf("Value of arr[%d] = %d\n", i, *ptr[i]); } Value of arr[2] = 3
main() }
{ • And the output is p: is pointer to 0th element of the array arr, while ptr is a pointer that points to the whole array arr.
int a[][4] ={ • 65500 65500 The base type of p is int while base type of ptr is ‘an array of 5 integers’.
5, 7, 5, 9, • 65502 65508 We know that the pointer arithmetic is performed relative to the base size, so if we write ptr++, then the
4, 6, 3, 1,
• To start with both p and q contain the same pointer ptr will be shifted forward by 20 bytes.
2, 9, 0, 6
}; address 65500. The following figure shows the pointer p and ptr. Darker arrow denotes pointer to an array.
int *p, int (*q)[4]; • However, p is an integer pointer and q is a
p=(int *)a; pointer to an array of 4 integers.
printf(“/n%u%u”,p,q); • Hence on incrementing p it points to the next
p++; integer
q++;
• Whereas on incrementing q starts pointing to
printf(“/n%u%u”,p,q);
} the next 1 D array of 4 integers.
• Pointer to an array is very useful while passing
a 2 D array to a function.
POINTER AND 1 D ARRAY
• Array elements arc always stored in contiguous memory locations.
• A pointer when incremented always points to an immediately next location of its type
• Pointers are used for storing address of dynamically allocated arrays and for arrays which are passed as arguments to functio ns. In other
contexts, arrays and pointer are two different things, see the following programs to justify this statement.
• Although array and pointer are different things, following properties of array make them look similar.
• Array name gives address of first element of array.
• Assigning any address to an array variable is not allowed.
• Array members are accessed using pointer arithmetic.
• Compiler uses pointer arithmetic to access array element.
• For example, an expression like “arr[i]” is treated as *(arr + i) by the compiler.
• That is why the expressions like *(arr + i) work for array arr, and expressions like ptr[i] also work for pointer ptr.
• Array parameters are always passed as pointers, even when we use square brackets.

Relation between Arrays and Pointers


Consider an array:
int arr[4];

In C programming, name of the array always points to address of the first element of an array.
• In the example, arr and &arr[0] points to the address of the first element.
• &arr[0] is equivalent to arr
• Since, the addresses of both are the same, the values of arr and &arr[0] are also the same.
• arr[0] is equivalent to *arr (value of an address of the pointer) Similarly,
• &arr[1] is equivalent to (arr + 1) AND, arr[1] is equivalent to *(arr + 1).
• &arr[2] is equivalent to (arr + 2) AND, arr[2] is equivalent to *(arr + 2).
• &arr[3] is equivalent to (arr + 3) AND, arr[3] is equivalent to *(arr + 3)...
• &arr[i] is equivalent to (arr + i) AND, arr[i] is equivalent to *(arr + i).
• In C, we can declare an array and can use pointer to alter the data of an array.
POINTERS AND 2D ARRAY
• In a two dimensional array, we can access each element by using two subscripts,
• where first subscript represents the row number and second subscript represents the column number.
• The elements of 2-D array can be accessed with the help of pointer notation also.
• Suppose arr is a 2-D array, we can access any element arr[i][j] of the array using the pointer expression *(*(arr + i) + j).
• Now we’ll see how this expression can be derived.
Let us take a two dimensional array arr[3][4]:int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
• Since memory in a computer is organized linearly.
• Hence it is not possible to store the 2-D array in rows and columns.
• The concept of rows and columns is only theoretical,
• Actually, a 2-D array is stored in row-major order i.e rows are placed next to each other.
• The following figure shows how the above 2-D array will be stored in memory.

• Each row can be considered as a 1-D array,


• so a two-dimensional array can be considered as a collection of one-dimensional arrays that are placed one after another.
• In other words, we can say that 2-D dimensional arrays that are placed one after another.
• So here arr is an array of 3 elements where each element is a 1-D array of 4 integers.
• We know that the name of an array is a constant pointer that points to 0th 1-D array and contains address 5000.
• Since arr is a ‘pointer to an array of 4 integers’, according to pointer arithmetic the expression arr + 1 will represent the address 5016 and expression arr + 2 will represent address 5032.
• So we can say that arr points to the 0th 1-D array, arr + 1 points to the 1st 1-D array and arr + 2 points to the 2nd 1-D array.
POINTERS AND 2D ARRAY
• In general we can write:
• arr + i Points to ith element of arr -> Points to ith 1-D array
• Since arr + i points to ith element of arr, on dereferencing it will get ith element of arr which is of course a 1-D array. Thus the expression *(arr + i) gives us the base
address of ith 1-D array.
• We know, the pointer expression *(arr + i) is equivalent to the subscript expression arr[i]. So *(arr + i) which is same as arr[i] gives us the base address of ith 1-D
array.

• In general we can write:


• *(arr + i) - arr[i] - Base address of ith 1-D array -> Points to 0th element of ith 1-D array
• Note: Both the expressions (arr + i) and *(arr + i) are pointers, but their base type are different. The base type of (arr + i) is ‘an array of 4 units’ while the base type of *(arr + i) or arr[i] is int.
•To access an individual element of our 2-D array, we should be able to access any jth element of ith 1-D array.
•Since the base type of *(arr + i) is int and it contains the address of 0th element of ith 1-D array, we can get the addresses of subsequent elements in the ith 1-D array by adding integer values to *(arr +
i).
•For example *(arr + i) + 1 will represent the address of 1st element of 1stelement of ith 1-D array and *(arr+i)+2 will represent the address of 2nd element of ith 1-D array.
•Similarly *(arr + i) + j will represent the address of jth element of ith 1-D array. On dereferencing this expression we can get the jth element of the ith 1-D array.
C DYNAMIC MEMORY ALLOCATION
• Since C is a structured language, it has some fixed rules for programming.
• One of it includes changing the size of an array. An array is collection of items stored at continuous memory locations.
• In this slide, you'll learn to dynamically allocate memory in your C program using standard library functions: malloc(), calloc(), free() and realloc().
• As you know, an array is a collection of a fixed number of values. Once the size of an array is declared, you cannot change it.
• Sometimes the size of the array you declared may be insufficient.
• To solve this issue, you can allocate memory manually during run-time. This is known as dynamic memory allocation in C programming.
• To allocate memory dynamically, library functions are malloc(), calloc(), realloc() and free() are used.
• These functions are defined in the <stdlib.h> header file.
ADVANTAGES, DISADVANTAGES OF POINTERS
• Advantages of Pointers in C
• Pointers are useful for accessing memory locations.
• Pointers provide an efficient way for accessing the elements of an array structure.
• Pointers are used for dynamic memory allocation as well as deallocation.
• Pointers are used to form complex data structures such as linked list, graph, tree, etc.
• Disadvantages of Pointers in C
• Pointers are a little complex to understand.
• Pointers can lead to various errors such as segmentation faults or can access a memory location which is not required at all.
• If an incorrect value is provided to a pointer, it may cause memory corruption.
• Pointers are also responsible for memory leakage.
• Pointers are comparatively slower than that of the variables.
• Programmers find it very difficult to work with the pointers; therefore it is programmer's responsibility to manipulate a
pointer carefully.
• Summary
• A pointer is nothing but a memory location where data is stored.
• A pointer is used to access the memory location.
• There are various types of pointers such as a null pointer, wild pointer, void pointer and other types of pointers.
• Pointers can be used with array and string to access elements more efficiently.
• We can create function pointers to invoke a function dynamically.
• Arithmetic operations can be done on a pointer which is known as pointer arithmetic.
• Pointers can also point to function which make it easy to call different functions in the case of defining an array of pointers.
• When you want to deal different variable data type, you can use a typecast void pointer.

You might also like