Pps Unit III

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 66

UNIT-III

Introduction to functions

A function is a group of statements that together perform a task. Every C program has at least one function,
which is main(), and all the most trivial programs can define additional functions.

You can divide up your code into separate functions. How you divide up your code among different
functions is up to you, but logically the division is such that each function performs a specific task.

A function declaration tells the compiler about a function's name, return type, and parameters. A function
definition provides the actual body of the function.

The C standard library provides numerous built-in functions that your program can call. For example,
strcat() to concatenate two strings, memcpy() to copy one memory location to another location, and many
more functions.

A function can also be referred as a method or a sub-routine or a procedure, etc.


Defining a Function
Definition: A function is a block of code/group of statements/self contained block of statements/
basic building blocks in a program that performs a particular task. It is also known
as procedure or subroutine or module, in other programming languages.
To perform any task, we can create function. A function can be called many times. It
provides modularity and code reusability.
The general form of a function definition in C programming language is as follows −

return_type function_name( parameter list ) {

body of the function

}
Advantage of functions
1) Code Reusability
By creating functions in C, you can call it many times. So we don't need to write the same code
again and again.
2) Code optimization
It makes the code optimized we don't need to write much code.
3) Easily to debug the program.
Example: Suppose, you have to check 3 numbers (781, 883 and 531) whether it is prime number or
not. Without using function, you need to write the prime number logic 3 times. So, there is repetition of
code. But if you use functions, you need to write the logic only once and you can reuse it several times.

Types of Functions
There are two types of functions in C programming:
1. Library Functions or Predefined functions or Built-in Functions are the functions which are declared
in the C header files such as scanf(), printf(), gets(), puts(), ceil(), floor() etc. You just need to include
appropriate header files to use these functions. These are already declared and defined in C libraries. oints
to be Remembered System defined functions are declared in header filesSystem defined functions are
implemented in .dll files. (DLL stands for Dynamic Link Library).To use system defined functions the
81
respective header file must be included.
2. User-defined functions: are the functions which are created by the C programmer, sothat he/she can use
it many times. It reduces complexity of a big program and optimizes the code. Depending upon the
complexity and requirement of the program, you can create as many user-defined functions as you want.

ELEMENTS OF USER-DEFINED FUNCTINS :


In order to write an efficient user defined function, the programmer must familiar with the
following three elements.

1 : Function Declaration. (Function Prototype).


2 : Function Call.
3 : Function Definition
A function definition in C programming consists of a function header and a function body. Here are all
the parts of a function −
 Return Type − A function may return a value. The return_type is the data type of the value the
function returns. Some functions perform the desired operations without returning a value. In this
case, the return_type is the keyword void.

 Function Name − This is the actual name of the function. The function name and the parameter list
together constitute the function signature.

 Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value to
the parameter. This value is referred to as actual parameter or argument. The parameter list refers
to the type, order, and number of the parameters of a function. Parameters are optional; that is, a
function may contain no parameters.

82
 Function Body − The function body contains a collection of statements that define what the
function does.

Example
Given below is the source code for a function called max(). This function takes two parameters num1 and
num2 and returns the maximum value between the two −

/* function returning the max between two numbers */

int max(int num1, int num2) {

/* local variable declaration */

int result;

if (num1 > num2)


83
result = num1;

else
Function Declarations
A function declaration tells the compiler about a function name and how to call the function. The actual
body of the function can be defined separately.
A function declaration has the following parts −

return_type function_name( parameter list );


For the above defined function max(), the function declaration is as follows −

int max(int num1, int num2);

Parameter names are not important in function declaration only their type is required, so the following is
also a valid declaration −

int max(int, int);

Function declaration is required when you define a function in one source file and you call that function in
another file. In such case, you should declare the function at the top of the file calling the function.
Function prototype

A function prototype is simply the declaration of a function that specifies function's name, parameters and
return type. It doesn't contain function body.

A function prototype gives information to the compiler that the function may later be used in the program.

Syntax of function prototype

returnType functionName(type1 argument1, type2 argument2,...);

In the above example, int addNumbers(int a, int b); is the function prototype which provides
following information to the compiler:

1. name of the function is addNumbers()


2. return type of the function is int
3. two arguments of type int are passed to the function

The function prototype is not needed if the user-defined function is defined before the main() function.

Category of functions:

A function depending an whether the arguments are present or not and whether a value is returned
or not, may belong to one of following categories

84
1. Function with no return values, no arguments
2. Functions with arguments, no return values
3. Functions with arguments and return values
4. Functions with no arguments and return values.

Function with no return values, no arguments

In this category, the function has no arguments. It does not receive any data from the calling
function. Similarly, it doesn‟t return any value. The calling function doesn‟t receive any data from
the called function. So, there is no communication between calling and called functions.

Functions with arguments, no return values

In this category, function has some arguments . it receives data from the calling function, but it
doesn‟t return a value to the calling function. The calling function doesn‟t receive any data from
the called function. So, it is one way data communication between called and calling functions.

Eg: Printing n Natural numbers


#include<stdio.h> #include<conio.h>
void nat( int);
void main()
{
int n;
printf("\n Enter n value:"); scanf("%d",&n);
nat(n);
}
void nat(int n)
{
int i; for(i=1;i<=n;i++) printf("%d\t",i);
}

Note:
In the main() function, n value is passed to the nat() function. The n value is now stored in the
formal argument n, declared in the function definition and subsequently, the natural numbers upto
n are obtained.

Functions with arguments and return values

In this category, functions has some arguments and it receives data from the calling function.
Simillarly, it returns a value to the calling function. The calling function receives data from
thecalled function. So, it is two-way data communication between calling and called functions.

Eg. Factorial of a Number

#include<stdio.h> #include<conio.h> int fact(int);


void main()
85
{
int n;
printf("\n Enter n:"); scanf("%d",&n);
printf("\n Factorial of the number : %d", fact(n));

}
int fact(int n)
{
int i,f;
for(i=1,f=1;i<=n;i++)
f=f*i;
return(f);
}

Functions with no arguments and return values.

In this category, the functions has no arguments and it doesn‟t receive any data from the calling
function, but it returns a value to the calling function. The calling function receives data from
the called function. So, it is one way data communication between calling and called functions.

Eg. Sum of Numbers

#include<stdio.h> #include<conio.h> int sum();


void main()
{
int s;
printf("\n Enter number of elements to be added :"); s=sum();
printf("\n Sum of the elements :%d",s);

int sum(){
int a[20], i, s=0,n;
scanf("%d",&n);
printf("\n Enter the elements:"); for(i=0;i< n; i++) scanf("%d",& a[i]);
for(i=0;i< n; i++) s=s+a[i];
return s;
}

Inter Function communication


When a function gets executed in the program, the execution control is transferred from calling function
to called function and executes function definition, and finally comes back to the calling function. In this
process, both calling and called functions have to communicate each other to exchange information. The
process of exchanging information between calling and called functions is called as inter function
communication.
86
In C, the inter function communication is classified as follows...

 Downward Communication
 Upward Communication
 Bi-directional Communication

Downward Communication
In this type of communication, the data is transferred from calling function to called function but not from
called function to calling function. The function with parameters and without return value are considered
under Downward communication.
Example

#include <stdio.h> #include<conio.h> void main(){


int num1, num2 ;
void addition(int, int) ; // function declaration clrscr() ;
num1 = 10 ; num2 = 20 ;

printf("\nBefore swap: num1 = %d, num2 = %d", num1, num2) ;


addition(num1, num2) ; // calling function

getch() ;
}
void addition(int a, int b) // called function
{

87
printf("SUM = %d", a+b) ;

Output SUM=30
Upward Communication
In this type of communication, the data is transferred from called function to calling function but not from
calling function to called function. The function without parameters and with return value are considered
under Upward communication.

Example
#include <stdio.h> #include<conio.h> void main(){
int result ;
int addition() ; // function declaration clrscr() ;

result = addition() ; // calling function

printf("SUM = %d", result) ; getch() ;


}

int addition() // called function


{
int num1, num2 ; num1 = 10;
num2 = 20;
return (num1+num2) ;
}

Output SUM=30

Bi-Directional Communication
In this type of communication, the data is transferred from called function to calling function and also from
calling function to called function. The function with parameters and with return value are considered under
Bi-Directional communication.

88
Example

#include <stdio.h> #include<conio.h> void main(){


int num1, num2, result ;
int addition(int, int) ; // function declaration clrscr() ;

num1 = 10 ; num2 = 20 ;

result = addition(num1, num2) ; // calling function

printf("SUM = %d", result) ; getch() ;


}
int addition(int a, int b) // called function
{
return (a+b) ;
}

