PPC Unit 4 Ref Material
PPC Unit 4 Ref Material
PPC Unit 4 Ref Material
For example: If I have to write a program to store Student information, which will have
Student's name, age, branch, permanent address, father's name etc, which included string
values, integer values etc, how can I use arrays for this problem, I will require something
which can hold data of different types together. In structure, data is stored in form of records.
Why structs in C?
Suppose, you want to store information about a person: his/her name, aadhar number, and
salary. You can create different variables name, uin and salary to store this information.
What if you need to store information of more than one person? Now, you need to create
different variables for each information per person : name1, citNo1, salary1, name2,
citNo2, salary2, etc.
A better approach would be to have a collection of all related information under a single
name Person structure and use it for every person.
Define Structures
Before you can create structure variables, you need to define its data type. To define a struct,
the struct keyword is used. struct defines a new data type which is a collection of primary and
derived data types.
Syntax
struct structureName
{
dataType member1;
dataType member2;
...
};
For example,
struct Person
{
char name[50];
int citNo;
float salary;
};
Here, a derived type struct Person is defined. Now, you can create variables of this type.
int main()
{
struct Person person1, person2, p[20];
return 0;
}
In both cases,
person1 and person2 are struct Person variables
p[] is a struct Person array of size 20.
Access Members of a Structure
There are two types of operators used for accessing members of a structure.
. Member operator
-> Structure pointer operator (will be discussed in the unit 4)
Suppose, you want to access the salary of person2. Here's how you can do it.
person2.salary
#include <stdio.h>
#include <string.h>
int main()
{
// assign value to name of person1
strcpy(person1.name, "Amar");
return 0;
}
Output
Name: Amar
Aadhar No.: 1947
Salary: 10000.00
In this program, we have created a struct named Person. We have also created a variable
of Person named person1. In main(), we have assigned values to the variables defined
in Person for the person1 object. strcpy(person1.name, "Amar"); person1.uin = 1947;
person1. salary = 10000;
Notice that we have used strcpy() function to assign the value to person1.name. This is
because name is a char array (C-string) and we cannot use the assignment operator = with it
after we have declared the string. Finally, we printed the data of person1.
Keyword typedef
We use the typedef keyword to create an alias name for data types. It is commonly used with
structures to simplify the syntax of declaring variables. For example, let us look at the
following code:
struct Distance
{
int feet;
float inch;
};
int main()
{
struct Distance d1, d2;
}
int main()
{
distances d1, d2;
}
#include <stdio.h>
#include <string.h>
int main() {
return 0;
}
Output
Name: Amar
Aadhar No.: 1947
Salary: 10000
Here, we have used typedef with the Person structure to create an alias person.
Nested Structures
struct number
{
struct complex comp;
int integers;
} num1, num2;
Suppose, you want to set imag of num2 variable to 11. Here's how you can do it:
num2.comp.imag = 11;
#include <stdio.h>
struct complex
{
int imag;
float real;
};
struct number
{
struct complex comp;
int integer;
} num1;
int main()
{
// initialize complex variables
num1.comp.imag = 11;
num1.comp.real = 5.25;
return 0;
}
Output
Imaginary Part: 11
Real Part: 5.25
Integer: 6
Array of Structure
We can also declare an array of structure variables, in which each element of the array will
represent a structure variable. Example : struct employee emp[5]; The below program defines
an array emp of size 5. Each element of the array emp is of type Employee.
#include<stdio.h>
void main()
{
struct Employee
{
char ename[10];
int sal;
};
We can pass a structure as a function argument just like we pass any other variable or an
array as a function argument.
Example:
#include<stdio.h>
struct Student
{
char name[10];
int roll;
};
void main()
{
struct Student std;
printf("\nEnter Student record:\n");
printf("\nStudent name:\t");
scanf("%s", std.name);
printf("\nEnter Student rollno.:\t");
scanf("%d", &std.roll);
show(std);
}
Union
Unions are conceptually similar to structures. The syntax to declare/define a union is also
similar to that of a structure. The only differences is in terms of storage. In structure each
member has its own storage location, whereas all members of union uses a single shared
memory location which is equal to the size of its largest data member.
This implies that although a union may contain many members of different types, it cannot
handle all the members at the same time. A union is declared using the union keyword.
union item
{
int m;
float x;
char c;
}it1;
This declares a variable it1 of type union item. This union contains three members each with
a different data type. However only one of them can be used at a time. This is due to the fact
that only one location is allocated for all the union variables, irrespective of their size. The
compiler allocates the storage that is large enough to hold the largest variable type in the
union.
In the union declared above the member x requires 4 bytes which is largest amongst the
members for a 16-bit machine. Other members of union will share the same memory address.
Accessing a Union Member in C
Syntax for accessing any union member is similar to accessing structure members,
union test
{
int a;
float b;
char c;
}t;
#include <stdio.h>
union item
{
int a;
float b;
char ch;
};
int main( )
{
union item it;
it.a = 12;
it.b = 20.2;
it.ch = 'z';
printf("%d\n", it.a);
printf("%f\n", it.b);
printf("%c\n", it.ch);
return 0;
}
Output
-26426
20.1999
z
As you can see here, the values of a and b get corrupted and only variable c prints the
expected result. This is because in union, the memory is shared among different data types.
Hence, the only member whose value is currently stored will have the memory. In the above
example, value of the variable c was stored at last, hence the value of other variables is lost.
Pointers: Introduction, Accessing the address of a variable, Declaring and initialization
of pointer variables, Pointers as function arguments, Example programs.
Although pointers may appear a little confusing and complicated in the beginning, but trust
me, once you understand the concept, you will be able to do so much more with C language.
Before we start understanding what pointers are and what they can do, let's start by
understanding what does "Address of a memory location" means?
Address in C
Whenever a variable is defined in C language, a memory location is assigned for it, in which
it's value will be stored. We can easily check this memory address, using the & symbol.
If var is the name of the variable, then &var will give it's address.
Let's write a small program to see memory address of any variable that we define in our
program.
#include<stdio.h>
void main()
{
int var = 7;
printf("Value of the variable var is: %d\n", var);
printf("Memory address of the variable var is: %x\n", &var);
}
Output
Value of the variable var is: 7
Memory address of the variable var is: bcc7a00
You must have also seen in the function scanf(), we mention &var to take user input for any
variable var. scanf("%d", &var); This is used to store the user inputted value to the address of
the variable var.
Concept of Pointers
Whenever a variable is declared in a program, system allocates a location i.e an address to
that variable in the memory, to hold the assigned value. This location has its own address
number, which we just saw above. Let us assume that system has allocated memory
location 80F for a variable a. int a = 10;
We can access the value 10 either by using the variable name a or by using its address 80F.
The question is how we can access a variable using it's address? Since the memory addresses
are also just numbers, they can also be assigned to some other variable. The variables which
are used to hold memory addresses are called Pointer variables.
A pointer variable is therefore nothing but a variable which holds an address of some other
variable. And the value of a pointer variable gets stored in another memory location.
The data type of the pointer and the variable to which the pointer variable is pointing must be
the same.
int a = 10;
int *ptr; //pointer declaration
ptr = &a; //pointer initialization
Pointer variable always points to variables of the same datatype. For example:
float a;
int *ptr = &a; // ERROR, type mismatch
While declaring a pointer variable, if it is not assigned to anything then it contains garbage
value. Therefore, it is recommended to assign a NULL value to it,
#include <stdio.h>
int main()
{
int a;
a = 10;
int *p = &a; // declaring and initializing the pointer
Output
10
10
3795480300
3795480300
3795480304
While declaring/initializing the pointer variable, * indicates that the variable is a pointer.
The address of any variable is given by preceding the variable name with Ampersand &.
The pointer variable stores the address of a variable.
The declaration int *a doesn't mean that a is going to contain an integer value. It means
that a is going to contain the address of a variable storing integer value.
To access the value of a certain address stored by a pointer variable * is used. Here, the * can
be read as 'value at'.
Since we have learned the basics of Pointers in C, you can check out some C programs using
pointer.
Pointers are used to store the address of other variables of similar datatype. But if you want to
store the address of a pointer variable, then you again need a pointer to store it. Thus, when
one pointer variable stores the address of another pointer variable, it is known as Pointer to
Pointer variable or Double Pointer.
Syntax:
int **p1;
Here, we have used two indirection operator(*) which stores and points to the address of a
pointer variable i.e, int *. If we want to store the address of this (double pointer) variable p1,
then the syntax would become:
int ***p2
int main() {
int a = 10;
int *p1; //this can store the address of variable a
int **p2;
/*
this can store the address of pointer variable p1 only.
It cannot store the address of variable 'a'
*/
p1 = &a;
p2 = &p1;
/*
This is not allowed, it will give a compile time error-
p2 = &a;
printf("%u", p2);
*/
return 0;
}
Output
Address of a = 2686724
Address of p1 = 2686728
Address of p2 = 2686732
Value of **p2 = 10
p1 pointer variable can only hold the address of the variable a (i.e Number of indirection
operator(*)-1 variable). Similarly, p2 variable can only hold the address of variable p1. It
cannot hold the address of variable a.
*p2 gives us the value at an address stored by the p2 pointer. p2 stores the address
of p1 pointer and value at the address of p1 is the address of variable a. Thus, *p2 prints
address of a.
**p2 can be read as *(*p2). Hence, it gives us the value stored at the address *p2. From
above statement, you know *p2 means the address of variable a. Hence, the value at the
address *p2 is 10. Thus, **p2 prints 10.
.
Pointer and Arrays in C
When an array in C language is declared, compiler allocates sufficient memory to contain all
its elements. Its base address is also allocated by the compiler.
Declare an array arr,
int arr[5] = { 1, 2, 3, 4, 5 };
Suppose the base address of arr is 1000 and each integer requires two bytes, the five elements
will be stored as follows:
Variable arr will give the base address, which is a constant pointer pointing to arr[0].
Hence arr contains the address of arr[0] i.e 1000.
arr has two purpose -
void main()
{
int a[3] = {1, 2, 3};
int *p = a;
for (int i = 0; i < 3; i++)
{
printf("%d", *p);
p++;
}
return 0;
}
Output
123
Syntax:
*(a+i) //pointer with an array
is same as:
a[i]
The above code creates a string and stores its address in the pointer variable str. The
pointer str now points to the first character of the string "Hello".
The string created using char pointer can be assigned a value at runtime.
char *str;
str = "hello";
The content of the string can be printed using printf() and puts().
printf("%s", str);
puts(str);
str is a pointer to the string and also name of the string. Therefore we do not need to use
indirection operator *.
Array of Pointers
Pointers are very helpful in handling character arrays with rows of varying lengths.
char *name[3] =
{
"Adam",
"chris",
"Deniel"
};
//without pointer
char name[3][20] =
{
"Adam",
"chris",
"Deniel"
};
In the second approach memory wastage is more, hence it is preferred to use pointer in such
cases.
Pointer Arithmetic in C
If you want to have complete knowledge of pointers, pointer arithmetic is very important to
understand. In this topic we will study how the memory addresses change when you
increment a pointer.
Similarly, in this case, size of pointer is still 2 bytes. But now, when we increment it, it will
increment by 8 bytes because its data type is double.
Note: We cannot add two pointers. This is because pointers contain addresses, adding two
addresses makes no sense, because you have no idea what it would point to. But we can
subtract two pointers. This is because difference between two pointers gives the number of
elements of its data type that can be stored between the two pointers.
Program for pointer arithmetic(32-bit machine)
#include <stdio.h>
int main()
{
int m = 5, n = 10, o = 0;
int *p1;
int *p2;
int *p3;
o = *p1+*p2;
printf("*p1+*p2 = %d\n", o);//point 1
p3 = p1-p2;
printf("p1 - p2 = %d\n", p3); //point 2
p1++;
printf("p1++ = %d\n", p1); //point 3
p2--;
printf("p2-- = %d\n", p2); //point 4
return 0;
}
Output
p1 = 2680016
p2 = 2680012
*p1+*p2 = 15
p1-p2 = 1
p1++ = 2680020
p2-- = 2680008
int main()
{
int m = 10, n = 20;
printf("m = %d\n", m);
printf("n = %d\n\n", n);
/*
pointer 'a' and 'b' holds and
points to the address of 'm' and 'n'
*/
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
Output
m = 10
n = 20
After Swapping:
m = 20
n = 10
void main()
{
int a = 15;
int b = 92;
int *p;
p = larger(&a, &b);
printf("%d is larger",*p);
}
Pointer to functions
It is possible to declare a pointer pointing to a function which can then be used as an
argument in another function. A pointer to a function is declared as follows,
type (*pointer-name)(parameter);
Here is an example :
int (*sum)(); //legal declaration of pointer to function
int *sum(); //This is not a declaration of pointer to function
Copy
A function pointer can point to a specific function when it is assigned the name of that
function.
int sum(int, int);
int (*s)(int, int);
s = sum;
Here s is a pointer to a function sum. Now sum can be called using function pointer s along
with providing the required argument values.
s (10, 20);
Example of Pointer to Function
#include <stdio.h>
int main( )
{
int (*fp)(int, int);
fp = sum;
int s = fp(10, 15);
printf("Sum is %d", s);
return 0;
}
Output
25
It appears complex but it is very simple. In this case (*foo) is a pointer to the function, whose
argument is of int* type and return type is void*.
Command-line arguments.