0% found this document useful (0 votes)
3 views23 pages

Module 1 Arrays

The document provides an overview of data structures in C, focusing on arrays, pointers, and their initialization and usage. It covers one-dimensional, two-dimensional, and three-dimensional arrays, including their declaration, initialization methods, and element access. Additionally, it discusses pointers, including their declaration, initialization, and dereferencing, highlighting their importance in memory management and dynamic allocation.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views23 pages

Module 1 Arrays

The document provides an overview of data structures in C, focusing on arrays, pointers, and their initialization and usage. It covers one-dimensional, two-dimensional, and three-dimensional arrays, including their declaration, initialization methods, and element access. Additionally, it discusses pointers, including their declaration, initialization, and dereferencing, highlighting their importance in memory management and dynamic allocation.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 23

Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

Module-1 Arrays:1D,2D and multidimensional. Pointers: Definition and Concepts, Array of pointers, Structures and unions. Array of structures, pointer arrays,
pointer to structures. Passing pointer variable as parameter in functions Dynamic memory allocation: malloc(), calloc(), realloc() and free function. Introduction to
data structures and algorithms Text book 1 -Chapter-1.1-1.3 except Rational Numbers. Text Book 2, chapter-2

Arrays
1D, 2D and Multidimensional Arrays.

Array in C is one of the most used data structures in C programming. It is a simple and fast way of storing multiple values under a single name.

What is Array in C?

An array in C is a fixed-size collection of similar data items stored in contiguous memory locations. It can be used to store the collection of primitive data types such as

int, char, float, etc., and also derived and user-defined data types such as pointers, structures, etc.

C Array Declaration

In C, we have to declare the array like any other variable before using it. We can declare an array by specifying its name, the type of its elements, and the size of its

dimensions. When we declare an array in C, the compiler allocates the memory block of the specified size to the array name.

Syntax of Array Declaration

data_type array_name [size];

or

data_type array_name [size1] [size2]...[sizeN];

where N is the number of dimensions.

The C arrays are static in nature, i.e., they are allocated memory at the compile time.

C Array Initialization

Dr. Nataraju A B Page - 1


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

Initialization in C is the process to assign some initial value to the variable. When the array is declared or allocated memory, the elements of the array contain some

garbage value. So, we need to initialize the array to some meaningful value. There are multiple ways in which we can initialize an array in C.

1. Array Initialization with Declaration

In this method, we initialize the array along with its declaration. We use an initializer list to initialize multiple elements of the array. An initializer list is the list of

values enclosed within braces { } separated by comma.

data_type array_name [size] = {value1, value2, ... valueN};

2. Array Initialization with Declaration without Size

If we initialize an array using an initializer list, we can skip declaring the size of the array as the compiler can automatically deduce the size of the array in these cases.

The size of the array in these cases is equal to the number of elements present in the initializer list as the compiler can automatically deduce the size of the array.

data_type array_name[] = {1,2,3,4,5};

The size of the above arrays is 5 which is automatically deduced by the compiler.

3. Array Initialization after Declaration (Using Loops)

We initialize the array after the declaration by assigning the initial value to each element individually. We can use for loop, while loop, or do-while loop to assign the

value to each element of the array.