Output SUM=30
PARAMETERS :
parameters provides the data communication between the calling function and called function.
They are two types of parameters.
1 : Actual parameters.
2 : Formal parameters.
1 : Actual Parameters : These are the parameters transferred from the calling function (main
program) to the called function (function).
2 : Formal Parameters :These are the parameters transferred into the calling function (main
program) from the called function(function).
 The parameters specified in calling function are said to be Actual Parameters.
 The parameters declared in called function are said to be Formal Parameters.
 The value of actual parameters is always copied into formal parameters.
Ex : main()
{
fun1( a , b ); //Calling function
}
fun1( x, y ) //called function
{
......
}
Where
a, b are the Actual Parameters
x, y are the Formal Parameters

Difference between Actual Parameters


Actual Parameters
1 : Actual parameters are used in calling function when a function is invoked.
Ex : c=add(a,b); Here a,b are actual parameters.
2 : Actual parameters can be constants,variables or expression.
Ex : c=add(a,b) //variable
c=add(a+5,b); //expression.c=add(10,20); //constants.

89
3 : Actual parameters sends values to the formal parameters.
Ex : c=add(4,5);
4 : Address of actual parameters can be sent
to formal parameters

Formal Parameters
1 : Formal parameters are used in thefunction header of a called function.
Ex : int add(int m,int n); Here m,n are called formal parameters.
Ex : int add(int m,int n);
Here m,n are called formal parameters.
2 : Formal parametes should be only variable. Expression and constants are not allowed.
Ex : int add(int m,n); //CORRECT
int add(int m+n,int n) //WRONG
int add(int m,10); //WRONG

3 : Formal parametes receive values from the actual parametes.


Ex : int add(int m,int n);
Here m will have the value 4 and n will
have the value 5.
4 : if formal parameters contains address,they should be declared as pointers.
Function Calls
This calls the actual function
Syntax:
function_name (arguments list);

There are two ways that a C function can be called from a program. They are,

1. Call by value or Pass by Value


2. Call by reference or Pass by Reference

90
Call by Value

 In call by value method, the value of the variable is passed to the function as parameter.

 The value of the actual parameter can not be modified by formal parameter.

 Different Memory is allocated for both actual and formal parameters. Because, value of actual
parameter is copied to formal parameter.
Note:

 Actual parameter – This is the argument which is used in function call.

 Formal parameter – This is the argument which is used in function definition

Call by Reference:

 In call by reference method, the address of the variable is passed to the function as parameter.

 The value of the actual parameter can be modified by formal parameter.

 Same memory is used for both actual and formal parameters since only address is used byboth
parameters.

Parameter Passing Mechanisms:

In C Programming we have different ways of parameter passing schemes such as Call by Value and Call by
Reference.
Function is good programming style in which we can write reusable code that can be called whenever
require.
Whenever we call a function then sequence of executable statements gets executed. We can pass some of
the information to the function for processing called argument.
Two Ways of Passing Argument to Function in C Language :
A. Call by Reference
B. Call by Value
Let us discuss different ways one by one –

A. Call by Value :

#include<stdio.h>
void interchange(int number1,int number2)
{
int temp;
temp = number1; number1 = number2; number2 = temp;
}
int main() {

91
int num1=50,num2=70; interchange(num1,num2); printf("\nNumber 1 : %d",num1); printf("\
nNumber 2 : %d",num2);
return(0);
}

Output :
Number 1 : 50
Number 2 : 70

Explanation : Call by Value


While Passing Parameters using call by value , xerox copy of original parameter is created and passed to
the called function.
Any update made inside method will not affect the original value of variable in calling function.

In the above example num1 and num2 are the original values and xerox copy of these values is passed to
the function and these values are copied into number1,number2 variable of sum function respectively.
As their scope is limited to only function so they cannot alter the values inside main function.

92
B. Call by Reference/Pointer/Address :

#include<stdio.h>
void interchange(int *num1,int *num2)
{
int temp;
temp = *num1;
*num1 = *num2;
*num2 = temp;
}
int main() {
int num1=50,num2=70; interchange(&num1,&num2); printf("\nNumber 1 : %d",num1); printf("\
nNumber 2 : %d",num2); return(0);
}

Output :
Number 1 : 70
Number 2 : 50

Call by Address
While passing parameter using call by address scheme , we are passing the actual address of the variable to
the called function.
Any updates made inside the called function will modify the original copy since we are directly modifying
the content of the exact memory location.

93
Recursion

The process of calling a function by itself is called recursion and the function which calls itself is
called recursive function. Recursion is used to solve various mathematical problems by dividing it
into smaller problems.
Syntax of Recursive Function

return_type recursive_func ([argument list])


{
statements;
... ... ...
recursive_func ([actual argument]);
... ... ...
}

Flowchart of Recursion

Note: In order to prevent infinite recursive call, we need to define proper exit condition in a recursive
function.

For example, consider the program below:


94
Example #1: C Program to show infinite recursive function

#include<stdio.h> int main()


{
printf("Hello world"); main();
return 0;
}

In this program, we are calling main() from main() which is recursion. But we haven't defined any
condition for the program to exit. Hence this code will print "Hello world" infinitely in the output screen.

Types of recursion
 Direct Recursion
 Indirect Recursion

Direct Recursion

A function is said to be direct recursive if it calls itself directly.

Example #2: C Program Function to show direct recursion

int fibo (int n)


{
if (n==1 || n==2) return 1;
else
return (fibo(n-1)+fibo(n-2));
}

In this program, fibo() is a direct recursive function. This is because, inside fibo() function, there is
a statement which calls fibo() function again directly.

Indirect Recursion

A function is said to be indirect recursive if it calls another function and this new function calls the
first calling function again.

95
Example #3: C Program Function to show indirect recursion

int func1(int n)
{
if (n<=1) return 1;
else
return func2(n);
}

int func2(int n)
{
return func1(n);
}

Passing Array to a Function:

Whenever we need to pass a list of elements as argument to any function in C language, it is


prefered to do so using an array.

Declaring Function with array as a parameter

There are two possible ways to do so, one by using call by value and other by using call by
reference.

We can either have an array as a Parameter

int sum (int arr[]);

Or, we can have a pointer in the parameter list, to hold the base address of our

array. int sum (int* ptr);

Returning an Array from a function

We don't return an array from functions, rather we return a pointer holding the base address of the
array to be returned.

int* sum (int x[])


{
// statements return x ;
}
Passing a single array element to a function(Call by value)

89
In this type of function call, the actual parameter is copied to the formal parameters.

Example 1:

#include<stdio.h>
void giveMeArray(int a); int main()
{
int myArray[] = { 2, 3, 4 }; giveMeArray(myArray[2]); return 0;
}
void giveMeArray(int a)
{
printf("%d", a);
}

Output: 4

Example 2:

#include <stdio.h> void disp( char ch)


{
printf("%c ", ch);
}
int main()
{
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}; for (int x=0; x<10; x++)
{
disp (arr[x]);
}
return 0;
}
OUTPUT: abcdefghij

Passing array to function using call by reference


When we pass the address of an array while calling a function then this is called function call by
reference. When we pass an address as an argument, the function declaration should have a pointer
as a parameter to receive the passed address.

#include <stdio.h> void disp( int *num)


{

90
printf("%d ", *num);
}

int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8,9, 0};
for (int i=0; i<10;i++)
{
/* Passing addresses of array elements*/ disp (&arr[i]);
}
return 0;
} OUTPUT:

1234567890

Passing a complete One-dimensional array to a function

We will only send in the name of the array as argument, which is nothing but the address of the
starting element of the array, or we can say the starting memory address.

#include<stdio.h>
float findAverage(int marks[]); int main()
{
float avg;
int marks[] = {99, 90, 96, 93, 95};
avg = findAverage(marks); printf("Average marks = %.1f", avg); return 0;
}
float findAverage(int marks[])
{
int i, sum = 0; float avg;
for (i = 0; i <= 4; i++)
{
sum += age[i];
}
avg = (sum / 5); return avg;
}

Output: 94.6

91
Passing a Multi-dimensional array to a function

For two dimensional array, we will only pass the name of the array as argument.

#include<stdio.h>
void displayArray(int arr[3][3]); int main()
{
int arr[3][3], i, j;
printf("Please enter 9 numbers for the array: \n"); for (i = 0; i < 3; ++i)
{
for (j = 0; j < 3; ++j)
{
scanf("%d", &arr[i][j]);
}
}
// passing the array as argument displayArray(arr); return 0;
}
void displayArray(int arr[3][3])
{
int i, j;
printf("The complete array is: \n"); for (i = 0; i < 3; ++i)
{
// getting cursor to new line printf("\n"); for (j = 0; j < 3; ++j)
{
// \t is used to provide tab space printf("%4d", arr[i][j]);
}
}
}

Output:
Please enter 9 numbers for the array: 1 2 3 4 5 6 7 8 9
The complete array is: 1 2 3 4 5 6 7 8 9

Passing string to function

 A string is a collection of characters.


 A string is also called as an array of characters.
 A String must access by %s access specifier in c and c++.
 A string is always terminated with \0 (Null) character.

92
 Example of string: “Gaurav”
 A string always recognized in double quotes.
 A string also consider space as a character.
 Example: ” Gaurav Arora”
 The above string contains 12 characters.
 Example: Char ar[20]
 The above example will store 19 character with I null character.

Strings are just char arrays. So, they can be passed to a function in a similar manner as arrays.

#include <stdio.h>
void displayString(char str[]); int main()
{
char str[50]; printf("Enter string: "); gets(str);
displayString(str);
// Passing string c to function. return 0;
}
void displayString(char str[])
{
printf("String Output: "); puts(str);
}

Here, string c is passed from main() function to user-defined function displayString(). In function
declaration, str[] is the formal argument

Example-2 : #include<stdio.h> #include<stdlib.h> #include<string.h>


void strreverse(char *string)
{
int i, len; char c;
len=strlen(string); char string2[len+1];

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


{
c=string[i];

93
string2[len-i]=c;

}
string2[len+1]='\0'; string=string2;
//printf("%s\n", string);
}

int main(int argc, char *argv[])


{
char str[256];
printf("Type a String to reverse it.[max. 255 chars]\n"); fgets(str, 255, stdin);
strreverse(&str[0]); printf("%s", str); return 0;
}

Storage Classes

Every Variable in a program has memory associated with it. Memory Requirement of Variables is
different for different types of variables. In C, Memory is allocated & released at different places

Term Definition

Region or Part of Program in which Variable is accessible


Scope

Extent Period of time during which memory is associated with


variable
Storage Manner in which memory is allocated by the Compiler for
Variable
Class
Different Storage Classes

Storage class of variable Determines following things


Where the variable is stored Scope of Variable
Default initial
value Lifetime of variable

94
Where the variable is stored:

Storage Class determines the location of variable, where it is declared. Variables declared with
auto storage classes are declared inside main memory whereas variables declared with keyword
register are stored inside the CPU Register.

Scope of Variable

Scope of Variable tells compile about the visibility of Variable in the block. Variable may have
Block Scope, Local Scope and External Scope. A scope is the context within a computer program
in which a variable name or other identifier is valid and can be used, or within which a declaration
has effect.

Default Initial Value of the Variable

Whenever we declare a Variable in C, garbage value is assigned to the variable. Garbage Value
may be considered as initial value of the variable. C Programming have different storage classes
which has different initial values such as Global Variable have Initial Value as 0 while the Local
auto variable have default initial garbage value.

Lifetime of variable

Lifetime of the = Time Of variable Declaration - Time of Variable Destruction Suppose we have
declared variable inside main function then variable will be destroyed only when the control
comes out of the main .i.e end of the program.

Different Storage Classes:

 Auto Storage Class


 Static Storage Class
 Extern Storage Class
 Register Storage Class

Automatic (Auto) storage class

This is default storage class

All variables declared are of type Auto by default

In order to Explicit declaration of variable use ‗auto„ keyword auto int num1 ; // Explicit

Declaration

95
Features:

Memory
Storage

Scope Local / Block Scope

Life time Exists as long as Control remains in the


block

Garbage
Default initial
Value

Example

void main()
{
auto mum = 20 ;
{
auto num = 60 ; printf("nNum : %d",num);
}
printf("nNum : %d",num);
}

Note :

Two variables are declared in different blocks , so they are treated as different variables

External ( extern ) storage class in C Programming

Variables of this storage class are ―Global variables‖

Global Variables are declared outside the function and are accessible to all functions in the
program

Generally , External variables are declared again in the function using keyword extern In order to
Explicit declaration of variable use ‗extern„ keyword

extern int num1 ; // Explicit Declaration

