0% found this document useful (0 votes)
18 views

C Pointers:: Unit-4 Pointers & User Defined Data Types

Uploaded by

rishicse547
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)
18 views

C Pointers:: Unit-4 Pointers & User Defined Data Types

Uploaded by

rishicse547
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/ 27

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.

int *a; //pointer to int


char *c ; //pointer to char

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:

Address of number variable is fff4


Address of p variable is fff4
Value of p variable is 50

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:

void show (int);


void(*p)(int) = &display; // Pointer p is pointing to the address of 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.

2) We can return multiple values from a function using the pointer.

Dereferencing and Address of Operator:

Dereferencing is used to access or manipulate data contained in memory location pointed


to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer
variable, it refers to variable being pointed, so this is called dereferencing of pointers.
When we dereference a pointer, then the value of the variable pointed by this pointer will
be returned.

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

Address Operator & in C:

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

The address operator is generally used as a prefix to its operand:

&operand

where operand can be a variable, array, function, pointer, etc.

Address Operator in C
Example to demonstrate how to use the address operator in our C program.

// C program to illustrate the use of address operator

#include <stdio.h>
int main()
{
// declaring a variable
int x = 100;

// printing the address of the variable


printf("The address of x is %p", &x);
return 0;
}

Output:

The address of x is 0x7fffe8f5591c

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.

Note: The %p format specifier to print the address in hexadecimal form.

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.

Address Operator Incompitable Entities in C

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.

The Rule to increment the pointer is given below:

new_address= current_address + i * size_of(data type)

Where i is the number by which the pointer get increased.

32-bit

For 32-bit int variable, it will be incremented by 2 bytes.

64-bit

For 64-bit int variable, it will be incremented by 4 bytes.


Let's see the example of incrementing 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+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

Address of p variable is 3214864300


After increment: Address of p variable is 3214864304

Traversing an array by using pointer

#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

printing array elements...


1 2 3 4 5
Decrementing Pointer in C:

Like increment, we can decrement a pointer variable. If we decrement a pointer, it will


start pointing to the previous location. The formula of decrementing the pointer is given
below:

new_address= current_address - i * size_of(data type)

32-bit

For 32-bit int variable, it will be decremented by 2 bytes.

64-bit

For 64-bit int variable, it will be decremented by 4 bytes.

Let's see the example of decrementing pointer variable on 64-bit OS.

#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

Address of p variable is 3214864300


After decrement: Address of p variable is 3214864296

C Pointer Addition:

We can add a value to the pointer variable. The formula of adding value to pointer is given
below:

new_address= current_address + (number * size_of(data type))

32-bit
For 32-bit int variable, it will add 2 * number.

64-bit

For 64-bit int variable, it will add 4 * number.

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

Address of p variable is 3214864300


After adding 3: Address of p variable is 3214864312

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:

new_address= current_address - (number * size_of(data type))


32-bit

For 32-bit int variable, it will subtract 2 * number.

64-bit

For 64-bit int variable, it will subtract 4 * number.

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

Address of p variable is 3214864300


After subtracting 3: Address of p variable is 3214864288

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.

If two pointers are of the same type,

Addr2 -Addr1 = (Subtra of two addr)/size of data type which pointer points

Consider the following example to subtract one pointer from an another.

#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 Subtraction: 1030585080 - 1030585068 = 3

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.

o Address + Address = illegal


o Address * Address = illegal
o Address % Address = illegal
o Address / Address = illegal
o Address & Address = illegal
o Address ^ Address = illegal
o Address | Address = illegal
o ~Address = illegal

Dangling Pointers in C:

o The most common bugs related to pointers and memory management is


dangling/wild pointers. Sometimes the programmer fails to initialize the pointer
with a valid address, then this type of initialized pointer is known as a dangling
pointer in C.
o Dangling pointer occurs at the time of the object destruction when the object is
deleted or de-allocated from memory without modifying the value of the pointer. In
this case, the pointer is pointing to the memory, which is de-allocated. The dangling
pointer can point to the memory, which contains either the program code or the
code of the operating system. If we assign the value to this pointer, then it
overwrites the value of the program code or operating system instructions; in such
cases, the program will show the undesirable result or may even crash. If the
memory is re-allocated to some other process, then we dereference the dangling
pointer will cause the segmentation faults.
Let's observe the following examples.

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.

Need of sizeof() operator:

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.

o Operand is a data type


o Operand is an expression

When operand is a data type:

#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

When operand is an expression:

#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

size of (i+j) expression is : 8

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

type pointer_name = NULL;


type pointer_name = 0;
We just have to assign the NULL value. Strictly speaking, NULL expands to an
implementation-defined null pointer constant which is defined in many header files such
as “stdio.h”, “stddef.h”, “stdlib.h” etc.

