UNIT 5
ARRAYS
Introduction
In programming, it is often required to store and process a set of data items of the
same type such as marks of students, salaries of employees, or temperatures recorded every
day. Using separate variables for each value is inefficient.
For example, the marks of 100 students or sales figures for 12 months. Using individual
variables such as "int mark1, mark2, …, mark100;" would make programs bulky and difficult
to manage. With arrays: "int marks[100];" All values can now be accessed and processed
collectively.
Hence, C language provides a way to store a large collection of data values of the same data
type under one variable name. This group of elements is known as an Array.
Definition: An array is a collection of variables of the same data type that are referred to by a
common name and can be individually accessed by using a subscript or an index number.
Types of Arrays
C supports the following types of arrays:
1. One-dimensional arrays
2. Two-dimensional arrays
3. Multi-dimensional arrays
1. One-dimensional arrays
A group of items with one common variable name, and from which individual item is
accessed by only one subscript is called a single-subscripted variable or a one-dimensional
array. Arrays must be declared before their use.
Syntax:
data-type varname[size];
The data-type is any valid data type in C, which decides the type of an array.
The size indicates the maximum number of elements that can be stored in the array.
Examples: int n[5];
This statement creates an array named n, which can hold five integer values at the maximum.
That is, it allocates 10Bytes(in 16bit systems) or 20Bytes(in 32bit/64bit systems) of
contiguous memory space to array n, as follows.
n[0] n[1] n[2] n[3] n[4]
The Valid subscripts are 0 to 4. In, an array index always stats with 0 and ends with
maximum number of elements minus 1.
Initialization of Arrays
Once the necessary memory locations are created for the array, the next step is to put
values into the array created. This process is known as initialization. This is done by using the
array subscripts as shown below:
Syntax: arrayname[subscript] = value;
Example:
n[0] = 40;
n[1] = 53;
n[2] = 65;
n[3] = 72;
n[4] = 85;
We can also initialize arrays automatically, in the same way as ordinary variables when they
are declared as shown below.
Syntax: data-type arrayname[size] = { list of values };
The initializer is a list of values separated by commas and surrounded by curly braces.
Example:
int n[5] = {40,53,65,72,85};
If the number of initialization values is less than the size of array, then only that many
elements will be initialized. The remaining elements left un-initialized.
Example:
int n[5] = {40,53}; here, only n[0] = 40 and n[1] = 53 are initialized remaining n[2],
n[3] and n[4] are left un-initialized.
The size may be omitted. In such cases the compiler allocates enough memory space for all
elements specified in the list.
Example:
int count[] = {1,2,3,4};
Character arrays may also be initialized in the same way.
The statement: char title[] = {'J', 'a', 'v', 'a'};
declares the title to be an array of four characters, initialized with the string 'Java'.
Processing an Array
We can use looping statements to read, write and manipulate arrays.
Example:
for(i=0; i<n; i++)
{
printf("Input array element %d", i+1);
scanf("%d", &a[i]);
}
a[i] refers to the ith element's address.
Example: C program that demonstrates how to create an array, read its elements from the
user, and display them.
#include <stdio.h>
int main()
{
int n, i, arr[50]; // Declare array of size 50 (max 50 elements)
// Input: number of elements
printf("Enter number of elements (max 50): ");
scanf("%d", &n);
// Input: array elements
printf("Enter %d elements:\n", n);
for(i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
// Display array elements
printf("\nThe elements in the array are:\n");
for(i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
Two Dimensional Arrays
A two-dimensional array in C is like a table with rows and columns. It stores data in a
grid, allowing you to organize values in both directions. You declare it using two index
values: one for rows and one for columns.
Syntax:
datatype arrayname[rows size] [columnsize];
Example: int marks[3][3]; creates a table with 3 rows and 3 columns.
Col 0 Col 1 Col 2
Row 0 1 2 3
Row 1 4 5 6
Row 2 7 8 9
1 marks[0][0]
2 marks[0][1]
3 marks[0][2]
4 marks[1][0]
5 marks[1][1]
6 marks[1][2]
7 marks[2][0]
8 marks[2][1]
9 marks[2][2]
Each element is accessed using marks[row][column], for example, marks[1][2]. refers to
element present in the second row and third column(6).
Initialization of two-dimensional arrays
Like the one-dimensional arrays, two-dimensional arrays may be initialized by following
their declaration with a list of initial values enclosed in braces.
For example:
int marks[3][3] = {1,2,3,4,5,6,7,8,9};
Initializes the elements as:
marks[0][0] = 1 marks[0][1] = 2 marks[0][2] = 3
marks[1][0] = 4 marks[1][1] = 5 marks[1][2] = 6
marks[2][0] = 7 marks[2][1] = 8 marks[2][2] = 9
The initialization may be done row by row. The above Statement is equivalent to:
int marks[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
Each row elements are surrounded by braces. Note that each row is a one dimensional array.
So, two dimensional array is treated as an array of one dimensional arrays.
The above initialization can also be written by omitting the row dimension as given below:
int marks[3][3] = {1,2,3,4,5,6,7,8,9};
Example: Program to find the sum of all elements of a two-dimensional array
#include <stdio.h>
int main()
{
int i, j, rows, cols;
int arr[10][10]; // Declare a 2D array with max size 10x10
int sum = 0;
// Input: size of the matrix
printf("Enter number of rows and columns: ");
scanf("%d %d", &rows, &cols);
// Input: elements of the matrix
printf("Enter elements of the matrix:\n");
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
scanf("%d", &arr[i][j]);
}
}
// Display the matrix
printf("\nThe entered matrix is:\n");
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
printf("%4d", arr[i][j]);
}
printf("\n");
}
// Calculate sum of all elements
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
sum += arr[i][j];
}
}
// Display result
printf("\nSum of all elements in the matrix = %d\n", sum);
return 0;
}
Multi-dimensional Arrays
The arrays with three or more dimensions is called multi-dimensional array.
Syntax:
datatype arrayname[d1][d2]...[dn];
where d is the dimension of the ith dimension.
Examples:
1. float a[3][4][3]; -> is a three dimensional array.
2. int table[2][3][4][2]; -> is a four-dimensional array
Consider the initialization of three-dimensional array.
int table[2][3][4][2] = { { {1,2,3},{4,5,6},{7,8,9} }
{ {9,8,7},{6,5,4},{3,2,1} }
{ {1,2,3},{4,5,6},{7,8,9} }
}
Example: Program to demonstrate a 3-Dimensional Array
#include <stdio.h>
int main()
{
int i, j, k;
int arr[2][2][2] = { { {1, 2}, {3, 4} }, { {5, 6}, {7, 8} } };
printf("Elements of the 3D array are:\n");
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; j++)
{
for(k = 0; k < 2; k++)
{
printf("arr[%d][%d][%d] = %d\n", i, j, k, arr[i][j][k]);
}
}
}
return 0;
}
Function Declaration or Function Prototype or Signature of the Function:
Tells the compiler about the function name, return type, and parameters (the number and type of arguments). It has no body, whereas the
definition includes the body. Parameter names in the declaration are optional.
When a function is defined after main or after a calling function, a prior declaration is needed so the compiler knows how to type‑check
the call, commonly provided via a header file (for library functions).
Sytax:
return_type function_name(parameter list);
Eg:
int add(int, int);
Function Call
To use a function, you will have to call that function to perform the defined task. When a program calls a function, the program control
transferred to the called function. When function-ending closing brace is reached or return statement is executed, it returns program control back
to the calling function.
Eg:
int result;
result = add(10, 20);
/* Program to demonstrate function declaration, definition, and call */
#include <stdio.h>
// Function declaration (prototype)
int add(int, int);
int main()
{
int a, b, result;
// Input two numbers
printf("Enter two numbers: ");
scanf("%d %d", &a, &b);
// Function call
result = add(a, b);
// Display the result
printf("Sum = %d\n", result);
return 0;
}
// Function definition
int add(int x, int y)
{
int sum;
sum = x + y;
return sum;
}
Passing Parameters to Functions
When we call a function, sometimes we need to send data from the calling function (usually main()) to the called function. This process
is known as passing parameters to a function.
The variables or values used in the function call are called Actual Arguments, while the variables defined in the function definition are
called Formal Arguments.
Actual Arguments: The data or variables passed while calling the function.
Formal Arguments: The variables declared in the function header that receive the values of the actual arguments.
In C, parameters can be passed in two ways:
1. Call by Value
2. Call by Reference
1. Call by Value
In Call by Value, the actual value of the argument is copied into the formal parameter. Any change made inside the function affects only
the copy — the original variable in calling function remains unchanged.
Example:
#include <stdio.h>
void modify(int x); // Function declaration
int main()
{
int num = 10; // Actual argument
modify(num); // Passing by value
printf("Value of num after function call = %d\n", num);
return 0;
}
// Function definition with formal argument
void modify(int x)
{
x = x + 5; // Changes only local copy
printf("Value inside function = %d\n", x);
}
Output:
Value inside function = 15
Value of num after function call = 10
Here, num is the actual argument, and x is the formal argument.
2. Call by Reference
In Call by Reference, instead of passing the value, we pass the address of the variable. The formal parameter becomes a pointer that directly
refers to the original variable in memory. Hence, any modification made inside the function also affects the original variable.
Example:
#include <stdio.h>
void modify(int *x); // Function declaration
int main()
{
int num = 10; // Actual argument
modify(&num); // Passing address of variable
printf("Value of num after function call = %d\n", num);
return 0;
}
// Function definition with pointer (formal argument)
void modify(int *x)
{
*x = *x + 5; // Changes actual variable
printf("Value inside function = %d\n", *x);
}
Output:
Value inside function = 15
Value of num after function call = 15
Here, &num is the actual argument (address) and *x is the formal argument (pointer) that accesses the original data.
Types of User-Defined Functions
In C, a user-defined function is a function created by the programmer to perform a specific task. Functions can be classified based on
whether they take arguments and whether they return a value to the calling function.
There are four main types of user-defined functions in C:
1. Function with No Arguments and No Return Value
These functions neither take any input (arguments) nor return any value. They perform a task and display results directly inside the
function.
Example:
#include <stdio.h>
// Function declaration
void display();
int main()
{
display(); // Function call
return 0;
}
// Function definition
void display()
{
printf("Hello! This is a simple function.\n");
}
Here, display() doesn’t take input or return anything.
2. Function with Arguments but No Return Value
Such functions take values from the calling function but don’t return any result. They usually perform operations like displaying or
processing data.
Example:
#include <stdio.h>
// Function declaration
void greet(char name[]);
int main()
{
greet("Ravi"); // Function call with argument
return 0;
}
// Function definition
void greet(char name[])
{
printf("Hello, %s!\n", name);
}
main() passes the string "Ravi" to greet(), which displays a message. No value is returned.
3. Function with No Arguments but Returns a Value
These functions don’t take input, but they send a result back to the calling function using the return statement.
Example:
#include <stdio.h>
// Function declaration
int getNumber();
int main()
{
int n = getNumber(); // Function call receives return value
printf("You entered: %d\n", n);
return 0;
}
// Function definition
int getNumber()
{
int num;
printf("Enter a number: ");
scanf("%d", &num);
return num; // Returned to main()
}
getNumber() reads a number and returns it to main() using the return statement.
4. Function with Arguments and Return Value
This is the most common type. It takes input values (arguments), processes them, and returns a result to the calling function.
Example:
#include <stdio.h>
// Function declaration
int add(int, int);
int main()
{
int a = 5, b = 10, sum;
sum = add(a, b); // Function call with arguments
printf("Sum = %d\n", sum);
return 0;
}
// Function definition
int add(int x, int y)
{
return x + y;
}
main() sends two numbers to add(), which returns their sum back to main().
Recursion
Recursion is a process where a function calls itself either directly or indirectly to solve a problem. In simple terms, a recursive function
keeps calling itself with smaller inputs until a stopping condition (base case) is met. Without a base condition, the recursion would continue
forever and cause a stack overflow.
Recursion is useful for problems that can be broken down into smaller subproblems of the same type — such as calculating a factorial,
generating Fibonacci series, or finding the sum of digits.
Example: Factorial of a Number Using Recursion
#include <stdio.h>
// Function declaration
int fact(int n);
int main()
{
int num;
printf("Enter a number: ");
scanf("%d", &num);
printf("Factorial of %d = %d\n", num, fact(num));
return 0;
}
// Recursive function definition
int fact(int n)
{
if (n == 0 || n == 1)
return 1; // Base condition
else
return n * fact(n - 1); // Recursive call
}
How It Works
If you enter num = 4, the calls happen like this:
fact(4)
→ 4 * fact(3)
→ 4 * 3 * fact(2)
→ 4 * 3 * 2 * fact(1)
→ 4 * 3 * 2 * 1 = 24
Each call waits until the next call finishes, then multiplies and returns the result.
Local and Global Variables
In C, variables can be declared inside or outside functions, and their location determines their scope (where they can be used) and
lifetime (how long they exist).
Local Variables
A local variable is declared inside a function or block. It can be used only within that function, and it is created when the function starts
and destroyed when the function ends.
Example:
void display()
{
int x = 10; // Local variable
printf("%d", x);
}
Here, x exists only inside display().
Global Variables
A global variable is declared outside all functions, usually at the top of the program. It can be accessed by all functions in the program.
Example:
#include <stdio.h>
int x = 20; // Global variable
void show()
{
printf("%d", x);
}
int main()
{
show();
return 0;
}
Here, x can be used in both main() and show().
When Local and Global Variables Have the Same Name
If a local variable has the same name as a global variable, the local variable takes priority within that function. The global variable
remains hidden inside that function.
Example:
#include <stdio.h>
int x = 10; // Global variable
int main()
{
int x = 5; // Local variable (same name)
printf("%d", x); // Prints 5 (local hides global)
return 0;
}
So, in this example, the local x shadows (overrides) the global x only inside main().
To avoid confusion, it’s best to use different variable names for global and local variables.
Structures and Unions
Structure:
A structure in C is a user-defined data type that allows grouping of variables of different data types (heterogeneous elements) under a
single name. In contrast, arrays can only hold homogeneous elements (all of the same data type).
Declaring a Structure:
Syntax:
struct struct_tag
{
data_type member1;
data_type member2;
…
data_type membern;
};
To create a structure, use the keyword struct followed by the struct_tag(structure name) and its members inside curly braces { }. The
struct_tag(structure name) is any valid identifier in C. Each variable inside a structure is called a member or field or elements. All members are
stored in contiguous memory, but each has its own storage space.
Example:
struct student
{
int rollno;
char name[30];
float marks;
};
Here, student is the name of the structure. It can hold three values — one integer, one string, and one float.
Structure Variable Declaration:
Structure declaration does not tell the compiler to reserve any space in memory. It defines the 'form' of the structure. After defining a
structure, memory is actually allocated when structure variables are declared. Once a structure is defined, we can create variables of that type
either:
1. Separately, after defining the structure:
Syntax:
struct struct_tag variable1, variable2, ... varaiblen;
Example:
struct student s1, s2;
2. Immediately, at the time of structure definition:
Syntax:
struct struct_tag
{
data_type member1;
data_type member2;
.
.
data_type membern;
}variable1, variable2, ... varaiblen;
Example:
struct student
{
int rollno;
char name[30];
float marks;
} s1, s2;
Each variable (like s1, s2) will contain its own set of rollno, name, and marks.
Or even:
struct
{
int rollno;
char name[30];
float marks;
} s1, s2;
Note: “If you define a structure without a structure tag (name) and only declare variables in that same statement, you cannot create more
variables of that type later because the type is anonymous and has no name to refer to.”
Accessing Structure Elements:
Structure members are accessed using the dot (.) operator also known as the member access operator or period operator.
Syntax:
[Link]
Example:
[Link] = 1;
Note: “There should be no spaces between structure variable, period operator, and member name.”
Initializing Structure Members:
After defining a structure, we can assign initial values to its members. This process is called initializing structure members.
Initialization at the Time of Declaration
You can assign values to all members when you declare the structure variable.
Example:
#include <stdio.h>
struct student
{
int rollno;
char name[20];
float marks;
};
struct student s1 = {101, “Ravi”, 89.5};
it is same as.
#include <stdio.h>
struct student
{
int rollno;
char name[20];
float marks;
}struct student s1 = {101, “Ravi”, 89.5};
Note:”The order of values should match the order of members in the structure definition.”
Assigning Values After Declaration
If you don’t initialize at declaration, you can assign values later using the dot (.) operator.
Example:
struct student s4;
[Link] = 104;
strcpy([Link], “Suresh”);
[Link] = 84.0;
Nesting of Structure:
A structure can contain another structure as a member or a structure variable as a member. This is called a nested structure. It helps
organize complex information more clearly.
Example:
struct date
{
int day, month, year;
};
struct student
{
int rollno;
char name[20];
struct date dob; // Nested structure
};
Accessing members of nested structures uses multiple dots:
[Link] = 12;
[Link] = 8;
[Link] = 2005;
Array of Structures
Sometimes, we need to store information of multiple records — for example, marks of several students or details of several employees.
Instead of declaring many separate structure variables, we can declare an array of structures.
Example:
struct Student s[100];
Each element in the array is itself a structure. All elements of this array are stored in adjacent memory locations (contiguous storage).
#include <stdio.h>
struct student
{
int rollno;
float marks;
};
int main()
{
struct student s[3];
int i;
for(i = 0; i < 3; i++)
{
printf("Enter roll no and marks for student %d: ", i+1);
scanf("%d %f", &s[i].rollno, &s[i].marks);
}
printf("\nStudent Details:\n");
for(i = 0; i < 3; i++)
{
printf("Roll No: %d\tMarks: %.2f\n", s[i].rollno, s[i].marks);
}
return 0;
}
Memory Allocation
Each member in a structure occupies its own memory space. The total size of a structure is the sum of all its members’ sizes.
For example:
struct test
{
int a;
float b;
char c;
};
If int = 4 bytes, float = 4 bytes, and char = 1 byte, then total size ≈ 9 bytes (or more due to padding by compiler).
Advantages of Structures
Allows grouping of different data types logically.
Makes complex data (like student or employee records) easier to handle.
Improves readability and program organization.
Union
A union is a user-defined data type (like a structure) that groups different data members under one name. Unlike a structure, where each
member has its own separate memory, in a union all members share a single common memory area.
Declaring and Using a Union:
To create a union, use the keyword union followed by the union_tag (union name) and its members inside curly braces { }. The union tag
is any valid identifier in C. Each variable declared inside a union is called a member or field or element.
Syntax:
union union_tag
{
data_type member1;
data_type member2;
...
data_type membern;
};
The memory size of a union is automatically set to be equal to the size of its largest member, so that any member can fit into that space.
Since the same memory is shared, only one member can hold a valid value at a time — assigning a new value to one member will overwrite the
previous one.
Example: Declaration, variable creation, assignment, and access
#include <stdio.h>
#include <string.h>
union Data
{
int i;
float f;
char str[10];
};
int main()
{
union Data d; // union variable
d.i = 100; // store integer
printf("i = %d\n", d.i);
d.f = 12.5f; // now store float (overwrites shared memory)
printf("f = %.2f\n", d.f);
strcpy([Link], "C-Prog"); // now store string (overwrites again)
printf("str = %s\n", [Link]);
return 0;
}
Note: “Because all members share the same memory, after you assign to [Link], the previous values in d.i and d.f are no longer reliable.”
Size of a Union
The size of a union is equal to the size of its largest member (plus any padding).
For example, if int is 4 bytes, float is 4 bytes, and char str[10] is 10 bytes, then:
printf("sizeof(union Data) = %zu\n", sizeof(union Data)); // typically 10 (or more due to padding).
Difference Between Structure and Union
Feature Structure (struct) Union (union)
Memory allocation Each member gets its own storage. One shared storage for all members.
Approximately the sum of sizes of all members (with
Size Size of the largest member (with padding).
padding).
Simultaneous
All members can hold valid values at the same time. Only one member holds a valid value at a time.
values
When you need to store one of many alternatives, saving
Use case When you need to keep and use many fields together.
memory.
Must manage carefully—writing one member invalidates
Data safety Safer—members don’t overwrite each other.
others.