96
Features :
Storage Memory
Global / File Scope
Scope

Life time Exists as long as variable is running


Retains value within the function
Zero
Default initial Value

Example

int num = 75 ; void display(); void main()


{
extern int num ; printf("nNum : %d",num); display();
}
void display()
{
extern int num ; printf("nNum : %d",num);
}

Static Storage Class

The static storage class instructs the compiler to keep a local variable in existence during the life-
time of the program instead of creating and destroying it each time it comes into and goes out of
scope. Therefore, making local variables static allows them to maintain their values between
function calls.The static modifier may also be applied to global variables. When this is done, it
causes that variable's scope to be restricted to the file in which it is declared.
In C programming, when static is used on a class data member, it causes only one copy of that
member to be shared by all the objects of its class.

97
#include <stdio.h>

void func(void);
static int count = 5; /* global variable
*/ main() { while(count--)
{
func();
}
return 0;
}
void func( void )
{
static int i = 5;
/* local static variable*/ i++;
printf("i is %d and count is %d\n", i, count);
}

Register Storage Class


register keyword is used to define local variable. Local variable are stored in register instead of
RAM.
As variable is stored in register, the Maximum size of variable = Maximum Size of Register
unary operator [&] is not associated with it because Value is not stored in RAM instead it is stored
in Register.

This is generally used for


faster access.

Common use is ―Counter―

Example

#include<stdio.h> int main()


{
int num1,num2; register int sum;
printf("\nEnter the Number 1 : "); scanf("%d",&num1); printf("\nEnter the Number 2 : ");

98
scanf("%d",&num2);
sum = num1 + num2;
printf("\nSum of Numbers : %d",sum);

return(0);
}

Preprocessor directives

The C preprocessor is a macro processor that is used automatically by the C compiler to transform
your program before actual compilation (Proprocessor direcives are executed before compilation.).
It is called a macro processor because it allows you to define macros, which are brief abbreviations
for longer constructs. A macro is a segment of code which is replaced by the value of macro.
Macro is defined by #define directive.

Preprocessing directives are lines in your program that start with #. The # is followed by an
identifier that is the directive name. For example, #define is the directive that defines a macro.
Whitespace is also allowed before and after the #.

The # and the directive name cannot come from a macro expansion. For example, if foo is defined
as a macro expanding to define, that does not make #foo a valid preprocessing directive.

All preprocessor directives starts with hash # symbol.

List of preprocessor directives :

1. #include
2. #define
3. #undef
4. #ifdef
5. #ifndef
6. #if
7. #else
8. #elif
9. #endif
10. #error
11. #pragma

1. #include

The #include preprocessor directive is used to paste code of given file into current file. It is used
include system- defined and user-defined header files. If included file is not found, compiler
renders error. It has three variants:

99
#include <file>

This variant is used for system header files. It searches for a file named file in a list of directories
specified by you, then in a standard list of system directories.
#include "file"

This variant is used for header files of your own program. It searches for a file named file first in
the current directory, then in the same directories used for system header files. The current
directory is the directory of the current input file.

#include anything else

This variant is called a computed #include. Any #include directive whose argument does not fit
the above two forms is a computed include.

2. Macro's (#define)

Let's start with macro, as we discuss, a macro is a segment of code which is replaced by the value
of macro. Macro is defined by #define directive.

Syntax

#define token value


There are two types of macros:

1. Object-like Macros
2. Function-like Macros

1. Object-like Macros

The object-like macro is an identifier that is replaced by value. It is widely used to represent
numeric constants. For example:

#define PI 3.1415
Here, PI is the macro name which will be replaced by the value 3.14. Let's see an example of
Object-like Macros
:

#include
<stdio.h>
#define PI
3.1415 main()
{ 100
Output: 3.14000

2. Function-like Macros

The function-like macro looks like function call. For example:

#define MIN(a,b) ((a)<(b)?(a):(b)

Here MIN is the macro name. Let's see an example of Function-like Macros : #include <stdio.h>
#define MIN(a,b) ((a)<(b)?(a):(b)) void main()
{
printf("Minimum between 10 and 20 is: %d\n", MIN(10,20));
}
Output:
Minimum between 10 and 20 is: 10

Preprocessor Formatting

A preprocessing directive cannot be more than one line in normal circumstances. It may be split
cosmetically with Backslash-Newline. Comments containing Newlines can also divide the
directive into multiple lines.
for example, you can split a line cosmetically with Backslash-Newline anywhere:

is equivalent into #define FOO 1020.


3. #undef

To undefine a macro means to cancel its definition. This is done with the

#undef directive. Syntax:

#undef token
define and undefine example #include <stdio.h>
#define PI 3.1415 #undef PI
main()
{ printf("%f",PI);
}

101
Output:

Compile Time Error: 'PI' undeclared

4. #ifdef

The #ifdef preprocessor directive checks if macro is defined by #define. If yes, it executes the

code.

Syntax:

#ifdef MACRO
//code #endif

5. #ifndef

The #ifndef preprocessor directive checks if macro is not defined by #define. If yes, it

executes the code.

Syntax:

#ifndef MACRO
//code #endif

6. #if

The #if preprocessor directive evaluates the expression or condition. If condition is true, it

executes the code.

Syntax:

#if expression
//code #endif

7. #else

The #else preprocessor directive evaluates the expression or condition if condition of #if is false. It
can be used with #if, #elif, #ifdef and #ifndef directives.

102
Syntax:

#if expression
//if code #else
//else code #endif

Syntax with #elif #if expression


//if code
#elif expression
//elif code #else
//else code #endif

8. #error

The #error preprocessor directive indicates error. The compiler gives fatal error if #error directive
is found and skips further compilation process.

C #error example

#include<stdio.h> #ifndef MATH_H


#error First include then compile #else void main(){ float a; a=sqrt(7); printf("%f",a);
}
#endif

9. #pragma

The #pragma preprocessor directive is used to provide additional information to the compiler. The
#pragma directive is used by the compiler to offer machine or operating-system feature. Different
compilers can provide different usage of #pragma directive.

Syntax:
#pragma token

103
UNIT-IV

STRUCTURES, UNIONS AND POINTERS

Need of
structure
s

Structure is a collection of variables of different types under a single name.

For example: You want to store some information about a person: his/her name, citizenship
number and salary. You can easily create different variables name, citNo, salary to store these
information separately.

However, in the future, you would want to store information about multiple persons. Now, you'd
need to create different variables for each information per person: name1, citNo1, salary1, name2,
citNo2, salary2

You can easily visualize how big and messy the code would look. Also, since no relation between
the variables (information) would exist, it's going to be a daunting task.

A better approach will be to have a collection of all related information under a single name
Person, and use it for every person. Now, the code looks much cleaner, readable and efficient as
well.

This collection of all related information under a single name Person is a structure.

Structure Definition in C

Keyword structis used for creating a structure.

Syntax of structure

struct structure_name

data_type member1;

data_type member2;

data_type memeber;};

104
Note: Don't forget the semicolon }; in the ending line.

We can create the structure for a person as mentioned above as:

struct person

char name[50]; int citNo;


float salary;

};

This declaration above creates the derived data type struct person.

Structure variable declaration