Uses of NULL Pointer in C:

Following are some most common uses of the NULL pointer in C:


1. To initialize a pointer variable when that pointer variable hasn’t been assigned any
valid memory address yet.
2. To check for a null pointer before accessing any pointer variable. By doing so, we
can perform error handling in pointer-related code, e.g., dereference a pointer
variable only if it’s not NULL.
3. To pass a null pointer to a function argument when we don’t want to pass any valid
memory address.
4. A NULL pointer is used in data structures like trees, linked lists, etc. to indicate the
end.

Check if the pointer is NULL:

It is a valid operation in pointer arithmetic to check whether the pointer is NULL. We


just have to use isequal to operator ( == ) as shown below:
ptr == NULL;
The above equation will be true if the pointer is NULL, otherwise, it will be false.
Example

/ C NULL pointer demonstration


#include <stdio.h>

int main()
{
// declaring null pointer
int* ptr = NULL;

// derefencing only if the pointer have any value


if (ptr == NULL) {
printf("Pointer does not point to anything");
}
else {
printf("Value pointed by pointer: %d", *ptr);
}
return 0;
}

Output

Pointer does not point to anything

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:

 We can create five integers differently;


 We can create an array of all the different integers.
One of the huge advantages of using arrays is that it becomes very easy for a programmer
to access all the elements in the program easily. All the elements can be accessed in a
single run of a loop in the program.

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:

 Declaration of the pointer variable


 Initialisation of the pointer variable
 Using the pointer to access the variable

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.

Declaration of an Array of Pointers in C:


An array of pointers can be declared just like we declare the arrays of char, float, int, etc.
The syntax for declaring an array of pointers would be:

data_type *name_of_array [array_size];

Now, let us take a look at an example for the same,

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];

int p = 40, q = 60, r = 90, i;

arr[0] = &p;

arr[1] = &q;

arr[2] = &r;

for(i = 0; i < 3; i++)

printf(“For the Address = %d\t the Value would be = %d\n”, arr[i], *arr[i]);

return 0;

Output

For the Address = 387130656 the Value would be = 40

For the Address = 387130660 the Value would be = 60

For the Address = 387130664 the Value would be = 90


C Structure :

Structure in c is a user-defined data type that enables us to store the collection of


different data types. Each element of a structure is called a member.

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;
};

Let's see the example to define a structure for an entity employee in c.

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

Let's see a simple example of structure in C language.

#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

employee 1 name : Sekhar

Union in C:

Union can be defined as a user-defined data type which is a collection of different


variables of different data types in the same memory location. The union can also be
defined as many members, but only one member can contain a value at a particular point
in time.

Union is a user-defined data type, but unlike structures, they share the same memory
location.

Let's understand this through an example.

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;

printf("\n a = %d", var.a);

printf("\n b = %d", var.b);

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).

Deciding the size of the union

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;

char b; float c; double d;

};

int main()

printf("Size of union abc is %d", sizeof(union abc));

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.

Accessing members of union using pointers

We can access the members of the union through pointers by using the (->) arrow operator.

Let's understand through an example.

#include <stdio.h>

union abc

int a;

char b;

};

int main()

{
union abc *ptr; // pointer variable declaration

union abc var; var.a= 90;

ptr = &var;

printf("The value of a is : %d", ptr->a);

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.

Differences between structure and union:

Parameter Structure Union

Keyword A user can deploy the A user can deploy the


keyword struct to define a keyword union to define a
Structure. Union.

Internal The implementation of In the case of a Union, the


Implementation Structure in C occurs memory allocation occurs for
internally- because it contains only one member with the
separate memory locations largest size among all the input
allotted to every input member. variables. It shares the same
location among all these
members/objects.

Accessing A user can access individual A user can access only one
Members members at a given time. member at a given time.

Syntax The Syntax of declaring a The Syntax of declaring a Union


Structure in C is: in C is:
struct [structure name] union [union name]
{ {
type element_1; type element_1;
type element_2; type element_2;
. .
. .
} variable_1, variable_2, …; } variable_1, variable_2, …;

Size A Structure does not have a A Union does not have a


shared location for all of its separate location for every
members. It makes the size of a member in it. It makes its size
Structure to be greater than or equal to the size of the largest
equal to the sum of the size of member among all the data
its data members. members.

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.

Storage of In the case of a Structure, there In the case of a Union, there is


Value is a specific memory location an allocation of only one shared
for every input data member. memory for all the input data
Thus, it can store multiple members. Thus, it stores one
values of the various members. value at a time for all of its
members.

Initialization In the case of a Structure, a In the case of a Union, a user can


user can initialize multiple only initiate the first member at a
members at the same time. time.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy