C Pointers:: Unit-4 Pointers & User Defined Data Types
C Pointers:: Unit-4 Pointers & User Defined Data Types
C Pointers:
The pointer in C language is a variable which stores the address of another variable. This
variable can be of type int, char, array, function, or any other pointer. The size of the
pointer depends on the architecture. However, in 32-bit architecture the size of a pointer is
2 bytes.
Consider the following example to define a pointer which stores the address of an integer.
int n = 10;
int* p = &n; // Variable p of type pointer is pointing to the address of the variable n
of type integer.
Declaring a pointer:
The pointer in c language can be declared using * (asterisk symbol). It is also known as
indirection pointer used to dereference a pointer.
Pointer Example
An example of using pointers to print the address and value is given below.
As you can see in the above figure, pointer variable stores the address of number variable,
i.e., fff4. The value of number variable is 50. But the address of pointer variable p is aaa3.
By the help of * (indirection operator), we can print the value of pointer variable p.
Let's see the pointer example as explained for the above figure.
#include<stdio.h>
int main(){
int number=50;
int *p;
p=&number; //stores the address of number variable
printf("Address of p variable is %x \n",p);
// p contains the address of the number therefore printing p gives the address of n
umber.
printf("Value of p variable is %d \n",*p);
// As we know that * is used to dereference a pointer therefore if we print *p, we
will get the value stored at the address contained by p.
return 0;
}
Output:
Pointer to array:
int arr[10];
int *p[10]=&arr; // Variable p of type pointer is pointing to the address of an integ
er array arr.
Pointer to a function:
Pointer to structure:
struct st {
int i;
float f;
}ref;
struct st *p = &ref;
Advantages of pointer:
1) Pointer reduces the code and improves the performance, it is used to retrieving
strings, trees, etc. and used with arrays, structures, and functions.
Example
#include<stdio.h>
int main()
{
int x=4;
int y;
int *ptr;
ptr=&x;
y=*ptr;
*ptr=5;
printf("The value of x is : %d",x);
printf("\n The value of y is : %d",y);
return 0;
}
Output:
The value of x is 5
The value of y is 4
The Address Operator in C is a special unary operator that returns the address of a
variable. It is denoted as the Ampersand Symbol ( & ). This operator returns an integer
value which is the address of its operand in the memory. We can use the address
operator (&) with any kind of variables, array, strings, functions, and even pointers.
Syntax
&operand
Address Operator in C
Example to demonstrate how to use the address operator in our C program.
#include <stdio.h>
int main()
{
// declaring a variable
int x = 100;
Output:
Here variable x was defined and initialized with the value 100 in the program above. We
retrieved the address of this variable x by using the address operator (&) as the prefix
and printed it using printf() function.
Generally, the value returned by the address operator is stored in the pointer variable and
then the pointer is dereferenced to get the value stored in that address.
There are some entities in C for which we cannot use the address operator i.e. we cannot
get the address of those entities in C. Some of them are:
1. Register Variables
2. Bit Fields
3. Literals
4. Expressions
Pointer Arithmetic in C:
We can perform arithmetic operations on the pointers like addition, subtraction, etc.
However, as we know that pointer contains the address, the result of an arithmetic
operation performed on the pointer will also be a pointer if the other operand is of type
integer. In pointer-from-pointer subtraction, the result will be an integer value. Following
arithmetic operations are possible on the pointer in C language:
o Increment
o Decrement
o Addition
o Subtraction
o Comparison
Incrementing Pointer in C:
o If we increment a pointer by 1, the pointer will start pointing to the immediate next
location. This is somewhat different from the general arithmetic since the value of
the pointer will get increased by the size of the data type to which the pointer is
pointing.
o We can traverse an array by using the increment operation on a pointer which will
keep pointing to every element of the array, perform some operation on that, and
update itself in a loop.
32-bit
64-bit
#include<stdio.h>
int main(){
int number=50;
int *p;//pointer to int
p=&number;//stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p+1;
printf("After increment: Address of p variable is %u \n",p); // in our case, p will get incre
mented by 4 bytes.
return 0;
}
Output
#include<stdio.h>
void main ()
{
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;
int i;
printf("printing array elements...\n");
for(i = 0; i< 5; i++)
{
printf("%d ",*(p+i));
}
}
Output
32-bit
64-bit
#include <stdio.h>
void main(){
int number=50;
int *p;//pointer to int
p=&number;//stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p-1;
printf("After decrement: Address of p variable is %u \n",p); // P will now point to the imm
idiate previous location.
}
Output
C Pointer Addition:
We can add a value to the pointer variable. The formula of adding value to pointer is given
below:
32-bit
For 32-bit int variable, it will add 2 * number.
64-bit
Let's see the example of adding value to pointer variable on 64-bit architecture.
#include<stdio.h>
int main(){
int number=50;
int *p;//pointer to int
p=&number;//stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p+3; //adding 3 to pointer variable
printf("After adding 3: Address of p variable is %u \n",p);
return 0;
}
Output
As you can see, the address of p is 3214864300. But after adding 3 with p variable, it is
3214864312, i.e., 4*3=12 increment. Since we are using 64-bit architecture, it increments 12. But
if we were using 32-bit architecture, it was incrementing to 6 only, i.e., 2*3=6. As integer value
occupies 2-byte memory in 32-bit OS.
C Pointer Subtraction:
Like pointer addition, we can subtract a value from the pointer variable. Subtracting any
number from a pointer will give an address. The formula of subtracting value from the
pointer variable is given below:
64-bit
Let's see the example of subtracting value from the pointer variable on 64-bit architecture.
#include<stdio.h>
int main(){
int number=50;
int *p;//pointer to int
p=&number;//stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p-3; //subtracting 3 from pointer variable
printf("After subtracting 3: Address of p variable is %u \n",p);
return 0;
}
Output
You can see after subtracting 3 from the pointer variable, it is 12 (4*3) less than the
previous address value.
However, instead of subtracting a number, we can also subtract an address from another
address (pointer). This will result in a number. It will not be a simple arithmetic operation,
but it will follow the following rule.
Addr2 -Addr1 = (Subtra of two addr)/size of data type which pointer points
#include<stdio.h>
void main ()
{
int i = 100;
int *p = &i;
int *temp;
temp = p;
p = p + 3;
printf("Pointer Subtraction: %d - %d = %d",p, temp, p-temp);
}
Output
Pointer Comparisons:
We can compare pointers if they are pointing to the same array. Relational operators >,
>=, <, <=, ==, !=. can be used to compare two pointers. Pointers can’t be multiplied or
divided.
Example
#include <stdio.h>
int main() {
int *p2;
int *p1;
p2 = (int *)300;
p1 = (int *)200;
if(p1 > p2) {
printf("P1 is greater than p2");
} else {
printf("P2 is greater than p1");
}
return(0);
}
Output
P2 is greater than p1
Illegal arithmetic with pointers:
There are various operations which cannot be performed on pointers. Since, pointer stores
address hence we must ignore the operations which may lead to an illegal address, for
example, addition, and multiplication. A list of such operations is given below.
Dangling Pointers in C:
In the above figure, we can observe that the Pointer 3 is a dangling pointer. Pointer
1 and Pointer 2 are the pointers that point to the allocated objects, i.e., Object 1 and
Object 2, respectively. Pointer 3 is a dangling pointer as it points to the de-
allocated object.
When the variable goes out of the scope then the pointer pointing to the variable becomes
a dangling pointer.
#include<stdio.h>
int main()
{
char *str;
{
char a = ?A?;
str = &a;
}
// a falls out of scope
// str is now a dangling pointer
printf("%s", *str);
}
Sizeof() operator in C:
The sizeof() operator is commonly used in C. It determines the size of the expression or
the data type specified in the number of char-sized storage units. The sizeof() operator
contains a single operand which can be either an expression or a data typecast where the
cast is data type enclosed within parenthesis. The data type cannot only be primitive data
types such as integer or floating data types, but it can also be pointer data types and
compound data types such as unions and structs.
Mainly, programs know the storage size of the primitive data types. Though the storage
size of the data type is constant, it varies when implemented in different platforms. For
example, we dynamically allocate the array space by using sizeof() operator:
int *ptr=malloc(10*sizeof(int));
In the above example, we use the sizeof() operator, which is applied to the cast of type int.
We use malloc() function to allocate the memory and returns the pointer which is pointing
to this allocated memory. The memory space is equal to the number of bytes occupied by
the int data type and multiplied by 10.
Note:
The output can vary on different machines such as on 32-bit operating system will show
different output, and the 64-bit operating system will show the different outputs of the
same data types.
The sizeof() operator behaves differently according to the type of the operand.
#include <stdio.h>
int main()
{
int x=89; // variable declaration.
printf("size of the variable x is %d", sizeof(x)); // Displaying the size of ?x? variable.
printf("\nsize of the integer data type is %d",sizeof(int)); //Displaying the size of integer
data type.
printf("\nsize of the character data type is %d",sizeof(char)); //Displaying the size of ch
aracter data type.
printf("\nsize of the floating data type is %d",sizeof(float)); //Displaying the size of floa
ting data type.
return 0;
}
In the above code, we are printing the size of different data types such as int, char, float
with the help of sizeof() operator.
Output
#include <stdio.h>
int main()
{
double i=78.0; //variable initialization.
float j=6.78; //variable initialization.
printf("size of (i+j) expression is : %d",sizeof(i+j)); //Displaying the size of the expressio
n (i+j).
return 0;
}
In the above code, we have created two variables 'i' and 'j' of type double and float
respectively, and then we print the size of the expression by using sizeof(i+j) operator.
Output
NULL Pointer in C:
The Null Pointer is the pointer that does not point to any location but NULL. According
to C11 standard:
“An integer constant expression with the value 0, or such an expression cast to type void
*, is called a null pointer constant. If a null pointer constant is converted to a pointer
type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a
pointer to any object or function.”
Syntax of Null Pointer Declaration in C
int main()
{
// declaring null pointer
int* ptr = NULL;
Output
An Array of Pointers in C:
Array:
If we want to include multiple elements in a program with the very same data type, we can
use an array. Let us assume that we are using a total of five integers in any program. There
are two different ways in which we can allocate memory to all of these integers:
Pointer:
The pointers in C point towards the variables present in a program. They hold the
addresses of the variables. The program will use these addresses to access the variables
and modify them. Here are the three crucial things that come into play when dealing with
pointers in C:
Array of Pointers:
When we want to point at multiple variables or memories of the same data type in a C
program, we use an array of pointers.
Let us assume that a total of five employees are working at a cheesecake factory. We can
store the employees’ names in the form of an array. Along with this, we also store the
names of employees working at the office, the library, and the shoe store.
Now, let us assume that once we read all the names of the employees randomly, we want
to sort all of the employees’ names working in the cheesecake factory. Sorting all the
employee names requires reading, swapping, and copying a lot of data. But since we have
stored all the employee names in groups/ arrays, we can directly refer to the array of
names of employees working at the cheesecake factory.
int *ary[55]
This one is an array of a total of 55 pointers. In simple words, this array is capable of
holding the addresses a total of 55 integer variables. Think of it like this- the ary[0] will
hold the address of one integer variable, then the ary[1] will hold the address of the other
integer variable, and so on.
Example
Let us take a look at a program that demonstrates how one can use an array of pointers in
C:
#include<stdio.h>
#define SIZE 10
int main()
int *arr[3];
arr[0] = &p;
arr[1] = &q;
arr[2] = &r;
printf(“For the Address = %d\t the Value would be = %d\n”, arr[i], *arr[i]);
return 0;
Output
The , struct keyword is used to define the structure. Let's see the syntax to define the
structure in c.
struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeberN;
};
struct employee
{ int id;
char name[20];
float salary;
};
The following image shows the memory allocation of the structure employee that is
defined in the above example.
Here, struct is the keyword; employee is the name of the structure; id, name,
and salary are the members or fields of the structure. Let's understand it by the diagram
given below:
C Structure Example
#include<stdio.h>
#include <string.h>
struct employee
{ int id;
char name[50];
}e1; //declaring e1 variable for structure
int main( )
{
//store first employee information
e1.id=101;
strcpy(e1.name, "Sekhar");//copying string into char array
//printing first employee information
printf( "employee 1 id : %d\n", e1.id);
printf( "employee 1 name : %s\n", e1.name);
return 0;
}
Output:
employee 1 id : 101
Union in C:
Union is a user-defined data type, but unlike structures, they share the same memory
location.
struct abc
int a;
char b;
The above code is the user-defined structure that consists of two members, i.e., 'a' of type
int and 'b' of type character. When we check the addresses of 'a' and 'b', we found that
their addresses are different. Therefore, we conclude that the members in the structure do
not share the same memory location.
When we define the union, then we found that union is defined in the same way as the
structure is defined but the difference is that union keyword is used for defining the union
data type, whereas the struct keyword is used for defining the structure. The union contains
the data members, i.e., 'a' and 'b', when we check the addresses of both the variables then
we found that both have the same addresses. It means that the union members share the
same memory location.
In union, members will share the memory location. If we try to make changes in any of the
member then it will be reflected to the other member as well. Let's understand this concept
through an example.
union abc
int a;
char b;
}var;
int main()
var.a = 66;
In the above code, union has two members, i.e., 'a' and 'b'. The 'var' is a variable of union
abc type. In the main() method, we assign the 66 to 'a' variable, so var.a will print 66 on
the screen. Since both 'a' and 'b' share the memory location, var.b will print 'B' (ascii code
of 66).
The size of the union is based on the size of the largest member of the union.
Let's understand through an example.
union abc{
int a;
};
int main()
return 0;
As we know, the size of int is 4 bytes, size of char is 1 byte, size of float is 4 bytes, and the
size of double is 8 bytes. Since the double variable occupies the largest memory among all
the four variables, so total 8 bytes will be allocated in the memory. Therefore, the output of
the above program would be 8 bytes.
We can access the members of the union through pointers by using the (->) arrow operator.
#include <stdio.h>
union abc
int a;
char b;
};
int main()
{
union abc *ptr; // pointer variable declaration
ptr = &var;
return 0;
In the above code, we have created a pointer variable, i.e., *ptr, that stores the address of var
variable. Now, ptr can access the variable 'a' by using the (->) operator. Hence the output of
the above code would be 90.
Accessing A user can access individual A user can access only one
Members members at a given time. member at a given time.
Value Altering Altering the values of a single When you alter the values of a
member does not affect the single member, it affects the
other members of a Structure. values of other members.