When a structure is defined, it creates a user-defined type but, no storage or memory is allocated. For the
above structure of a person, variable can be declared as:

struct person

char name[50]; int citNo;


float salary;

};
int main()

struct person person1, person2, person3[20]; return 0;


}

Another way of creating a structure variable is struct person

char name[50]; int citNo;


float salary;

105
} person1, person2, person3[20];

In both cases, two variables person1, person2 and an array person3 having 20 elements of type
struct person are created.

Accessing members of a structure

There are two types of operators used for accessing members of a structure.
1. Member operator(.)
2. Structure pointer operator(->) (is discussed in structure and pointers tutorial)
3. Any member of a structure can be accessed as:

structure_variable_name.member_name

Suppose, we want to access salary for variable person2. Then, it can be accessed as:

person2.salary

Example of structure

Write a C program to add two distances entered by user. Measurement of distance should be in inch
and feet. (Note: 12 inches = 1 foot)

#include <stdio.h> struct Distance


{
int feet; float inch;
} dist1, dist2, sum;

int main()
{
printf("1st distance\n");
// Input of feet for structure variable dist1 printf("Enter feet: "); scanf("%d", &dist1.feet);

// Input of inch for structure variable dist1 printf("Enter inch: "); scanf("%f", &dist1.inch);

106
printf("2nd distance\n");

// Input of feet for structure variable dist2 printf("Enter feet: "); scanf("%d", &dist2.feet);

// Input of feet for structure variable dist2 printf("Enter inch: "); scanf("%f", &dist2.inch);
sum.feet = dist1.feet + dist2.feet; sum.inch = dist1.inch + dist2.inch;

if (sum.inch > 12)


{
//If inch is greater than 12, changing it to feet.
++sum.feet;
sum.inch = sum.inch - 12;
}
// printing sum of distance dist1 and dist2
printf("Sum of distances = %d\'-%.1f\"", sum.feet, sum.inch); return 0;
}

Output
1st distance Enter feet: 12
Enter inch: 7.9 2nd distance Enter feet: 2 Enter inch: 9.8
Sum of distances = 15'-5.7"

Structure Initialization

1. When we declare a structure, memory is not allocated for un-initialized variable.

2. Let us discuss very familiar example of structure student , we can initialize structure
variable in different ways –

Way1: Declare and Initialize

struct student
{
char name[20]; int roll;
float marks;
}std1 = { "Pritesh",67,78.3 };

107
In the above code snippet, we have seen that structure is declared and as soon as after declaration we have
initialized the structure variable.

Way2: Declaring and Initializing Multiple Variables

struct student
{
char name[20]; int roll;
float marks;
}
std1 = {"Pritesh",67,78.3};
std2 = {"Don",62,71.3};

In this example, we have declared two structure variables in above code. After declaration of variable we
have initialized two variable.

Way3: Initializing single member struct student


{
int mark1; int mark2; int mark3;
} sub1={67};
Though there are three members of structure,only one is initialized , Then remaining two members are
initialized with Zero. If there are variables of other data type then their initial values will be –

Data Type Default value if not initialized

integer 0

Float 0.00

Char NULL

Way4: Initializing inside main struct student


{
int mark1;

108
int mark2; int mark3;
};
void main()
{
struct student s1 = {89,54,65};
- - - - --
- - - - --
- - - - --
};

When we declare a structure then memory won‟t be allocated for the structure. i.e only writing below
declaration statement will never allocate memory
struct student
{
int mark1; int mark2; int mark3;
};

We need to initialize structure variable to allocate some memory to the structure

Accessing StructureMembers

1. Array elements are accessed using the Subscript variable , Similarly Structure members are

accessed using dot [.] operator.

2. (.) is called as “Structure member Operator”.

3. Use this Operator in between “Structure name” & “member name”.

#include<stdio.h> struct stud


{

char name[20]; char fname[10];


};

struct stud s;

109
main()
{

scanf("%s%s",&s.name,&s.fname); printf("%s%s",s.name,s.fname);
}

Output:
Vedha srinivas Vedhasrinivas

struct employee
{
char name[100]; int age;
float salary;
char department[50];

} employee_one = {"Jack", 30, 1234.5, "Sales"};

int age = employee_one.age;

float salary= employee_one.salary;

char department= employee_one.department;

ACCESSING ARRAY OF STRUCTURE ELEMTS

STRUCT STUD
{
Datatype member1; Datatype member2;
.

110
.
} struct stud s[50];

Members of structures are accessed through dot operator. Eg: stud[i].memeber1 Stud[i].member2

#include<stdio.h> struct stud


{
char name[20];

};

struct stud s[10]; main()