for (int i = 0; i < N; i++) {

array_name[i] = valuei;

Access Array Elements

We can access any element of an array in C using the array subscript operator [ ] and the index value i of the element.

array_name [index];

Dr. Nataraju A B Page - 2


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

One thing to note is that the indexing in the array always starts with 0, i.e., the first element is at index 0 and the last element is at N – 1 where N is the number of

elements in the array.

Update Array Element

We can update the value of an element at the given index i in a similar way to accessing an element by using the array subscript operator [ ] and assignment operator =.

array_name[i] = new_value;

C Array Traversal

Traversal is the process in which we visit every element of the data structure. For C array traversal, we use loops to iterate through each element of the array.

Array Traversal using for Loop

for (int i = 0; i < N; i++) {

array_name[i];

A one-dimensional array is a single list of elements, all of which share the same data type. A two-dimensional array is an array of arrays, a list of lists , or an array of

one-dimensional arrays .

Multidimensional arrays

A multi-dimensional array can be termed as an array of arrays that stores homogeneous data in tabular form. Data in multidimensional arrays is generally stored in row-

major order in the memory.

The general form of declaring N-dimensional arrays is shown below.

Dr. Nataraju A B Page - 3


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

Syntax:

data_type array_name[size1][size2]....[sizeN];

● data_type: Type of data to be stored in the array.

● array_name: Name of the array.

● size1, size2,…, sizeN: Size of each dimension.

Examples:

Two dimensional array: int two_d[10][20];

Three dimensional array: int three_d[10][20][30];

Size of Multidimensional Arrays:

The total number of elements that can be stored in a multidimensional array can be calculated by multiplying the size of all the dimensions.

For example:

● The array int x[10][20] can store total (10*20) = 200 elements.

● Similarly array int x[5][10][20] can store total (5*10*20) = 1000 elements.

To get the size of the array in bytes, we multiply the size of a single element with the total number of elements in the array.

For example:

● Size of array int x[10][20] = 10 * 20 * 4 = 800 bytes. (where int = 4 bytes)

● Similarly, size of int x[5][10][20] = 5 * 10 * 20 * 4 = 4000 bytes. (where int = 4 bytes)

The most commonly used forms of the multidimensional array are:

1. Two Dimensional Array

2. Three Dimensional Array

Two-Dimensional Array in C

A two-dimensional array or 2D array in C is the simplest form of the multidimensional array. We can visualize a two-dimensional array as an array of one-

dimensional arrays arranged one over another forming a table with ‘x’ rows and ‘y’ columns where the row number ranges from 0 to (x-1) and the column number

ranges from 0 to (y-1).

Dr. Nataraju A B Page - 4


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

Graphical Representation of Two-Dimensional Array of Size 3 x 3

Declaration of Two-Dimensional Array in C

The basic form of declaring a 2D array with x rows and y columns in C is shown below.

Syntax:

data_type array_name[x][y];

where,

● data_type: Type of data to be stored in each element.

● array_name: name of the array

● x: Number of rows.

● y: Number of columns.

We can declare a two-dimensional integer array say ‘x’ with 10 rows and 20 columns as:

Example:

int x[10][20];

Note: In this type of declaration, the array is allocated memory in the stack and the size of the array should be known at the compile time i.e. size of the array is fixed.

We can also create an array dynamically in C by using methods mentioned here.

Initialization of Two-Dimensional Arrays in C

The various ways in which a 2D array can be initialized are as follows:

1. Using Initializer List

2. Using Loops

Dr. Nataraju A B Page - 5


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

1. Initialization of 2D array using Initializer List

We can initialize a 2D array in C by using an initializer list as shown in the example below.

First Method:

int x[3][4] = {0, 1 ,2 ,3 ,4 , 5 , 6 , 7 , 8 , 9 , 10 , 11}

The above array has 3 rows and 4 columns. The elements in the braces from left to right are stored in the table also from left to right. The elements will be filled in the

array in order: the first 4 elements from the left will be filled in the first row, the next 4 elements in the second row, and so on.

Second Method (better):

int x[3][4] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};

This type of initialization makes use of nested braces. Each set of inner braces represents one row. In the above example, there is a total of three rows so there are three

sets of inner braces. The advantage of this method is that it is easier to understand.

Note: The number of elements in initializer list should always be less than or equal to the total number of elements in the array.

We can also declare the array without defining the size of the row if we are using list initialization. The compiler will automatically deduce the size of the array in this

case:

data_type array_name[][y] = {...} ;

It is still compulsory to define the number of columns.

2. Initialization of 2D array using Loops

We can use any C loop to initialize each member of a 2D array one by one as shown in the below example.

Example:

int x[3][4];

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

for(int j = 0; j < 4; j++){

x[i][j] = i + j;

This method is useful when the values of each element have some sequential relation.

Accessing Elements of Two-Dimensional Arrays in C

Elements in 2D arrays are accessed using row indexes and column indexes. Each element in a 2D array can be referred to by:

Syntax:

array_name[i][j]

Dr. Nataraju A B Page - 6


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

where,

● i: The row index.

● j: The column index.

Example:

int x[2][1];

The above example represents the element present in the third row and second column.

Note: In arrays, if the size of an array is N. Its index will be from 0 to N-1. Therefore, for row index 2 row number is 2+1 = 3. To output all the elements of a Two-

Dimensional array we can use nested for loops. We will require two ‘for‘ loops. One to traverse the rows and another to traverse columns.

Three-Dimensional Array in C

A Three Dimensional Array or 3D array in C is a collection of two-dimensional arrays. It can be visualized as multiple 2D arrays stacked on top of each other.

Graphical Representation of Three-Dimensional Array of Size 3 x 3 x 3

Declaration of Three-Dimensional Array in C

We can declare a 3D array with x 2D arrays each having y rows and z columns using the syntax shown below.

Syntax:

data_type array_name[x][y][z];

● data_type: Type of data to be stored in each element.

● array_name: name of the array

Dr. Nataraju A B Page - 7


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

● x: Number of 2D arrays.

● y: Number of rows in each 2D array.

● z: Number of columns in each 2D array.

Example:

int array[3][3][3];

Initialization of Three-Dimensional Array in C

Initialization in a 3D array is the same as that of 2D arrays. The difference is as the number of dimensions increases so the number of nested braces will also increase.

A 3D array in C can be initialized by using:

1. Initializer List

2. Loops

Initialization of 3D Array using Initializer List

Method 1:

int x[2][3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

11, 12, 13, 14, 15, 16, 17, 18, 19,

20, 21, 22, 23};

Method 2(Better):

int x[2][3][4] =

{ {0,1,2,3}, {4,5,6,7}, {8,9,10,11} },

{ {12,13,14,15}, {16,17,18,19}, {20,21,22,23} }

};

Again, just like the 2D arrays, we can also declare the 3D arrays without specifying the size of the first dimensions if we are using an initializer list for initialization.

The compiler will automatically deduce the size of the first dimension. But we still need to specify the rest of the dimensions.

data_type array_name[][y][z] = {....};

Initialization of 3D Array using Loops

It is also similar to that of a 2D array with one more nested loop for accessing one more dimension.

int x[2][3][4];

Dr. Nataraju A B Page - 8


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

for (int i=0; i<2; i++) {

for (int j=0; j<3; j++) {

for (int k=0; k<4; k++) {

x[i][j][k] = (some_value);

Accessing elements in Three-Dimensional Array in C

Accessing elements in 3D Arrays is also similar to that of 2D Arrays. The difference is we have to use three loops instead of two loops for one additional dimension in

3D Arrays.

Syntax:

array_name[x][y][z]

where,

● x: Index of 2D array.

● y: Index of that 2D array row.

● z: Index of that 2D array column.

// C program to print elements of Three-Dimensional Array

#include <stdio.h>

int main(void)

// initializing the 3-dimensional array

int x[2][3][2] = { { { 0, 1 }, { 2, 3 }, { 4, 5 } },

{ { 6, 7 }, { 8, 9 }, { 10, 11 } } };

// output each element's value

for (int i = 0; i < 2; ++i) {

for (int j = 0; j < 3; ++j) {

for (int k = 0; k < 2; ++k) {

printf("Element at x[%i][%i][%i] = %d\n", i,

j, k, x[i][j][k]);

return (0);

Pointers: Definition and Concepts, Array of pointers,

Pointers are one of the core components of the C programming language. A pointer can be used to store the memory address of other variables, functions, or even other

pointers. The use of pointers allows low-level memory access, dynamic memory allocation, and many other functionality in C.

How to Use Pointers?

The use of pointers in C can be divided into three steps:

Dr. Nataraju A B Page - 9


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

1. Pointer Declaration

2. Pointer Initialization

3. Pointer Dereferencing

1. Pointer Declaration

In pointer declaration, we only declare the pointer but do not initialize it. To declare a pointer, we use the ( * ) dereference operator before its name.

Example

int *ptr;

The pointer declared here will point to some random memory address as it is not initialized. Such pointers are called wild pointers.

2. Pointer Initialization

Pointer initialization is the process where we assign some initial value to the pointer variable. We generally use the ( & ) address of operator to get the memory address

of a variable and then store it in the pointer variable.

Example

int var = 10;

int * ptr;

ptr = &var;

We can also declare and initialize the pointer in a single step. This method is called pointer definition as the pointer is declared and initialized at the same time.

Example

int *ptr = &var;

Note: It is recommended that the pointers should always be initialized to some value before starting using it. Otherwise, it may lead to a number of errors.

3. Pointer Dereferencing

Dereferencing a pointer is the process of accessing the value stored in the memory address specified in the pointer. We use the same ( * ) dereferencing operator that we

used in the pointer declaration.

Dr. Nataraju A B Page - 10


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

C allows the programmer to reference the location of objects as well as the objects (that is, the contents of those locations) themselves. For example, if x is declared as

an integer, &x refers to the location that has been set aside to contain &x is called a pointer.

It is possible to declare a variable whose data type is a pointer and whose possible values are memory locations. For example, the declarations

int *pi;

float *pf;

char pc;

declare three pointer variables: pi is a pointer to an integer, pf is a pointer to a float number, and pc is a pointer to a character. The asterisk indicates that the values of

the variables being declared are pointers to values of the type specified in the declaration rather than objects of that type.

A pointer is like any other data type in C in many respects. The value of a pointer is a memory location in the way that the value of an integer is a number. Pointer

values can be assigned like any other values; For example, the statement pi = &x; assigns is a pointer to the integer x to the pointer variable pi.

The notation *pi in C refers to the integer at the location referenced by the pointer pi.

The statement x *pi; assigns the value of that integer to the integer variable x.

The conversion of pf from the type "pointer to a float number" to the type "pointer to an integer" can be made by writing

pi = (int *) pf;

where the cast (int *) converts the value of pf to the type "pointer to an int," or "int *"

The importance of each pointer being associated with a particular base type becomes clear in reviewing the arithmetic facilities that C provides for pointers.

If pi is a pointer to an integer, then pi+1 is the pointer to the integer immediately following the integer *pi in memory, pi-1 is the pointer to the integer

immediately preceding *pi. pi + 2 is the pointer to the second integer following *pi, and so on. For example, suppose that a particular machine uses byte addressing, an

integer requires four bytes, and the value of pi happens to be 100 (that is, p1 points to the integer *pi at location 100). Then the value of pi - 1 is 96, the value of pi + I

is 104 and the value of p1 + 2 is 108. The value of *(pi - 1) is the contents of the four bytes 96, 97, 98, and 99 interpreted as an integer; the value of *(pi + 1) is the

contents of bytes 104, 105, 106. and 107 interpreted as an integer; and the value of *(pi + 2) is the integer at bytes 108, 109. 110, and 111.

Similarly, if the value of the variable pc is 100 (recall that pc is a pointer to a character) and a character is one byte long, pc - 1 refers to location 99, pc + 1 to location

101, and pc + 2 to location 102. Thus, the result of pointer arithmetic in C depends on the base type of the pointer.

Note also the difference between *pi + 1, which refers to 1 added to the integer *pi. and *(pi + 1), which refers to the integer following the integer at location p1.

One area in which C pointers play a prominent role is in passing parameters to functions. Ordinarily, parameters are passed to a C function by value, that is. the values

being passed are copied into the parameters of the culled function at the time the function is invoked. If the value of a parameter is changed within the function, the

value in the calling program is not changed. For example, consider the following program segment and function (the line numbers are for reference only):
1. x = 5;

2. printf("%d\n, x);

3. funct(x);

4. printf('%d\n", x);

5. void funct(int y)

Dr. Nataraju A B Page - 11


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

6. {

7. ++y;

8. printf("%d\n", y);

9. } /* end funct */

Line 2 prints 5 and then line 3 invokes funct. The value of x, which is 5, is copied into y and funct begins execution. Line 8 then prints 6 and funct returns. However,

when line 7 increments the value of y, the value of x remains unchanged. Thus line 4 prints 5. x and y refer to two different variables that happen to have the same

value at the beginning of funct. y can change independently of x.

If we wish to use fund: to modify the value of x, we must pass the address of x as follows:
1. x=5;

2. printf("%d\n", x);

3. funct(&x);

4. printf('%d\n", x);

5. void funct(int *py)

6. {

7. ++(*py);

8. printf("%d\n", *py);

9. } /* end funct */

Line 2 again prints 5 and line 3 invokes funct. Now, however, the value passed is not the integer value of x, but the pointer value &x. This is the address of x. The

parameter of funct is no longer y of type int but py of type int*. (It is convenient to name pointer variables beginning with the letter p as a reminder to both the

programmer and the program reader that it is a pointer. However, this is not a requirement of the C language and we could have named the pointer parameter y.) Line 7

now increments the integer at location py. py, itself, however, is not changed and retains its initial value &x. Thus, py points to the integer x, so that when *py is

incremented, x is incremented. Line 8 prints 6 and when funct returns, line 4 also prints 6. Pointers are the mechanism used in C to allow a called function to modify

variables in a calling function.

Structures and unions. Array of structures, pointer arrays, pointer to structures.

A structure is a group of items in which each item is identified by its own identifier, each of which is known as a member of the structure. (In many other programming

languages, a structure is called a "record" and a member is called a "field." We may sometimes use these terms instead of "structure" or "member," although both

terms have different meanings in C.) For example, consider the following declaration:
struct {

char first[10);

char midinit;

char last[20];

} sname, ename;

This declaration creates two structure variables, sname, ename, each of which contains three members: first, midinit, and last. Two of the members are character

strings, and the third is a single character. Alternatively, we can assign a tag to the structure and then declare the variables by means of the tag. For example. consider

the following declaration that accomplishes the same thing as the declaration just given:

struct nametype{

char first[10);

char midinit;

char last[20];

};

struct nametype sname, ename;

This definition creates a structure tag name type containing three members, first, midinit, and last. Once a structure tag has been defined, variables sname and ename

may be declared. For maximum program clarity, it is recommended that a tag be declared for each structure and variables then be declared using the tag.

An alternative to using a structure tag is to use the typedef definition in C. For

Dr. Nataraju A B Page - 12


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

example
typedef struct {

char first[10];

char midinit;

char last[20];

} NAMETYPE;

says that the identifier NAMETYPE is synonymous with the preceding structure specifier wherever NAMETYPE occurs. We can then declare
NAMETYPE sname, ename;

to achieve the declarations of the structure variables sname and ename. Note that structure tags are conventionally written in lowercase but typedef specifiers are

written in uppercase in presenting C programs. typedef is sometimes used to achieve the flavor of an ADT specification within a C program.

Once a variable has been declared as structure, each member within that variable may be accessed by specifying the variable name and the item's member identifier

separated by a period. Thus, the statement

printf('%s', sname.first);

can be used to print the first name in the structure sname, and the statement

ename.midinit = ‘m’

can be used to set the middle initial in the structure ename to the letter ‘m’. If a member of a Structure is an array, a subscript may be used to access a particular element

of the array, as in

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

sname.last[i) = ename.last[i];

A member of a structure may be declared to be another structure. For example.

given the foregoing definition of nametvpe and the following definition of addrtvpe

struct addr.type {

char straddr[40];

char cty[10];

char state[3]; // Allow room for two char abbreviation and ‘\0’

char zip[6]; // // Allow room for five char abbreviation and ‘\0’

};

we may declare a new structure tag nmadtype by

struct nmadtype {

struct nametype name;

struct addrtype address;

};

If we declare two variables

struct nmadtype nmadl, nmad2;

the following are valid statements:

nmadl.name,midinit = nmad2.name.midinit;

nmad2.address.city[4] = nmadl.name.first[1];

for (i=1; I < 10; i+)

nmadl.name.first[i] = nmadl.name.first[i];

ANSI standard C allows the assignment of structures of the same type. For example.

the statement nmadl = n,nad2: is valid and equivalent to

nmadl.name = nmad2.name;

Dr. Nataraju A B Page - 13


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

nmadl.address = nmad2.address;

These, in turn, are equivalent to

for (1=0; i < 10; i.+)

nmadl.name.first[i) = nmad2.name.first[i];

nmadl.name.midinit =nmad2.name.midftdt;

for (1=0; i < 20; i++)

nmadl.name.last[i] = nmad2.name.last[i];

for (1=0; 1 < 40; i++)

nmadl.address.straddr[i] = nmad2.address.straddr(i];

for (1=0; i < 10; i-)

nmadl.address.city[i] = nmad2.address.city[i];

for (i=0; I < 2; i++)

nmadl.address.state[i] = nmad2.address.state[i];

for (1=0; 1 < 5; i++)

nmadl.address.zip[i] = nmad2.address.zip[i];

Array of Structures in C

When dealing with a large set of related data and different data types, organizing and managing it efficiently is crucial. In C programming, the combination of arrays

and structures i.e. array of structures provides a powerful tool for managing that.

Need for Array of Structures

Suppose we have 50 employees and we need to store the data of 50 employees. So, for that, we need to define 50 variables of struct Employee type and store the data

within that. However, declaring and handling the 50 variables is not an easy task. Let’s imagine a bigger scenario, like 1000 employees.

So, if we declare the variable this way, it’s not possible to handle this.

struct Employee emp1, emp2, emp3, .. . ... . .. ... emp1000;

For that, we can define an array whose data type will be struct Employee so that will be easily manageable.

Declaration of Array of Structures

struct structure_name array_name [number_of_elements];

Initialization of Array of Structures

We can initialize the array of structures in the following ways:

struct structure_name array_name [number_of_elements] = {

{element1_value1, element1_value2, ....},

{element2_value1, element2_value2, ....},

......

......

};

Dr. Nataraju A B Page - 14


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

The same initialization can also be done as:

struct structure_name array_name [number_of_elements] = {

element1_value1, element1_value2 ....,

element2_value1, element2_value2 .....

};

Passing pointer variable as parameter in functions

//This function swaps the value of two variables

#include <stdio.h>

void swap_call_val(int, int);

void swap_call_ref(int *, int *);

int main()

int a=1, b=2, c=3, d=4;

printf("\n In main(), a = %d and b = %d", a, b);

swap_call_val(a, b);

printf("\n In main(), a = %d and b = %d", a, b);

printf("\n\n In main(), c = %d and d = %d", c, d);

swap_call_ref(&c, &d);

printf("\n In main(), c = %d and d = %d", c, d);

return 0;

void swap_call_val(int a, int b) // example of pass by value

int temp;

temp = a;

a = b;

b = temp;

printf("\n In function (Call By Value Method) – a = %d and b = %d", a, b);

void swap_call_ref(int *c, int *d) // example of pass by pointer

int temp;

temp = *c;

*c = *d;

*d = temp;

printf("\n In function (Call By Reference Method) – c = %d and d = %d", *c, *d);

Output

Dr. Nataraju A B Page - 15


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

In main(), a = 1 and b = 2

In function (Call By Value Method) – a = 2 and b = 1

In main(), a = 1 and b = 2

In main(), c = 3 and d = 4

In function (Call By Reference Method) – c = 4 and d = 3

In main(), c = 4 and d = 3

In main(), a = 1 and b = 2

In function (Call By Value Method) – a = 2 and b = 1

In main(), a = 1 and b = 2

In main(), c = 3 and d = 4

In function (Call By Reference Method) – c = 4 and d = 3

In main(), c = 4 and d = 3

Unions in C

The Union is a user-defined data type in C language that can contain elements of the different data types just like structure. But unlike structures, all the members in the

C union are stored in the same memory location. Due to this, only one member can store data at the given instance.

// An example of union usage…

#include <stdio.h>

union myUnion {

int i;

float f;

char str[20];

};

int main() {

union myUnion u;

u.i = 10;

printf("Value of integer member: %d\n", u.i);

u.f = 3.14;

printf("Value of float member: %.2f\n", u.f);

strcpy(u.str, "Hello");

printf("Value of string member: %s\n", u.str);

printf("sizeof(myUnion): %d\n", sizeof(union myUnion));

return 0;

Value of integer member: 10

Value of float member: 3.14

Value of string member: Hello

sizeof(myUnion): 20 sizeof union is the max of size of the individual elements of union

Dynamic memory allocation: malloc(), calloc(), realloc() and free function.

If x is any object, &x is a pointer to x. If p is a pointer in C, *p is the object to which p points.

In C a pointer variable to an integer can be created by the declaration

int *p;

Dr. Nataraju A B Page - 16


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

Once a variable p has been declared as a pointer to a specific type of object, it must be possible to dynamically create an object of that specific type and assign its

address top.

This may be done in C by calling the standard library function rna/loc(size). mac dynamically allocates a portion of memory of size size and returns a pointer to an item

of type char. Consider the declarations

extern char *malloc();

int *pi;

float *pr;

The statements

pi = (int *) malloc(sizeof (int));

pr = (float *) malloc(sizeof (float));

dynamically create the integer variable *pi and the float variable *pr. These variables are called dynamic variables. In executing these Statements, the operator sizeof

returns. the size, in bytes, of its operand. This is used to maintain machine independence. malloc can then create an object of that size. Thus malloc(sizeof(int))

allocates storage for an integer, whereas malloc(sizeof(float)) allocates storage for a floating-point number. malloc also returns a pointer to the storage it allocates. This

pointer is to the first byte (for example, character) of that storage and is of type char *. To coerce this pointer so that it points to an integer or real, we use the cast

operator (int *) or (float *).

(The sizeof operator returns a value of type int, whereas the malloc function expects a parameter of type unsigned. To make the program "lint free" we should write

pi = (int *) malloc ((unsigned)(sizeof (int)));

However, the cast on the sizeof operator is often omitted.)

As an example of the use of pointers and the function malloc, consider the following

statements:
1. int *p , *q;

2. int x

3. p = (int *) malloc( sizeof (int) );

4. *p = 3;

5. q = p;

6. printf ("%d %d \n', *p , *q);

7. x = 7;

8. *q = x;

9. printf('%d %d \n", *p q);

10. p = (mt ) malloc (sizeof (int));

11. *p = 5;

12. printf("%d %d \n", *p, *q);

In line 3, an integer variable is created and its address is placed in n. Line 4 sets the value of that variable to 3. Line sets q to the address of that variable. The

assignment statement in line 5 is perfectly valid, since one pointer variable (q) is being assigned the value of another (p). Note that at this point, *p and *q refers to the

same variable. Line 6 therefore prints the contents of this variable (which is 3) twice.

Line 7 Sets the value of an integer variable, x. to 7. Line 8 changes the value of *q to the value of x. However, since p and q both point 'to the same variable, *p and *q

both have the value 7. This is illustrated in Figure 4.3.2b. Line 9 therefore prints the number 7 twice.

Line 10 creates a new integer variable and places its address in p. *p now refers to the newly created integer variable that has not yet been given a value. q has not been

changed; therefore the value of *q remains 7. Note that *p does not refer to a single, specific variable. Its value changes as the value of p changes. Line 11 sets the

value of this newly created variable to 5 and line 12 prints the values 5 and 7.

Dr. Nataraju A B Page - 17


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

The function free is used in C to free storage of a dynamically allocated variable.

The statement

free(p);

makes any future references to the variable *p illegal (unless, of course, a new value is assigned top by an assignment statement or by a call to malloc). Calling free(p)

makes the storage occupied by *p available for reuse, if necessary.

Since C is a structured language, it has some fixed rules for programming. One of them includes changing the size of an array. An array is a collection of items stored at

contiguous memory locations.

As can be seen, the length (size) of the array above is 9. But what if there is a requirement to change this length (size)? For example,

● If there is a situation where only 5 elements are needed to be entered in this array. In this case, the remaining 4 indices are just wasting memory in this

array. So there is a requirement to lessen the length (size) of the array from 9 to 5.

● Take another situation. In this, there is an array of 9 elements with all 9 indices filled. But there is a need to enter 3 more elements in this array. In this

case, 3 indices more are required. So the length (size) of the array needs to be changed from 9 to 12.

This procedure is referred to as Dynamic Memory Allocation in C.

Therefore, C Dynamic Memory Allocation can be defined as a procedure in which the size of a data structure (like Array) is changed during the runtime.

C provides some functions to achieve these tasks. There are 4 library functions provided by C defined under <stdlib.h> header file to facilitate dynamic memory

allocation in C programming. They are:

1. malloc()

2. calloc()

3. free()

4. realloc()

Let’s look at each of them in greater detail.

C malloc() method
The “malloc” or “memory allocation” method in C is used to dynamically allocate a single large block of memory with the specified size. It returns a pointer of type

void which can be cast into a pointer of any form. It doesn’t Initialize memory at execution time so that it has initialized each block with the default garbage value

initially.

Dr. Nataraju A B Page - 18


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

Syntax of malloc() in C

ptr = (cast-type*) malloc(byte-size)

For Example:

ptr = (int*) malloc(100 * sizeof(int));

Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory. And, the pointer ptr holds the address of the first byte in the allocated memory.

If space is insufficient, allocation fails and returns a NULL pointer.

C calloc() method
1. “calloc” or “contiguous allocation” method in C is used to dynamically allocate the specified number of blocks of memory of the specified type. it is

very much similar to malloc() but has two different points and these are:

2. It initializes each block with a default value ‘0’.

3. It has two parameters or arguments as compare to malloc().

Syntax of calloc() in C

ptr = (cast-type*)calloc(n, element-size);

here, n is the no. of elements and element-size is the size of each element.

For Example:

Dr. Nataraju A B Page - 19


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

ptr = (float*) calloc(25, sizeof(float));

This statement allocates contiguous space in memory for 25 elements each with the size of the float.

If space is insufficient, allocation fails and returns a NULL pointer.

C free() method
“free” method in C is used to dynamically de-allocate the memory. The memory allocated using functions malloc() and calloc() is not de-allocated

on their own. Hence the free() method is used, whenever the dynamic memory allocation takes place. It helps to reduce wastage of memory by

freeing it.

Syntax of free() in C

free(ptr);

Introduction to data structures and algorithms


We have already learnt the basics of programming in C in the previous chapter and know how to write, debug, and run simple programs in C language. Our

aim has been to design good programs,

where a good program is defined as a program that


● runs correctly
● is easy to read and understand
● is easy to debug and
● is easy to modify.

A program should undoubtedly give correct results, but along with that it should also run

efficiently. A program is said to be efficient when it executes in minimum time and with minimum memory space. In order to write efficient programs we need

to apply certain data management concepts.

Dr. Nataraju A B Page - 20


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

Data structure is a crucial part of data management and in this book it will be our prime concern. A data structure is basically a group of data elements that

are put together under one name, and which defines a particular way of storing and organizing data in a computer so that it can be used efficiently.

Data structures are used in almost every program or software system. Some common examples of data structures are arrays, linked lists, queues, stacks,

binary trees, and hash tables. Data structures are widely applied in the following areas:
● Compiler design
● Operating system
● Statistical analysis package
● DBMS
● Numerical analysis
● Simulation
● Artificial intelligence
● Graphics

CLASSIFICATION OF DATA STRUCTURES


Data structures are generally categorized into two classes: primitive and non-primitive data structures.

Primitive and Non-primitive Data Structures


Primitive data structures are the fundamental data types which are supported by a programming language. Some basic data types are integer, real,

character, and boolean. The terms ‘data type’, ‘basic data type’, and ‘primitive data type’ are often used interchangeably.

Non-primitive data structures are those data structures which are created using primitive data structures. Examples of such data structures include linked

lists, stacks, trees, and graphs. Non-primitive data structures can further be classified into two categories: linear and non-linear data structures.

Linear and Non-linear Structures


If the elements of a data structure are stored in a linear or sequential order, then it is a linear data structure. Examples include arrays, linked lists, stacks, and

queues. Linear data structures can be represented in memory in two different ways. One way is to have a linear relationship between elements by means of

sequential memory locations. The other way is to have a linear relationship between elements by means of links.

However, if the elements of a data structure are not stored in a sequential order, then it is a non-linear data structure. The relationship of adjacency is not

maintained between elements of a non-linear data structure. Examples include trees and graphs.

OPERATIONS ON DATA STRUCTURES


This section discusses the different operations that can be performed on the various data structures previously mentioned.
● Traversing It means to access each data item exactly once so that it can be processed. For example, to print the names of all the students in a

class.
● Searching It is used to find the location of one or more data items that satisfy the given constraint. Such a data item may or may not be present in

the given collection of data items. For example, to find the names of all the students who secured 100 marks in mathematics.
● Inserting It is used to add new data items to the given list of data items. For example, to add the details of a new student who has recently joined

the course.
● Deleting It means to remove (delete) a particular data item from the given collection of data items. For example, to delete the name of a student

who has left the course.


● Sorting Data items can be arranged in some order like ascending order or descending order depending on the type of application. For example,

arranging the names of students in a class in an alphabetical order, or calculating the top three winners by arranging the participants’ scores in descending

order and then extracting the top three.


● Merging Lists of two sorted data items can be combined to form a single list of sorted data items.

Many times, two or more operations are applied simultaneously in a given situation. For example, if we want to delete the details of a student whose name is

X, then we first have to search the list of students to find whether the record of X exists or not and if it exists then at which location, so that the details can be

deleted from that particular location.

ALGORITHMS
The typical definition of algorithm is ‘a formally defined procedure for performing some

Dr. Nataraju A B Page - 21


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

calculation’. If a procedure is formally defined, then it can be implemented using a formal language, and such a language is known as a programming language.

In general terms, an algorithm provides a blueprint to write a program to solve a particular problem. It is considered to be an effective procedure for solving a

problem in finite number of steps. That is, a well-defined algorithm always provides an answer and is guaranteed to terminate.

Algorithms are mainly used to achieve software reuse. Once we have an idea or a blueprint of a solution, we can implement it in any high-level language like C,

C++, or Java.

An algorithm is basically a set of instructions that solve a problem. It is not uncommon to have multiple algorithms to tackle the same problem, but the choice

of a particular algorithm must depend on the time and space complexity of the algorithm.

DIFFERENT APPROACHES TO DESIGNING AN ALGORITHM


Algorithms are used to manipulate the data contained in data structures. When working with data structures, algorithms are used to perform operations on

the stored data.

A complex algorithm is often divided into smaller units called modules. This process of dividing an algorithm into modules is called modularization. The key

advantages of modularization are as follows:


● Σ It makes the complex algorithm simpler to design and implement.
● Σ Each module can be designed independently. While designing one module, the details of other modules can be ignored, thereby enhancing

clarity in design which in turn simplifies implementation, debugging, testing, documenting, and maintenance of the overall algorithm.

There are two main approaches to design an algorithm—top-down approach and bottom-up approach,

Top-down approach A top-down design approach starts by dividing the complex algorithm into one or more modules. These modules can further be

decomposed into one or more sub-modules, and this process of decomposition is iterated until the desired level of module complexity is achieved. Top-down

design method is a form of stepwise refinement where we begin with the topmost module and incrementally add modules that it calls.

Therefore, in a top-down approach, we start from an abstract design and then at each step, this design is refined into more concrete levels until a level is

reached that requires no further refinement.

Bottom-up approach A bottom-up approach is just the reverse of top-down approach. In the bottom-up design, we start with designing the most basic or

concrete modules and then proceed towards designing higher level modules. The higher level modules are implemented by using the operations performed

by lower level modules. Thus, in this approach sub-modules are grouped together to form a higher level module. All the higher level modules are clubbed

together to form even higher level modules. This process is repeated until the design of the complete algorithm is obtained.

CONTROL STRUCTURES USED IN ALGORITHMS

An algorithm has a finite number of steps. Some steps may involve decision-making and repetition. Broadly speaking, an algorithm may employ

one of the following control structures: (a) sequence, (b) decision, and (c) repetition.

Sequence

Dr. Nataraju A B Page - 22


Data Structures using C [BEC405D] Dept of ECE, ACIT, Bangalore

By sequence, we mean that each step of an algorithm is executed in a specified order. Let us write an algorithm to add two numbers. This

algorithm performs the steps in a purely sequential order, as shown in Fig. 2.10.

Decision

Decision statements are used when the execution of a process depends on the outcome of some condition. For example, if x = y, then print EQUAL.

So the general form of IF construct can be given as:

IF condition Then process

A condition in this context is any statement that may evaluate to either a true value or a false value.

In the above example, a variable x can be either equal to y or not equal to y. However, it cannot be both true and false. If the condition is true, then

the process is executed.

A decision statement can also be stated in the following manner:


IF condition
Then process1
ELSE process2

This form is popularly known as the IF–ELSE construct. Here, if the condition is true, then process1 is executed, else process2 is executed. Figure

2.11 shows an algorithm to check if two numbers are equal.

Repetition

Repetition, which involves executing one or more steps for a number of times, can be implemented using constructs such as while, do–while, and

for loops. These loops execute one or more steps until some condition is true. Figure 2.12 shows an algorithm that prints the first 10 natural

numbers.

Dr. Nataraju A B Page - 23

You might also like