Birla Institute of Technology & Science, Pilani
Second Semester 2025-2026, Computer Programming [CS F111]
Lab #9
Objectives
1. Pointers in C
2. Pointers arithmetic, Pointer and Functions
3. Pointers and Arrays
4. Structures, Union and Enum in C
5. Introduction to Linked Lists
9.0 Introduction to Pointers
Pointers are variables that hold address of another variable of same data type. Pointers are one of the
most distinct and exciting features of C language. It provides power and flexibility to the language.
Although pointer may appear little confusing and complicated in the beginning, but it is a powerful tool
and handy to use once its mastered.
Benefit of using pointers
• Pointers are more efficient in handling Array and Structure.
• Pointer allows references to function and thereby helps in passing of function as arguments to other
function.
• It reduces length and the program execution time.
• It allows C to support dynamic memory management.
Whenever a variable is declared, system will allocate a location to that variable in the memory, to hold
value. This location will have its own address number.
Let us assume that system has allocated memory location 80F (Hexa decimal representation of memory
address) for a variable a.
int a = 10 ;
We can access the value 10 by either using the variable name a or the address 80F. Since the memory
addresses are simply numbers they can be assigned to some other variable. The variable that holds
memory address are called pointer variables. A pointer variable is therefore nothing but a variable that
contains an address, which is a location of another variable. Value of pointer variable will be stored in
another memory location.
Declaring and initializing a pointer variable:
datatype * identifier ;
int *a;
The meaning of the above statement is that a is a pointer variable that holds address in which integer
data is stored.
Note: a itself is not an integer
Example 1: Write a program to declare pointer variables that point to float data, character data.
Initialize them with appropriate variables. Print the addresses stored and size of memory used by these
pointer variables.
Unlike the variable the pointer variables also will have junk/garbage values. They have to be initialized
before using.
For example:
int a=10;
int *ptra;
ptra=&a; //This statement assigns the pointer address where a is
stored .
*ptra=20; // This statement assign 20 to the memory location pointed by ptra
Note: & is the address operator also called as reference operator and * is called as deference operator
9.1 Pointers and functions
There are two ways of passing parameters to functions
[Link] by value
[Link] by reference
Example 2: Demonstrate the implementation of call by value and reference for a program that swaps
two input numbers.
pass by value pass by reference
#include<stdio.h> #include<stdio.h>
void swap(int num1, int num2); void swap(int *num1, int
*num2);
int main() {
int main() {
int x, y;
int x, y;
printf("\nEnter two numbers
: "); printf("\nEnter two numbers
: ");
scanf("%d%d",&x,&y);
scanf("%d%d",&x,&y);
printf("\nBefore Swaping x =
%d and y = %d", x, y); printf("\nBefore Swaping x =
%d and y = %d", x, y);
swap(x, y); // Function Call
- Pass By Reference swap(&x, &y); // Function
Call - Pass By Reference
printf("\nAfter Swaping x =
%d and y = %d", x, y); printf("\nAfter Swaping x =
%d and y = %d", x, y);
return 0;
return 0;
}
}
void swap(int num1, int num2) {
void swap(int *num1, int *num2)
int temp; {
temp = num1; int temp;
num1 = num2; temp = *num1;
num2 = temp; *num1 = *num2;
} *num2 = temp;
Enter two numbers : 2 3 Enter two numbers : 2 3
Before Swapping x = 2 and y = 3 Before Swapping x = 2 and y = 3
After Swaping x = 2 and y = 3 After Swaping x = 3 and y = 2
Conclusion from above example
1. When call by value is used a local copy of the variable is made in the function and the scope those
variables are within the function.
2. When call by reference is used the address of the variables in the main are sent and the function has
pointers refereeing to the sent address hence any change to the content pointed by pointers are
permanent.
9.2 Pointer Arithmetic
A pointer in c is an address, which is a numeric value. Therefore, you can perform arithmetic operations
on a pointer just as you can on a numeric value. There are four arithmetic operators that can be used on
pointers: ++, --, +, and –
To understand pointer arithmetic, let us consider that ptr is an integer pointer which points to the
address 1000. Assuming 32-bit integers, let us perform the following arithmetic operation on the pointer
ptr++
After the above operation, the ptr will point to the location 1004 because each time ptr is incremented,
it will point to the next integer location which is 4 bytes next to the current location. This operation will
move the pointer to the next memory location without impacting the actual value at the memory
location.
The address computation is as follows when ptr++ is evaluated:
ptr = ptr + 1 * sizeof(int)
= 1000 + 1 * 4 = 1004
If ptr points to a character whose address is 1000, then the above operation will point to the location
1001 because the next character will be available at 1001.
Example 3: Incrementing and decrementing a Pointer
int arr[] = {10, 100, 1000};
int *ptr1,*ptr2;
ptr1 = arr; /*here arr is an array and implicilty is a pointer
hence & is ignored in case of arrays */
ptr1++; /*assuming that the starting address of the array is 1000
this step results in 1004 hence ptr now points to 1004*/
ptr1--; /*since the pointer was pointing to 1004 this step results
in 1000 hence ptr now points to 1000*/
ptr2 = ptr1; //ptr2 will now point to 1000 memory location
if(ptr1==ptr2) //Comparing two pointers
printf(“both pointers are pointing to the same location”);
9.3 Pointers and arrays
Arrays are closely related to pointers in C programming but the important difference between them is
that, a pointer variable can take different addresses as value whereas, in case of array it is fixed. This is
demonstrated by the following example:
Example 4:
#include <stdio.h>
int main(){
char c[4];
int i;
for(i=0;i<4;++i){
printf("Address of c[%d]=%x\n",i,&c[i]);
}
return 0;
}
Address of c[0]=28ff44
Address of c[1]=28ff45
Address of c[2]=28ff46
Address of c[3]=28ff47
Notice, that there is equal difference (difference of 1 byte) between any two consecutive elements of
array.
Note: You may get different address of an array.
Relation between Arrays and Pointers
Consider and array:
int arr[4];
Relation between arrays and pointers
In arrays of C programming, name of the array always points to the first element of an array. Here,
address of first element of an array is &arr[0]. Also, arr represents the address of the pointer where it is
pointing. Hence, &arr[0] is equivalent to arr.
Also, value inside the address &arr[0] and address arr are equal. Value in address &arr[0] is arr[0] and
value in address arr is *arr. Hence, arr[0] is equivalent to *arr.
Similarly,
&a[1] is equivalent to (a+1) AND, a[1] is equivalent to *(a+1).
&a[2] is equivalent to (a+2) AND, a[2] is equivalent to *(a+2).
&a[3] is equivalent to (a+1) AND, a[3] is equivalent to *(a+3).
.
.
&a[i] is equivalent to (a+i) AND, a[i] is equivalent to *(a+i).
In C, you can declare an array and can use pointer to alter the data of an array.
Example 5: Write a C program to find the sum of six numbers with arrays and pointers
//Program to find the sum of six numbers with arrays and pointers.
#include <stdio.h>
int main(){
int i,class[6],sum=0;
printf("Enter 6 numbers:\n");
for(i=0;i<6;++i){
scanf("%d",(class+i)); // (class+i) is equivalent to &class[i]
sum += *(class+i); // *(class+i) is equivalent to class[i]
}
printf("Sum=%d",sum);
return 0;
}
Output
Enter 6 numbers:
2
3
4
5
3
4
Sum=21
9.4 Structures
A structure allows you to group one or more variables that may be of different data
types into one. It can contain any valid data type like int, char, float, array, pointers
and even structures. A variable in the structure is called a structure member.
Structures help us build compact user defined data types.
Declaring a Structure
struct keyword is used to define a structure as follows,
struct struct_name {
structure member ;
} ;
The following example defines a person structure which contains a persons first name, last name,
and
age.
struct struct_name {
char first[20];
char last [20];
int age;
} ;
Instead of defining a structure we can define independent variables for first name, last name, and
age. However creating and managing variables to manipulate the information of 100 or 1000 uses
is both confusing and tedious.
Note that the above code only defines a structure person. However, it does not create
any variable of type person. We can declare a structure variable as follows:
Declare structure variables together with the structure definition.
struct struct_name {
char first[20];
char last [20];
int age;
} person1, person2, person3;
typedef structure can be used to omit the keyword struct while declaring a structure variable.
typedef struct struct_name {
char first[20];
char last [20];
int age;
} person;
. . .
person p1 , p2 ;
Accessing Member Variables
Dot operator ‘.’ between the structure name and member to access a structure
member.
person p1 ;
scanf(”%s%s”,&[Link],&[Link]);
printf( ”%s %s”, [Link], [Link]) ;
Array and Structure
We can create an array of structure data types as follows:
person p1[10];
strcpy(p1[0].first, ”Shyam”);
strcpy(p1[0].last, ”Rao”) ;
Pointers and Structures
The address of a structure variable can be stored in a pointer variable, just like the
address of any other type of variable. There are two ways to access the member
variables while using pointers on structure variables:
person ∗p1 ;
p1=(person∗) malloc(sizeof(person));
(∗p1).age = 21 ;
p1−>age =22;
‘− >’ operator is the most preferred way to access the member variables.
9.5 Union
Like structure, union is a user defined data type. In union, all members share the same
memory location (i.e. Unions only allocate enough space to store the largest member
variable, and all fields are stored at the same space.). Thus, only one variable can be
used at any instant of time. For example in the following C program, both x and y share
the same location. If we change x, we can see the changes being reflected in y.
#include <stdio.h>
typedef union test { int x , y ; } T;
int main ()
{
T t ;
t.x = 2 ;
printf(”After making x=2: \n x=%, y=%d\n\n”, t.x, t.y);
t.y = 10 ;
printf(”After making Y=10 : \ n x=%d, y=%d\n\n”, t.x, t.y) ;
return 0 ;
}
Unions are useful when the type of data being passed through functions is unknown,
using a union which contains all possible data types can remedy this problem.
The usage of unions are similar to that of structures. Hence, all the things discussed
above for structures are valid for unions too.
9.6 Enum
Enumeration (or enum) is a user defined data type in C. It is mainly used to assign names
to integral constants, the names make a program easy to read and maintain.
Declaring an Enumeration
There are two different types of enumerations
declarations: Named type:
enum state {START, STOP, PAUSE};
Unnamed type:
enum {ZERO, ONE};
Values may be assigned to specific enum value names. Any names without assigned values will
get one higher than the previous entry. If the first name does not have an assigned value, it
gets the value of zero. It is even legal to assign the same value to more than one name.
enum Errors {
NONE=0, // Redundant. The first one would be zero anyway
MINOR1=100, MINOR2, MINOR3, // 100 , 101 , and 102
MAJOR1=1000 , MAJOR2, DIVIDE BY ZERO=1000} ; // 1000 , 1001 , and 1000 again
9.7 INTRODUCTION TO LINKED LIST
Like arrays, Linked List is a linear data structure. Unlike arrays, linked list elements are not stored at
contiguous location; the elements are linked using pointers.
Why Linked List?
Arrays can be used to store linear data of similar types, but arrays have following limitations.
1) The size of the arrays is fixed: So we must know the upper limit on the number of elements in
advance. Also, generally, the allocated memory is equal to the upper limit irrespective of the usage.
2) Inserting a new element in an array of elements is expensive, because room has to be created for the
new elements and to create room existing elements have to shifted. For example, in a system if we
maintain a sorted list of IDs in an array id[].
id[] = [1000, 1010, 1050, 2000, 2040].
And if we want to insert a new ID 1005, then to maintain the sorted order, we have to move all the
elements after 1000 (excluding 1000). Deletion is also expensive with arrays until unless some special
techniques are used. For example, to delete 1010 in id[], everything after 1010 has to be moved.
Advantages over arrays
Dynamic size, Ease of insertion/deletion
Drawbacks:
1. Random access is not allowed. We have to access elements sequentially starting from the first
node. So we cannot do binary search with linked lists.
2. Extra memory space for a pointer is required with each element of the list.
Representation in C
A linked list is represented by a pointer to the first node of the linked list. The first node is called head. If
the linked list is empty, then value of head is NULL. Each node in a list consists of at least two parts:
(a) data
(b) pointer to the next node
In C, we can represent a node using structures. Below is an example of a linked list node with an integer
data.
struct node
{
int data;
struct node *next;
};
First Simple Linked List in C
Let us create a simple linked list with 3 nodes.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
// Program to create a simple linked list with 3 nodes
int main()
{
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
// allocate 3 nodes in the heap
head = (struct node*)malloc(sizeof(struct node));
second = (struct node*)malloc(sizeof(struct node));
third = (struct node*)malloc(sizeof(struct node));
/* Three blocks have been allocated dynamically.
We have pointers to these three blocks as first, second and third
head second third
| | |
| | |
+---+-----+ +----+----+ +----+----+
| # | # | | # | # | | # | # |
+---+-----+ +----+----+ +----+----+
# represents any random value.
Data is random because we haven’t assigned anything yet */
head->data = 1; //assign data in first node
head->next = second; // Link first node with the second node
/* data has been assigned to data part of first block (block
pointed by head). And next pointer of first block points to
second. So they both are linked.
head second third
| | |
| | |
+---+---+ +----+----+ +-----+----+
| 1 | o----->| # | # | | # | # |
+---+---+ +----+----+ +-----+----+
*/
second->data = 2; //assign data to second node
second->next = third;
/* data has been assigned to data part of second block (block pointed by
second). And next pointer of the second block points to third block.
So all three blocks are linked.
head second third
| | |
| | |
+---+---+ +---+---+ +----+----+
| 1 | o----->| 2 | o-----> | # | # |
+---+---+ +---+---+ +----+----+ */
third->data = 3; //assign data to third node
third->next = NULL;
/* data has been assigned to data part of third block (block pointed
by third). And next pointer of the third block is made NULL to indicate
that the linked list is terminated here.
We have the linked list ready.
head
|
|
+---+---+ +---+---+ +----+------+
| 1 | o----->| 2 | o-----> | 3 | NULL |
+---+---+ +---+---+ +----+------+
Note that only head is sufficient to represent the whole list. We can
traverse the complete list by following next pointers. */
return 0;
}
******