{

int i,n; for(i=0;i<2;i++)


{

scanf("%s",&s[i].name);

printf("%s",s[i].name);

Output: Swapna Divya Swapna divya

111
Nested Structures

A structure can be nested inside another structure. In other words, the members of a structure can
be of any other type including structure.
Here is the syntax to create nested structures.

structure tagname_1
{
member1; member2; member3;... Member n; structure tagname_2

{
member_1; member_2; member_3;... member_n;
}, var1
} var2;

To access the members of the inner structure, we write a variable name of the outer structure, followed by
a dot(.) operator, followed by the variable of the inner structure, followed by a dot(.) operator, which is
then followed by the name of the member we want to access.

var2.var1.member_1 - refers to the member_1 of structure tagname_2 var2.var1.member_2 - refers to the


member_2 of structure tagname_2

Let's take an example:

struct student
{
struct person

{
char name[20]; int age;

char dob[10];

}p;
int rollno; float marks;

} stu;

112
Here we have defined structure person as a member of structure student. Here is how we can access the
members of person structure.

stu.p.name - refers to the name of the person stu.p.age - refers to the age of the person stu.p.dob - refers to

the date of birth of the person

It is important to note that structure person doesn't exist on its own. We can't declare structure variable of
type struct person anywhere else in the program.

Instead of defining the structure inside another structure. We could have defined it outside and then
declare it's variable inside the structure where we want to use it. For example:

struct person
{
char name[20]; int age;
char dob[10];
};

We can use this structure as a part of a bigger structure struct student

{
struct person info; int rollno;

float marks;

Here the first member is of type struct person. If we use this method of creating nested structures then you
must first define the structures before creating variables of its types. So, it's mandatory for you to first
define person structure before using it's variable as a member of the structure student.

The advantage of using this method is that now we can declare a variable of type struct person in
anywhere else in the program.

113
Initializing nested Structures

Nested structures can be initialized at the time of declaration. For example:

struct person
{
char name[20]; int age; char dob[10];
};
struct student
{
struct person info; int rollno; float marks[10];
}
struct student student_1 = {{"Adam", 25,1990},101,90};

The following program demonstrates how we can use nested structures.

#include<stdio.h> struct person


{
char name[20]; int age;
char dob[10];
};

struct student
{
struct person info; int roll_no; float marks;
};

int main()
{
struct student s1;
printf("Details of student: \n\n");
printf("Enter name: "); scanf("%s", s1.info.name);
printf("Enter age: "); scanf("%d", &s1.info.age);
printf("Enter dob: "); scanf("%s", s1.info.dob); printf("Enter roll no: "); scanf("%d", &s1.roll_no);
printf("Enter marks: "); scanf("%f", &s1.marks); printf("\n*******************************\
n\n"); printf("Name: %s\n", s1.info.name);
printf("Age: %d\n", s1.info.age);
printf("DOB: %s\n", s1.info.dob); printf("Roll no:%d\n", s1.roll_no); printf("Marks: %.2f\n",
s1.marks);
signal to operating system program ran fine return 0;
}

114
Need of array of structures:
Structure is collection of different data type. An object of structure represents a single record in memory, if
we want more than one record of structure type, we have to create an array of structure or object. As we
know, an array is a collection of similar type, therefore an array can be of structure type.
Structure is used to store the information of One particular object but if we need to store such 100 objects
then Array of Structure is used.

Syntax

Struct struct-name
{
datatype var1; datatype var2;

datatype varN
};
Struct struct-name obj[size]

Initializing Array of Structure:

Array elements are stored in consecutive memory Location. Like Array , Array of Structure can be
initialized at compile time.

Way1 : Initializing After Declaring Structure Array :

struct Book

{
char bname[20]; int pages;

char author[20]; float price;

}b1[3] = {{"Let us C",700,"YPK",300.00},

{"Wings of Fire",500,"APJ AbdulKalam",350.00},

{"Complete C",1200,"HerbtSchildt",450.00}

};

115
Explanation:

As soon as after declaration of structure we initialize structure with the pre-defined values. For each
structure variable we specify set of values in curly braces. Suppose we have 3 Array Elements then we have
to initialize each array element individually and all individual sets are combined to form single set.

{"Let us C",700,"YPK",300.00}

Above set of values are used to initialize first element of the array. Similarly –

{"Wings of Fire",500,"APJ Abdul Kalam",350.00} is used to initialize second element of the array.

Way 2 : Initializing in Main

struct Book

char bname[20]; int pages;

char author[20]; float price;

};

void main()

struct Book b1[3] = {{"Let us C",700,"YPK",300.00},

{"Wings of Fire",500,"AbdulKalam",350.00},

{"Complete C",1200,"HerbtSchildt",450.00}

};

116
C Program on book details using array of structures:

#include <stdio.h> struct Bookinfo


{
char[20] bname; int pages;
int price;
}book[3];
int main(int argc, char *argv[])
{
int i; for(i=0;i<3;i++)
{
printf("\nEnter the Name of Book: "); gets(book[i].bname);
printf("\nEnter the Number of Pages : "); scanf("%d",book[i].pages); printf("\nEnter the Price of Book : ");
scanf("%f",book[i].price);
}
printf("\n--------- Book Details------------------");
for(i=0;i<3;i++)
{
printf("\nName of Book : %s",book[i].bname); printf("\nNumber of Pages : %d",book[i].pages); printf("\
nPrice of Book : %f",book[i].price);
}
return 0;
}

117
Some Observations and Important Points:

Tip #1 : All Structure Members need not be initialized

#include<stdio.h> struct Book

char bname[20]; int pages;

char author[20]; float price;

}b1[3] = {

{"Book1",700,"YPK"},

{"Book2",500,"AAK",350.00},

{"Book3",120,"HST",450.00}

};

void main()

printf("\nBook Name: %s",b1[0].bname); printf("\nBook Pages : %d",b1[0].pages); printf("\nBook

Author : %s",b1[0].author); printf("\nBook Price : %f",b1[0].price);

In this example , While initializing first element of the array we have not specified the price of book 1.It is
not mandatory to provide initialization for all the values. Suppose we have 5 structure elements and we
provide initial values for first two element then we cannot provide initial values to remaining elements.

118
{"Book1",700,,90.00}

above initialization is illegal and can cause compile time error. Tip #2 :

Default Initial Value

struct Book

char bname[20]; int pages;

char author[20]; float price;

}b1[3] = {

{},

{"Book2",500,"AAK",350.00},

{"Book3",120,"HST",450.00}

};

Output :

Book Name :

Book Pages : 0 Book Author :

Book Price : 0.000000

Structures and functions

In C, structure can be passed to functions by two methods: 1.Passing by value (passing actual

value as argument) 2.Passing by reference (passing address of an argument)

119
Passing structure by value

A structure variable can be passed to the function as an argument as a normal variable.

If structure is passed by value, changes made to the structure variable inside the function definition
does not reflect in the originally passed structure variable.

C program to create a structure student, containing name and roll and display the information.

#include <stdio.h>
struct student
{
char name[50]; int roll;
};
void display(struct student stu); int main()
{
struct student stud; printf("Enter student's name: "); scanf("%s", &stud.name); printf("Enter roll
number:"); scanf("%d", &stud.roll);
display(stud); // passing structure variable stud as argument return 0;
}
void display(struct student stu){ printf("Output\nName: %s",stu.name); printf("\nRoll:
%d",stu.roll);

Output :
Enter student's name: Raju Enter roll number: 48 Name: Raju
Roll : 48

Passing structure by reference

The memory address of a structure variable is passed to function while passing it by reference. If structure
is passed by reference, changes made to the structure variable inside function definition reflects in the
originally passed structure variable.

C program to add two distances and display the result without the return statement.

#include <stdio.h> struct distance

120
{
int feet; float inch;
};
void add(struct distance d1,struct distance d2, struct distance *d3); int main()
{
struct distance dist1, dist2, dist3; printf("First distance\n"); printf("Enter feet: "); scanf("%d",
&dist1.feet); printf("Enter inch: "); scanf("%f", &dist1.inch); printf("Second distance\n");
printf("Enter feet: "); scanf("%d", &dist2.feet); printf("Enter inch: "); scanf("%f", &dist2.inch);
add(dist1, dist2, &dist3);
printf("\nSum of distances = %d\'-%.1f\"", dist3.feet, dist3.inch); return 0;
}
void add(struct distance d1,struct distance d2, struct distance *d3)
{
d3-> feet = d1.feet + d2.feet; d3-> inch = d1.inch + d2.inch; if (d3->inch >= 12)
{
d3->inch -= 12;
++d3->feet;
}
}

Output:

First distance Enter feet: 12


Enter inch: 6.8 Second distance Enter feet: 5
Enter inch: 7.5
Sum of distances = 18'-2.3"

121
Structure and Pointer
Structures can be created and accessed using pointers. A pointer variable of a structure can be created as below:

struct name
{
member1; member2;
.
.
.
};

int main()
{
struct name *ptr;
}

Here, the pointer variable of type struct name is created.

Accessing structure's member through pointer

A structure's member can be accesssed through pointer in two ways: Referencing pointer to another address

to access memory

Using dynamic memory allocation

1. Referencing pointer to another address to access the memory Consider an example to access

structure's member through pointer. #include<stdio.h>

typedef struct person


{
int age;
float weight;
};

int main()
{
struct person *personPtr, person1;
personPtr = &person1; // Referencing pointer to memory address of person1
printf("Enterinteger: ");
scanf("%d",&(*personPtr).age);

122
printf("Enter number: "); scanf("%f",&(*personPtr).weight); printf("Displaying: "); printf("%d
%f",(*personPtr).age,(*personPtr).weight); return 0;
}

In this example, the pointer variable of type struct person is referenced to the address of person1. Then,
only the structure member through pointer can can accessed.

Using -> operator to access structure pointer member Structure pointer member can also be accessed

using -> operator. (*personPtr).age is same as personPtr->age

(*personPtr).weight is same as personPtr->weight

2. Accessing structure member through pointer using dynamic memory allocation

To access structure member using pointers, memory can be allocated dynamically using malloc() function
defined under "stdlib.h" header file.

Syntax to use malloc()

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

Example to use structure's member through pointer using malloc() function.

#include<stdio.h> #include<stdlib.h> struct person {


int age;
float weight; char name[30];
};
int main()
{
struct person *ptr; int i, num;
printf("Enter number of persons: "); scanf("%d", &num);
ptr = (struct person*) malloc(num * sizeof(struct person));

// Above statement allocates the memory for n structures with pointer personPtr pointing to base
address */ for(i = 0; i < num; ++i)

123
{
printf("Enter name, age and weight of the person respectively:\n"); scanf("%s%d%f", &(ptr+i)-
>name, &(ptr+i)->age, &(ptr+i)->weight);
}
printf("Displaying Infromation:\n"); for(i = 0; i < num; ++i)
printf("%s\t%d\t%.2f\n", (ptr+i)->name, (ptr+i)->age, (ptr+i)->weight); return 0;
}

Output

Enter number of persons: 2


Enter name, age and weight of the person respectively:
Adam

2
3.2

Enter name, age and weight of the person respectively: Eve 6 2.3

Displaying Information:

Adam 2 3.20
Eve 6 2.30

In C, structure can be passed to functions by two methods:

 Passing by value (passing actual value as argument)

 Passing by reference (passing address of an argument)

Passing structure by value

A structure variable can be passed to the function as an argument as a normal variable.

If structure is passed by value, changes made to the structure variable inside the function definition
does not reflect in the originally passed structure variable.

C program to create a structure student, containing name and roll and display the information.

#include <stdio.h>

124
struct student
{
char name[50]; int roll;
};

void display(struct student stu);

// function prototype should be below to the structure declaration otherwise compiler shows error
int main()
{
struct student stud; printf("Enterstudent's name: "); scanf("%s",&stud.name); printf("Enter
rollnumber:"); scanf("%d",&stud.roll);
display(stud); // passing structure variable stud as argument return 0;
}
void display(struct student stu){ printf("Output\nName: %s",stu.name); printf("\nRoll:
%d",stu.roll);
}

Output

Enter student's name: Kevin Amla Enter roll number: 149

Output

Name: Kevin Amla Roll: 149

Passing structure by reference

The memory address of a structure variable is passed to function while passing it by reference.

If structure is passed by reference, changes made to the structure variable inside function definition
reflects in the originally passed structure variable.

C program to add two distances (feet-inch system) and display the result without the return
statement.

#include <stdio.h>

125
struct distance
{
int feet; float inch;
};

void add(struct distance d1,struct distance d2, struct distance *d3); int main()
{
struct distance dist1, dist2, dist3; printf("First distance\n"); printf("Enter feet: "); scanf("%d",
&dist1.feet); printf("Enter inch: "); scanf("%f", &dist1.inch); printf("Second distance\n");
printf("Enter feet: "); scanf("%d", &dist2.feet); printf("Enter inch: "); scanf("%f", &dist2.inch);
add(dist1, dist2, &dist3);

//passing structure variables dist1 and dist2 by value whereas passing structure variable dist3 by
reference

printf("\nSum of distances = %d\'-%.1f\"", dist3.feet, dist3.inch); return 0;


}
void add(struct distance d1,struct distance d2, struct distance *d3)
{

//Adding distances d1 and d2 and storing it in d3 d3-

>feet = d1.feet + d2.feet;

d3->inch = d1.inch + d2.inch;

if (d3->inch >= 12) { /* if inch is greater or equal to 12, converting it to feet. */ d3-
>inch -= 12;
++d3->feet;
}
}

126
Output

First distance Enter feet: 12


Enter inch: 6.8

Second distance Enter feet: 5


Enter inch: 7.5

Sum of distances = 18'-2.3"

In this program, structure variables dist1 and dist2 are passed by value to the addfunction (because
value of dist1 and dist2 does not need to be displayed in main function).

But, dist3 is passed by reference ,i.e, address of dist3 (&dist3) is passed as an argument.

Due to this, the structure pointer variable d3 inside the add function points to the address of dist3
from the calling main function. So, any change made to the d3 variable is seen in dist3 variable in
main function.

As a result, the correct sum is displayed in the output.

Self Referential Structures:

Self referential structures contain a pointer member that points to a structure of the same structure
type.
In other words, a self-referential C structure is the one which includes a pointer to an instance of
itself.

Syntax of Self-Referential Structure in C Programming

struct demo
{
Data_type member1, member2; struct demo *ptr1, *ptr2;
}

127
As you can see in the syntax, ptr1 and ptr2 are structure pointers that are pointing to the structure
demo, so structure demo is a self referential structure. These types of data structures are helpful in
implementing data structures like linked lists and trees.

It is an error to use a structure variable as a member of its own struct type structure or union type
union, respectively.

Self Referential Structure Example struct node


{
int data;
struct node *nextPtr;
}

nextPtr
 is a pointer member that points to a structure of the same type as the one being declared.
 is referred to as a link. Links can tie one node to another node.

The concept of linked lists, stacks, queues, trees and many others works on the principle of self-
referential structures.
One important point worth noting is that you cannot reference the typedef that you create within
the structure itself in C programming.

An example of Self-Referential Structure in C #include<stdio.h>


#include<stdlib.h>-
struct node //structure of the node in the list
{
int info;
struct node * link;
};
int main()
{
int choice;
typedef struct node NODE; NODE *PTR, *START;
START = NULL;//Initialising START to NULL while(1)
{
printf("\n1.Enter the new node at the start\n"); printf("2.Display the elements of the list\n");

128
printf("3.Exit\n"); printf("Enter Choice\n"); scanf("%d",&choice); switch(choice)
{
case 1:PTR = (NODE*)malloc(sizeof(NODE)); //Allocating Memory to new node printf("Enter
the number you want to enter at the start\n");
scanf("%d",&PTR->info); if(START == NULL)
{
START = PTR; PTR->link = NULL;
}
else
{
PTR->link = START; START = PTR;
}
break;
case 2:PTR = START;
printf("The elements in the list are::\n"); while(PTR->link != NULL)
{
printf("%d\t",PTR->info); PTR = PTR->link;
}
printf("%d",PTR->info); break;
case 3:exit(1); break;
default: printf("\nEnter Valid Choice");
}
}
return 0;
}

Unions in C Language
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.

129
#include<stdio.h> struct student
{
char sname[20]; char fname[50]; int marks;
}s;

main()
{
printf("size of union=%d",sizeof(union student));
}

Output:size of union =50


Maximum size of the variable is the size of union so its size is 50.

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;

130
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

Syntax for accessing any union member is similar to accessing structure members, union test
{
int a; float b; char c;
}t;

t.a; //to access members of union t t.b;


t.c;

Time for an Example

#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);

131
printf("%f\n", it.b);
printf("%c\n", it.ch);

return 0;
}

output
-26426
20.1999

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.

Bit fields

Suppose your C program contains a number of TRUE/FALSE variables grouped in a structure


calle status, as follows:

struct
{
unsigned int widthValidated; unsigned int heightValidated;
} status;

This structure requires 8 bytes of memory space but in actual we are going to store either 0 or 1 in
each of the variables. The C programming language offers a better way to utilize the memory
space in such situation. If you are using such variables inside a structure then you can define the
width of a variable which tells the C compiler that you are going to use only those number of
bytes. For example, above structure can be re-written as follows:

struct
{
unsigned int widthValidated : 1; unsigned int heightValidated : 1;
} status

132
Now, the above structure will require 4 bytes of memory space for status variable but only 2 bits will be
used to store the values. If you will use up to 32 variables each one with a width of 1 bit , then also status
structure will use 4 bytes, but as soon as you will have 33 variables, then it will allocate next slot of the
memory and it will start using 8 bytes. Let us check the following example to understand the concept:

#include <stdio.h> #include <string.h>


/* define sim ple structure * / struct
{
unsigned int widthValidated; unsigned int heightValidated;
} status1;
/* define a structure with bit fields * / struct
{
unsigned int widthValidated : 1; unsigned int heightValidated : 1;
} status2; int m ain( )
{
printf( "Mem ory size occupied by status1 : %d\n", sizeof(status1)); printf( "Mem ory size
occupied by status2 : %d\n", sizeof(status2)); return 0;
}

When the above code is compiled and executed, it produces the above result: Memory size

occupied by status1 : 8
Memory size occupied by status2 : 4

Bit Field Declaration

The declaration of a bit-field has the form inside a structure: struct


{
type [member_name] : width ;
};

Below the description of variable elements of a bit field:

133
Elements Description

Type An integer type that determines how the bit-field's value is

interpreted. The type may be int, signed int, unsigned int.

member_ The name of thebit-field.


name
Width The number of bits in the bit-field. The width must be less than
or equal to the bit width of the specified type.

The variables defined with a predefined width are called bit fields. A bit field can hold more than a
single bit for example if you need a variable to store a value from 0 to 7 only then you can define a
bit field with a width of 3 bits as follows:

struct
{
unsigned int age :3;
} Age;

The above structure definition instructs C compiler that age variable is going to use only 3 bits to
store the value, if you will try to use more than 3 bits then it will not allow you to do so.

Let us try the following example: #include <stdio.h>


#include <string.h> struct
{
unsigned int age : 3;
} Age;
int m ain( )
{
Age.age = 4;
printf( "Sizeof( Age ) : %d\n", sizeof(Age) ); printf( "Age.age : %d\n",Age.age );
Age.age = 7;
printf( "Age.age : %d\n", Age.age ); Age.age = 8;
printf( "Age.age : %d\n", Age.age ); return 0;
}

134
When the above code is compiled it will compile with warning and when executed, it produces the
following result:

Sizeof( Age) :4
Age.age : 4
Age.age : 7
Age.age : 0

Typedef:

The C programming language provides a keyword called typedef, which you can use to give a
type, a new name.

Syntax:

typedef data_type new_name;

typedef: It is a keyword.
data_type: It is the name of any existing type or user defined type created using structure/union.
new_name: alias or new name you want to give to any existing type or user defined type.

Following is an example to define a term BYTE for one-byte numbers − typedef unsigned char
BYTE;

After this type definition, the identifier BYTE can be used as an abbreviation for the type unsigned
char, for example..

BYTE b1, b2;

By convention, uppercase letters are used for these definitions to remind the user that the type
name is really a symbolic abbreviation, but you can use lowercase, as follows −

typedef unsigned char byte;

You can use typedef to give a name to your user defined data types as well. For example, you can
use typedef with structure to define a new data type and then use that data type to define structure
variables directly as follows −

#include <stdio.h> #include <string.h> typedef struct Books { char title[50];


char author[50]; char subject[100];

135
int book_id;
} Book; int main( )
{
Book book;
strcpy( book.title, "C Programming"); strcpy( book.author, "Nuha Ali");
strcpy( book.subject, "C Programming Tutorial"); book.book_id = 6495407;
printf( "Book title : %s\n", book.title); printf( "Book author : %s\n",book.author); printf( "Book
subject : %s\n", book.subject);
printf( "Book book_id : %d\n", book.book_id); return 0;
}

OUTPUT:
Book title : C Programming Book author : Nuha Ali
Book subject : C Programming Tutorial Book book_id : 6495407

Structures with typedef:

Consider the following student structure struct student

int mark [2];

char name [10]; float average;

Variable for the above structure can be declared in two ways.


st
1 way :

struct student record; /* for normal variable */ struct student *record; /* for pointer variable */

136
nd
2 way :

typedef struct student status;

When we use “typedef” keyword before struct <tag_name> like above, after that we can simply use type
definition “status” in the C program to declare structure variable. Now, structure variable declaration will
be, “status record”. This is equal to “struct student record”. Type definition for “struct student” is status.
i.e. status = “struct student”.

An Alternative Way for Structure Declaration Using Typedef in C:

typedef struct student


{
int mark [2];
char name [10]; float average;
} status;

To declare structure variable, we can use the below statements. status record1; /* record 1 is

structure variable */ status record2; /* record 2 is structure variable */

// Structure using typedef:

#include <stdio.h> #include <string.h> typedef struct student


{
int id;
char name[20]; float percentage;
} status; int main()
{
status record; record.id=1;
strcpy(record.name, "Raju"); record.percentage = 86.5; printf(" Id is: %d \n", record.id);
printf(" Name is: %s \n", record.name); printf(" Percentage is: %f \n", record.percentage);
return 0;
}

137
OUTPUT:

Id is: 1

Name is: Raju Percentage is: 86.500000 Another Example

#include <stdio.h> #include <limits.h> int main()


{
typedef long long int LLI; printf("Storage size for long long
int data " \"type : %ld \n", sizeof(LLI)); return 0;
}

OUTPUT: Storage size for long long int data type : 8

Enumeration data type:

An enumeration is a user-defined data type that consists of integral constants. To define an


enumeration, keyword enum is used.

Syntax:
enum flag {const1, const2,……constN};

Here, name of the enumeration is flag. Constants like const1, const2,............., constN are values
of type flag.

By default, const1 is 0, const2 is 1 and so on. You can change default values of enum elements
during declaration (if necessary).

// Changing the default value of enum elements enum suit{

club=0; diamonds=10; hearts=20; spades=3;

};

138
Declaration of enumerated variable

Above code defines the type of the data but, no any variable is created. Variable of type enum can
be created as:

enum boolean{ false; true;

};

enum boolean check;

Here, a variable check is declared which is of type enum boolean.

Example of enumerated type

#include <stdio.h>
enum week{ sunday, monday, tuesday, wednesday, thursday, friday, saturday}; int main(){
enum week today; today=wednesday; printf("%d day",today+1); return 0;
}

Output 4 day

139

You might also like

pFad - Phonifier reborn

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

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


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy