0% found this document useful (0 votes)
2 views45 pages

Unit 3 Pre Processor Directives Notes APC

The document provides an overview of the C preprocessor, detailing its role in processing source code before compilation, including steps like generating expanded source code and executable files. It outlines various preprocessor directives such as #define, #include, and conditional compilation directives, explaining their functions and providing examples. Additionally, it discusses macros, file inclusion, and other directives like #undef and #pragma, along with special operators for string manipulation.

Uploaded by

anjaliparikh1306
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views45 pages

Unit 3 Pre Processor Directives Notes APC

The document provides an overview of the C preprocessor, detailing its role in processing source code before compilation, including steps like generating expanded source code and executable files. It outlines various preprocessor directives such as #define, #include, and conditional compilation directives, explaining their functions and providing examples. Additionally, it discusses macros, file inclusion, and other directives like #undef and #pragma, along with special operators for string manipulation.

Uploaded by

anjaliparikh1306
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

APC_IIIrd_UNIT_NOTES Rakesh Pandit

C Preprocessor: -
Preprocessors are programs that process the source code before compilation.
Several steps are involved between writing a program and executing a program in C.

You can see the intermediate steps in the above diagram. The source code written by
programmers is first stored in a file, let the name be “program.c“. This file is then
processed by preprocessors and an expanded source code file is generated named
“program.i”. This expanded file is compiled by the compiler and an object code file is
generated named “program.obj”. Finally, the linker links this object code file to the
object code of the library functions to generate the executable file “program.exe”.

Preprocessor Directives in C
Preprocessor programs provide preprocessor directives that tell the compiler to
preprocess the source code before compiling.

All of these preprocessor directives begin with a ‘#’ (hash) symbol.

The ‘#’ symbol indicates that whatever statement starts with a ‘#’ will go to the
preprocessor program to get executed. We can place these preprocessor directives
anywhere in our program.

Examples of some preprocessor directives are: #include, #define, #ifndef, etc.

pg. 1
APC_IIIrd_UNIT_NOTES Rakesh Pandit
Note Remember that the # symbol only provides a path to the preprocessor, and a
command such as include is processed by the preprocessor program. For example,
#include will include the code or content of the specified file in your program.

List of preprocessor directives in C:-


The following table lists all the preprocessor directives in C:

Preprocessor Directives Description

#define Used to define a macro

#undef Used to undefine a macro

#include Used to include a file in the source code program

Used to include a section of code if a certain macro is


#ifdef
defined by #define

Used to include a section of code if a certain macro is not


#ifndef
defined by #define

#if Check for the specified condition

#else Alternate code that executes when #if fails

#endif Used to mark the end of #if, #ifdef, and #ifndef

These preprocessors can be classified based on the type of function they perform.
Types of C Preprocessors
There are 4 Main Types of Preprocessor Directives:
1. Macros
2. File Inclusion
3. Conditional Compilation
4. Other directives
Let us now learn about each of these directives in detail.
1. Macros
In C, Macros are pieces of code in a program that is given some name. Whenever this
name is encountered by the compiler, the compiler replaces the name with the actual
piece of code. The ‘#define’ directive is used to define a macro.

pg. 2
APC_IIIrd_UNIT_NOTES Rakesh Pandit
Syntax of Macro Definition
#define token value
where after preprocessing, the token will be expanded to its value in the program.
Example of Macro
// C Program to illustrate the macro
#include <stdio.h>

// macro definition
#define LIMIT 5

int main()
{
for (int i = 0; i < LIMIT; i++) {
printf("%d \n", i);
}

return 0;
}

Output
0
1
2
3
4
In the above program, when the compiler executes the word LIMIT, it replaces it with
5. The word ‘LIMIT’ in the macro definition is called a macro template and ‘5’ is
macro expansion.
Note There is no semi-colon (;) at the end of the macro definition. Macro definitions do
not need a semi-colon to end.
There are also some Predefined Macros in C which are useful in providing various
functionalities to our program.
Macros With Arguments
We can also pass arguments to macros. Macros defined with arguments work
similarly to functions.
Example
#define foo(a, b) a + b
#define func(r) r * r
Let us understand this with a program:

// C Program to illustrate function like macros

pg. 3
APC_IIIrd_UNIT_NOTES Rakesh Pandit

#include <stdio.h>

// macro with parameter


#define AREA(l, b) (l * b)

int main()
{
int l1 = 10, l2 = 5, area;

area = AREA(l1, l2);

printf("Area of rectangle is: %d", area);

return 0;
}

Output
Area of rectangle is: 50
We can see from the above program that whenever the compiler finds AREA(l, b) in
the program, it replaces it with the statement (l*b). Not only this, but the values passed
to the macro template AREA(l, b) will also be replaced in the statement (l*b).
Therefore AREA(10, 5) will be equal to 10*5.

A macro is a segment of code which is replaced by the value of macro. Macro is


defined by #define directive. There are two types of macros:

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

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:

1. #define PI 3.14

Here, PI is the macro name which will be replaced by the value 3.14.

Example 1: #define preprocessor

#include <stdio.h>
#define PI 3.1415

pg. 4
APC_IIIrd_UNIT_NOTES Rakesh Pandit

int main() {
float radius, area; printf("Enter the radius: ");
scanf("%f", &radius);

// Notice, the use of PI

area = PI*radius*radius;

printf("Area=%.2f",area);
return 0; }

Function-like Macros

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

Function like Macros

You can also define macros that work in a similar way as a function call. This is
known as function-like macros. For example,

#define circleArea(r) (3.1415*(r)*(r))

Every time the program encounters


circleArea(argument), it is replaced by
(3.1415*(argument)*(argument)).
Suppose, we passed 5 as an argument then, it
expands as below:

circleArea(5) expands to (3.1415*5*5)

pg. 5
APC_IIIrd_UNIT_NOTES Rakesh Pandit

Example 2: Using #define preprocessor


#include <stdio.h>
#define PI 3.1415
#define circleArea(r) (PI*r*r)

int main() {
float radius, area;

printf("Enter the radius:


"); scanf("%f", &radius);
area = circleArea(radius);
printf("Area = %.2f", area);

return 0;
}

Macro Value

__DATE__ A string containing the current date.

__FILE__ A string containing the file name.

__LINE__ An integer representing the current line number.

__STDC__ If follows ANSI standard C, then the value is a nonzero


integer.

__TIME__ A string containing the current time.

pg. 6
APC_IIIrd_UNIT_NOTES Rakesh Pandit

Predefined Macros

Here are some predefined macros in C programming.


Example 3: Get current time using __TIME__

The following program outputs the current time using __TIME__ macro.

#include <stdio.h>
int main()
{
printf("Current time: %s",__TIME__); }

Output

Current time: 19:54:39

2. File Inclusion
This type of preprocessor directive tells the compiler to include a file in the source
code program. The #include preprocessor directive is used to include the header files
in the C program.
There are two types of files that can be included by the user in the program:
Standard Header Files
The standard header files contain definitions of pre-defined functions like printf(),
scanf(), etc. These files must be included to work with these functions. Different
functions are declared in different header files.
For example, standard I/O functions are in the ‘iostream’ file whereas functions that
perform string operations are in the ‘string’ file.
Syntax
#include <file_name>
where file_name is the name of the header file to be included. The ‘<‘ and ‘>’
brackets tell the compiler to look for the file in the standard directory.
User-defined Header Files
When a program becomes very large, it is a good practice to divide it into smaller files
and include them whenever needed. These types of files are user-defined header files.
Syntax
#include "filename"
The double quotes ( ” ” ) tell the compiler to search for the header file in the source
file’s directory.
3. Conditional Compilation

pg. 7
APC_IIIrd_UNIT_NOTES Rakesh Pandit
Conditional Compilation in C directives is a type of directive that helps to compile a
specific portion of the program or to skip the compilation of some specific part of the
program based on some conditions. There are the following preprocessor directives
that are used to insert conditional code:
1. #if Directive
2. #ifdef Directive
3. #ifndef Directive
4. #else Directive
5. #elif Directive
6. #endif Directive
#endif directive is used to close off the #if, #ifdef, and #ifndef opening directives which
means the preprocessing of these directives is completed.
Syntax
#ifdef macro_name
// Code to be executed if macro_name is defined
#ifndef macro_name
// Code to be executed if macro_name is not defined
#if constant_expr
// Code to be executed if constant_expression is true
#elif another_constant_expr
// Code to be excuted if another_constant_expression is true
#else
// Code to be excuted if none of the above conditions are true
#endif
If the macro with the name ‘macro_name‘ is defined, then the block of statements will
execute normally, but if it is not defined, the compiler will simply skip this block of
statements.
Example
The below example demonstrates the use of #include #if, #elif, #else, and #endif
preprocessor directives.

//program to demonstrates the use of #if, #elif, #else,


// and #endif preprocessor directives.
#include <stdio.h>

// defining PI
#define PI 3.14159

int main()
{

#ifdef PI
printf("PI is defined\n");

pg. 8
APC_IIIrd_UNIT_NOTES Rakesh Pandit

#elif defined(SQUARE)
printf("Square is defined\n");
#else
#error "Neither PI nor SQUARE is defined"
#endif

#ifndef SQUARE
printf("Square is not defined");
#else
cout << "Square is defined" << endl;
#endif

return 0;
}

Output
PI is defined
Square is not defined

4. Other Directives
Apart from the above directives, there are two more directives that are not commonly
used. These are:
1. #undef Directive
2. #pragma Directive
1. #undef Directive
The #undef directive is used to undefine an existing macro. This directive works as:
#undef LIMIT
Using this statement will undefine the existing macro LIMIT. After this statement,
every “#ifdef LIMIT” statement will evaluate as false.
Example
The below example demonstrates the working of #undef Directive.

#include <stdio.h>

// defining MIN_VALUE

#define MIN_VALUE 10

int main() {
// Undefining and redefining MIN_VALUE
printf("Min value is: %d\n",MIN_VALUE);

//undefining max value

pg. 9
APC_IIIrd_UNIT_NOTES Rakesh Pandit

#undef MIN_VALUE

// again redefining MIN_VALUE


#define MIN_VALUE 20

printf("Min value after undef and again redefining it: %d\n", MIN_VALUE);

return 0;
}

Output
Min value is: 10
Min value after undef and again redefining it: 20

2. #pragma Directive
This directive is a special purpose directive and is used to turn on or off some features.
These types of directives are compiler-specific, i.e., they vary from compiler to
compiler.
Syntax
#pragma directive
Some of the #pragma directives are discussed below:
1. #pragma startup: These directives help us to specify the functions that are
needed to run before program startup (before the control passes to main()).
2. #pragma exit: These directives help us to specify the functions that are
needed to run just before the program exit (just before the control returns
from main()).
Below program will not work with GCC compilers.
Example
The below program illustrate the use of #pragma exit and pragma startup

// C program to illustrate the #pragma exit and pragma


// startup
#include <stdio.h>

void func1();
void func2();

// specifying funct1 to execute at start


#pragma startup func1
// specifying funct2 to execute before end
#pragma exit func2

void func1() { printf("Inside func1()\n"); }

pg. 10
APC_IIIrd_UNIT_NOTES Rakesh Pandit

void func2() { printf("Inside func2()\n"); }

// driver code
int main()
{
void func1();
void func2();
printf("Inside main()\n");

return 0;
}

Expected Output
Inside func1()
Inside main()
Inside func2()
The above code will produce the output as given below when run on GCC compilers:
Inside main()c
This happens because GCC does not support #pragma startup or exit. However, you
can use the below code for the expected output on GCC compilers.

#include <stdio.h>

void func1();
void func2();

void __attribute__((constructor)) func1();


void __attribute__((destructor)) func2();

void func1()
{
printf("Inside func1()\n");
}

void func2()
{
printf("Inside func2()\n");
}

int main()
{
printf("Inside main()\n");

return 0;
}

pg. 11
APC_IIIrd_UNIT_NOTES Rakesh Pandit

Output
Inside func1()
Inside main()
Inside func2()
In the above program, we have used some specific syntaxes so that one of the
functions executes before the main function and the other executes after the main
function.
#pragma warn Directive
This directive is used to hide the warning message which is displayed during
compilation. We can hide the warnings as shown below:
• #pragma warn -rvl: This directive hides those warnings which are raised
when a function that is supposed to return a value does not return a value.
• #pragma warn -par: This directive hides those warnings which are raised
when a function does not use the parameters passed to it.
• #pragma warn -rch: This directive hides those warnings which are raised
when a code is unreachable. For example, any code written after
the return statement in a function is unreachable.

pg. 12
APC_IIIrd_UNIT_NOTES Rakesh Pandit

Stringification (#) and Token Passing Operator (#) in C:-


There are two special preprocessor directives in the C programming language for
string operations.
These are:
Stringizing operator (#)
Token-Pasting operator (##)
Both these operators are mainly used to deal with strings.

The Stringizing Operator (#):-


The stringizing operator (#) converts macro parameters to string literals without
expanding the parameter definition. It is only used in conjunction with function-like
macros (macros that take arguments). When a macro parameter is preceded by a
leading '#,' the preprocessor replaces it with the literal text of the actual argument,
converted to a string constant.
Syntax
The syntax of the stringizing operator (#) is as follows:
#define MACRO_NAME(param) #param

You can also try this code with Online C Compiler

#define: It is a preprocessor directive in C.


MACRO_NAME: It represents the macro that has to be replaced by its value
throughout the program.
Param: It represents the parameter of the macro. We use the macro anywhere in the
program and provide the value of the param between the braces () of the macro, which
has to be converted to string literal.
#: It is the Stringizing operator.
Example 1
// C program to demonstrate Stringizing operator (#)

#include <stdio.h>
// Stringizing operator #
// it converts the input into a String literal
#define STRINGIZING_OPERATOR(input) #input

pg. 13
APC_IIIrd_UNIT_NOTES Rakesh Pandit
int main()
{

printf(STRINGIZING_OPERATOR(Coding Ninjas));
printf("\n" STRINGIZING_OPERATOR(12345));
printf("\n" STRINGIZING_OPERATOR(CodingNinjas @ 12345));

return 0;
}

You can also try this code with Online C Compiler

Output:
Coding Ninjas
12345
CodingNinjas @ 12345

Explanation
In C, we use the stringize operator to convert a token to a string. It converts the macro
parameter to a string. The preprocessor turns the line
printf(demoOfStringizingOperator(Coding Ninjas)); into printf(“Coding Ninjas”);
Example 2
// C program to demonstrate Stringizing operator (#)

#include <stdio.h>
// Stringizing operator #
// it converts the input into a String literal
#define DEMO1(val) #val
int main()
{

printf(DEMO1( Message without quotes));

// The above statement is equivalent to


printf("\nMessage without quotes");

return 0;
}

Output:

pg. 14
APC_IIIrd_UNIT_NOTES Rakesh Pandit
Message without quotes
Message without quotes

Example 3
// C program to demonstrate Stringizing operator (#)

#include <stdio.h>
// Stringizing operator #
// it converts the input into a String literal
#define DEMO2(val) #val
int main()
{

printf(DEMO2(DEMO2(Nothing will happen)));

// The above line will simply print DEMO2(Nothing will happen) because
// the stringizing operator does not expand the macros
return 0;
}

Output:
DEMO2(Nothing will happen)

Explanation
The macros passed as a value to the macro are not expanded. It will simply print the
message as it is inside the macro.
Example 4
// C program to demonstrate Stringizing operator (#)

#include <stdio.h>
// Stringizing operator #
// it converts the input into a String literal
#define DEMO3(val) printf(#val)
int main()
{

DEMO3(I am an Indian);
printf("\n");

pg. 15
APC_IIIrd_UNIT_NOTES Rakesh Pandit
// This will print the message with the double quotes
DEMO3("I am a proud Indian");
return 0;
}

Output:
I am an Indian
"I am a proud Indian"

The Token-Pasting Operator (##):-

The Token Pasting operator is also a preprocessor operator. It instructs the compiler
to add or concatenate two tokens into a single string. This operator is used in the
macro definition.
When expanding macros, it is frequently useful to combine two tokens into one. This
is known as token concatenation or token pasting. Token pasting is performed by the
'##' pre-processing operator. When a macro is expanded, the two tokens on either
side of each '##' operator are combined to form a single token that replaces the '##'
and the two original tokens in the macro expansion.
The token pasting (##) operator simply removes any surrounding white space and
concatenates (joins together) the non-whitespace characters.
Syntax
The syntax of the token-pasting operator (##) is as follows:
#define MACRO_NAME(param1, param2) param1##param2

#define: It is a preprocessor directive in C.


MACRO_NAME: It represents the macro that has to be replaced by its value
throughout the program.
Param1 / param2: The parameters that are passed to the macros for concatenation.
##: This is the token-pasting operator.
Example 1
// C program to demonstrate token-pasting operator (##)

#include <stdio.h>

#define TOKEN_PASTING(param1, param2) param1##param2


int main()

pg. 16
APC_IIIrd_UNIT_NOTES Rakesh Pandit
{

printf("The concatenated result is: %d",TOKEN_PASTING(1234,56789));


return 0;
}

Output:
The concatenated result is: 123456789

Example 2
// C program to demonstrate token-pasting operator (##)

#include <stdio.h>

#define TOKEN_PASTING(param1, param2) param1##param2


int main()
{
int val1=100;

//val2 value will be 15


int val2=TOKEN_PASTING(1,5);

printf("The value of variable val2 is : %d", val2);

// equivalent to 100+15
printf("\nSum of val1 and val2 is : %d", (val1+val2));
return 0;
}

Output:
The value of variable val2 is : 15
Sum of val1 and val2 is : 115

Example 3
// C program to demonstrate token-pasting operator (##)

#include <stdio.h>

pg. 17
APC_IIIrd_UNIT_NOTES Rakesh Pandit
#define TOKEN_PASTING(param1, param2) param1##param2
int main()
{
// The below statement will give a compilation error.
//You do not need to use ## to concatenate strings.
//C already concatenates adjacent strings.

printf("%s",TOKEN_PASTING(Coding, Ninjas));
return 0;
}
Output:
Compilation error.

Explanation
The above code will result in a compilation error. The reason is that C already
concatenates adjacent strings. For e.g. printf("Coding""Ninjas"); will print
CodingNinjas.
However, we can use the stringizing operator (#) to concatenate two strings. The
below example demonstrates the same.
Example 4
// C program to demonstrate string concatenation

#include <stdio.h>

#define STRINGIZING_OPERATOR(param) #param


int main()
{

// Using # operator to concatenate two strings


// Simply call STRINGIZING_OPERATOR() twice with two parameters and
// it will concatenate the two parameters as strings.

printf(STRINGIZING_OPERATOR(Coding) STRINGIZING_OPERATOR(Ninjas));
return 0;
}

Output:
CodingNinjas

pg. 18
APC_IIIrd_UNIT_NOTES Rakesh Pandit
Application
## operator allows you to concatenate actual arguments during macro expansion. If a
parameter in the replacement text is adjacent to a ##, the ## and surrounding white
space are removed, and the result is re-scanned.
It is also used for logs in our program and to avoid repetitive typing.

C typedef
The typedef is a keyword that is used to provide existing data types with a new
name. The C typedef keyword is used to redefine the name of already existing data
types.
When names of datatypes become difficult to use in programs, typedef is used with
user-defined datatypes, which behave similarly to defining an alias for commands.

Syntax
typedef existing_name alias_name;
After this declaration, we can use the alias_name as if it were the
real existing_name in out C program.
Example of typedef in C
typedef long long ll;
Below is the C program to illustrate how to use typedef.

// C program to implement typedef


#include <stdio.h>

// defining an alias using typedef


typedef long long ll;

// Driver code
int main()
{
// using typedef name to declare variable
ll var = 20;
printf("%ld", var);

pg. 19
APC_IIIrd_UNIT_NOTES Rakesh Pandit

return 0;
}

Output
20

Use of typedef in C
Following are some common uses of the typedef in C programming:
• The typedef keyword gives a meaningful name to the existing data type
which helps other users to understand the program more easily.
• It can be used with structures to increase code readability and we don’t
have to type struct repeatedly.
• The typedef keyword can also be used with pointers to declare multiple
pointers in a single statement.
• It can be used with arrays to declare any number of variables.
1. typedef struct
typedef can also be used with structures in the C programming language. A new
data type can be created and used to define the structure variable.

Example 1: Using typedef to define a name for a structure

• C

// C program to implement
// typedef with structures
#include <stdio.h>
#include <string.h>

// using typedef to define an alias for structure


typedef struct students {
char name[50];

pg. 20
APC_IIIrd_UNIT_NOTES Rakesh Pandit

char branch[50];
int ID_no;
} stu;

// Driver code
int main()
{
stu st;
strcpy(st.name, "Kamlesh Joshi");
strcpy(st.branch, "Computer Science And Engineering");
st.ID_no = 108;

printf("Name: %s\n", st.name);


printf("Branch: %s\n", st.branch);
printf("ID_no: %d\n", st.ID_no);
return 0;
}

Output
Name: Kamlesh Joshi
Branch: Computer Science And Engineering
ID_no: 108

2. typedef with Pointers


typedef can also be used with pointers as it gives an alias name to the pointers.
Typedef is very efficient while declaring multiple pointers in a single statement
because pointers bind to the right on the simple declaration.
Example:
typedef int* Int_ptr;
Int_ptr var, var1, var2;
In the above statement var, var1, and var2 are declared as pointers of type int which
helps us to declare multiple numbers of pointers in a single statement.

Example 2: Using typedef to define a name for pointer type.

// C program to implement
// typedef with pointers

pg. 21
APC_IIIrd_UNIT_NOTES Rakesh Pandit

#include <stdio.h>

typedef int* ptr;

// Driver code
int main()
{
ptr var;
*var = 20;

printf("Value of var is %d", *var);


return 0;
}

Output
Value of var is 20

3. typedef with Array


typedef can also be used with an array to increase their count.
Example:
typedef int arr[20]
Here, arr is an alias for an array of 20 integer elements.
// it's same as Arr[20], two-Arr[20][23];
arr Arr, two-Arr[23];

Example 3: Using typedef to define an alias for Array.

// C program to implement typedef with array


#include <stdio.h>

typedef int Arr[4];

// Driver code
int main()
{
Arr temp = { 10, 20, 30, 40 };
printf("typedef using an array\n");

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


printf("%d ", temp[i]);

pg. 22
APC_IIIrd_UNIT_NOTES Rakesh Pandit

}
return 0;
}

Output

typedef using an array


10 20 30 40

C typedef vs #define
The following are the major difference between the typedef and #define in C:
1. #define is capable of defining aliases for values as well, for instance, you
can define 1 as ONE, 3.14 as PI, etc. Typedef is limited to giving symbolic
names to types only.
2. Preprocessors interpret #define statements, while the compiler interprets
typedef statements.
3. There should be no semicolon at the end of #define, but a semicolon at the
end of typedef.
4. In contrast with #define, typedef will actually define a new type by copying
and pasting the definition values.

Below is the C program to implement #define:

// C program to implement #define


#include <stdio.h>

// macro definition
#define LIMIT 3

// Driver code
int main()

pg. 23
APC_IIIrd_UNIT_NOTES Rakesh Pandit

{
for (int i = 0; i < LIMIT; i++) {
printf("%d \n", i);
}
return 0;
}

Output
0
1
2

pg. 24
APC_IIIrd_UNIT_NOTES Rakesh Pandit

Command Line Arguments in C


In C programming language, command line arguments are the data values that are passed from

command line to our program. Using command line arguments we can control the program execution

from the outside of the program. Generally, all the command line arguments are handled by the main()

method. Generally, the command line arguments can be understood as follows...

Command line arguments are the parameters passing to main() method from the command line.

When command line arguments are passed main() method receives them with the help of two formal

parameters and they are,

• int argc

• char *argv[ ]

int argc - It is an integer argument used to store the count of command line arguments are passed from

the command line.

char *argv[ ] - It is a character pointer array used to store the actual values of command line arguments

are passed from the command line.

• argc (Argument Count): This is an integer that indicates how many arguments were passed to the

program. The count includes the name of the program itself, so argc will always be at least 1.

• argv (Argument Vector): This is an array of character pointers (char *). Each element in this array is a

C string (null-terminated array of characters) representing one of the arguments passed to the

program. argv[0] is the name of the program, and argv[1] to argv[argc-1] are the command line

arguments provided by the user.

Importent Points to be Remembered

The command line arguments are suppurated with SPACE.

Always the first command line argument is file path.

Only string values can be passed as command line arguments.

All the command line arguments are stored in a character pointer array called argv[ ].

pg. 25
APC_IIIrd_UNIT_NOTES Rakesh Pandit

Total count of command line arguments including file path argument is stored in a integer parameter

called argc.

Consider the following example program...

Example Program to illustrate command line arguments in C.


#include<stdio.h>
#include<conio.h>

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

int i;
clrscr() ;

if(argc == 1){
printf("Please provide command line arguments!!!");
return 0;
}
else{
printf("Total number of arguments are - %d and they are\n\n", argc);
for(i=0; i<argc ; i++){
printf("%d -- %s \n", i+1, argv[i]);
}
return 0;
}
}

When execute the above program by passing "Hello welcome to www.btechsmartclass.com" as

command line arguments it produce the following output.

pg. 26
APC_IIIrd_UNIT_NOTES Rakesh Pandit

In the above example program we are passing 4 string arguments (Hello, welcome, to and

www.btechsmartclass.com) but the default first argument is a file path. So, the total count of command

line arguments is 5.

Whenever we want to pass numerical values as command line arguments, they are passed as string

values only and we need to convert them into numerical values in the program. Consider the following

program that calculates the sum of all command line arguments and displays the result.

Example Program to display sum of all command line arguments in C.


#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

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

int i, n, sum = 0;
clrscr() ;

if(argc == 1){
printf("Please provide command line arguments!!!");
return 0;
}
else{
printf("Total number of arguments are - %d and sum of those is ", argc);

pg. 27
APC_IIIrd_UNIT_NOTES Rakesh Pandit
for(i=0; i<argc ; i++){
n = atoi(argv[i]);
sum += n;
}
printf("%d\n", sum);
return 0;
}
}

When execute the above program by passing "10 20 30 40 50" as command line arguments it produce

the following output.

In the above example program we are passing 5 string arguments (10, 20, 30 40 and 50). They are

converted into integer values by using atoi() method which is available in stdlib.h header file.

pg. 28
APC_IIIrd_UNIT_NOTES Rakesh Pandit

Dynamic Memory Allocation in C using malloc(),


calloc(), free() and realloc()

••
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.
Syntax of malloc() in C

pg. 29
APC_IIIrd_UNIT_NOTES Rakesh Pandit
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.


Example of malloc() in C

#include <stdio.h>
#include <stdlib.h>

int main()
{

// This pointer will hold the


// base address of the block created
int* ptr;
int n, i;

// Get the number of elements for the array


printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);

// Dynamically allocate memory using malloc()


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

// Check if the memory has been successfully


// allocated by malloc or not
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0);
}

pg. 30
APC_IIIrd_UNIT_NOTES Rakesh Pandit

else {

// Memory has been successfully allocated


printf("Memory successfully allocated using malloc.\n");

// Get the elements of the array


for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}

// Print the elements of the array


printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}

return 0;
}

Output
Enter number of elements: 5
Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5

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:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for 25 elements each with the size of
the float.

pg. 31
APC_IIIrd_UNIT_NOTES Rakesh Pandit

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


Example of calloc() in C

#include <stdio.h>
#include <stdlib.h>

int main()
{

// This pointer will hold the


// base address of the block created
int* ptr;
int n, i;

// Get the number of elements for the array


n = 5;
printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using calloc()


ptr = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully


// allocated by calloc or not
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {

// Memory has been successfully allocated


printf("Memory successfully allocated using calloc.\n");

// Get the elements of the array


for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}

pg. 32
APC_IIIrd_UNIT_NOTES Rakesh Pandit

// Print the elements of the array


printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}

return 0;
}

Output
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,

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

Example of free() in C

#include <stdio.h>

pg. 33
APC_IIIrd_UNIT_NOTES Rakesh Pandit

#include <stdlib.h>

int main()
{

// This pointer will hold the


// base address of the block created
int *ptr, *ptr1;
int n, i;

// Get the number of elements for the array


n = 5;
printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using malloc()


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

// Dynamically allocate memory using calloc()


ptr1 = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully


// allocated by malloc or not
if (ptr == NULL || ptr1 == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {

// Memory has been successfully allocated


printf("Memory successfully allocated using malloc.\n");

// Free the memory


free(ptr);
printf("Malloc Memory successfully freed.\n");

// Memory has been successfully allocated


printf("\nMemory successfully allocated using calloc.\n");

// Free the memory


free(ptr1);
printf("Calloc Memory successfully freed.\n");
}

return 0;
}

Output
Enter number of elements: 5

pg. 34
APC_IIIrd_UNIT_NOTES Rakesh Pandit
Memory successfully allocated using malloc.
Malloc Memory successfully freed.

Memory successfully allocated using calloc.


Calloc Memory successfully freed.

C realloc() method
“realloc” or “re-allocation” method in C is used to dynamically change the memory
allocation of a previously allocated memory. In other words, if the memory previously
allocated with the help of malloc or calloc is insufficient, realloc can be used
to dynamically re-allocate memory. re-allocation of memory maintains the already
present value and new blocks will be initialized with the default garbage value.
Syntax of realloc() in C
ptr = realloc(ptr, newSize);
where ptr is reallocated with new size 'newSize'.

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


Example of realloc() in C

Output
Enter number of elements: 5

pg. 35
APC_IIIrd_UNIT_NOTES Rakesh Pandit
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,

Enter the new size of the array: 10


Memory successfully re-allocated using realloc.
The elements of the array are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

One another example for realloc() method is:

#include <stdio.h>
#include <stdlib.h>
int main()
{
int index = 0, i = 0, n,
*marks; // this marks pointer hold the base address
// of the block created
int ans;
marks = (int*)malloc(sizeof(
int)); // dynamically allocate memory using malloc
// check if the memory is successfully allocated by
// malloc or not?
if (marks == NULL) {
printf("memory cannot be allocated");
}
else {
// memory has successfully allocated
printf("Memory has been successfully allocated by "
"using malloc\n");
printf("\n marks = %pc\n",
marks); // print the base or beginning
// address of allocated memory
do {
printf("\n Enter Marks\n");
scanf("%d", &marks[index]); // Get the marks
printf("would you like to add more(1/0): ");
scanf("%d", &ans);

if (ans == 1) {
index++;
marks = (int*)realloc(
marks,
(index + 1)

pg. 36
APC_IIIrd_UNIT_NOTES Rakesh Pandit

* sizeof(
int)); // Dynamically reallocate
// memory by using realloc
// check if the memory is successfully
// allocated by realloc or not?
if (marks == NULL) {
printf("memory cannot be allocated");
}
else {
printf("Memory has been successfully "
"reallocated using realloc:\n");
printf(
"\n base address of marks are:%pc",
marks); ////print the base or
///beginning address of
///allocated memory
}
}
} while (ans == 1);
// print the marks of the students
for (i = 0; i <= index; i++) {
printf("marks of students %d are: %d\n ", i,
marks[i]);
}
free(marks);
}
return 0;
}

Output:

pg. 37
APC_IIIrd_UNIT_NOTES Rakesh Pandit

How to dynamically allocate a 2D array in C?


Following are different ways to create a 2D array on the heap (or dynamically allocate a 2D
array).
In the following examples, we have considered ‘r‘ as number of rows, ‘c‘ as number of
columns and we created a 2D array with r = 3, c = 4 and the following values
1 2 3 4
5 6 7 8
9 10 11 12

1) Using a single pointer and a 1D array with pointer arithmetic:


A simple way is to allocate a memory block of size r*c and access its elements using simple
pointer arithmetic.

#include <stdio.h>

#include <stdlib.h>

int main(void)

int r = 3, c = 4;

int* ptr = malloc((r * c) * sizeof(int));

/* Putting 1 to 12 in the 1D array in a sequence */

for (int i = 0; i < r * c; i++)

ptr[i] = i + 1;

/* Accessing the array values as if it was a 2D array */

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

for (int j = 0; j < c; j++)

printf("%d ", ptr[i * c + j]);

printf("\n");

pg. 38
APC_IIIrd_UNIT_NOTES Rakesh Pandit

free(ptr);

return 0;

Output
1 2 3 4
5 6 7 8
9 10 11 12

Output
1 2 3 4 5 6 7 8 9 10 11 12
3) Using pointer to a pointer
We can create an array of pointers also dynamically using a double pointer. Once we have
an array pointers allocated dynamically, we can dynamically allocate memory and for
every row like method 2.

#include <stdio.h>

#include <stdlib.h>

int main()

int r = 3, c = 4, i, j, count;

int** arr = (int**)malloc(r * sizeof(int*));

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

arr[i] = (int*)malloc(c * sizeof(int));

// Note that arr[i][j] is same as *(*(arr+i)+j)

count = 0;

pg. 39
APC_IIIrd_UNIT_NOTES Rakesh Pandit

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

for (j = 0; j < c; j++)

arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

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

for (j = 0; j < c; j++)

printf("%d ", arr[i][j]);

/* Code for further processing and free the

dynamically allocated memory */

for (int i = 0; i < r; i++)

free(arr[i]);

free(arr);

return 0;

Output
1 2 3 4 5 6 7 8 9 10 11 12

4) Using double pointer and one malloc call

#include<stdio.h>

#include<stdlib.h>

int main()

int r=3, c=4, len=0;

int *ptr, **arr;

pg. 40
APC_IIIrd_UNIT_NOTES Rakesh Pandit

int count = 0,i,j;

len = sizeof(int *) * r + sizeof(int) * c * r;

arr = (int **)malloc(len);

// ptr is now pointing to the first element in of 2D array

ptr = (int *)(arr + r);

// for loop to point rows pointer to appropriate location in 2D array

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

arr[i] = (ptr + c * i);

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

for (j = 0; j < c; j++)

arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

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

for (j = 0; j < c; j++)

printf("%d ", arr[i][j]);

return 0;

Output
1 2 3 4 5 6 7 8 9 10 11 12
5) Using a pointer to Variable Length Array.
The dimensions of VLA are bound to the type of the variable. Therefore one form a pointer
to an array with run-time defined shape.
The pointer has to be dereferenced before subscripting with syntax (*arr)[i][j].

#include <stdio.h>

#include <stdlib.h>

pg. 41
APC_IIIrd_UNIT_NOTES Rakesh Pandit

int main()

int row = 3, col = 4, i, j, count;

int (*arr)[row][col] = malloc(sizeof *arr);

count = 0;

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

for (j = 0; j < col; j++)

(*arr)[i][j] = ++count;

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

for (j = 0; j < col; j++)

printf("%d ", (*arr)[i][j]);

free(arr);

return 0;

Output
1 2 3 4 5 6 7 8 9 10 11 12
6) Using a pointer to the first row of VLA
Similar to 5 but allows arr[i][j] syntax.

#include <stdio.h>

#include <stdlib.h>

int main()

pg. 42
APC_IIIrd_UNIT_NOTES Rakesh Pandit

int row = 3, col = 4, i, j, count;

int (*arr)[col] = calloc(row, sizeof *arr);

count = 0;

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

for (j = 0; j < col; j++)

arr[i][j] = ++count;

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

for (j = 0; j < col; j++)

printf("%d ", arr[i][j]);

free(arr);

return 0;

Output
1 2 3 4 5 6 7 8 9 10 11 12

How to write your own header file in C?


•••
As we all know that files with .h extension are called header files in C. These header files
generally contain function declarations which we can be used in our main C program, like
for e.g. there is need to include stdio.h in our C program to use function printf() in the
program. So the question arises, is it possible to create your own header file? The answer to
the above is yes. header files are simply files in which you can declare your own functions
that you can use in your main program or these can be used while writing large C
programs. NOTE:Header files generally contain definitions of data types, function
prototypes and C preprocessor commands. Below is the short example of creating your
own header file and using it accordingly.

pg. 43
APC_IIIrd_UNIT_NOTES Rakesh Pandit
1. Creating myhead.h : Write the below code and then save the file
as myhead.h or you can give any name but the extension should be .h indicating
its a header file.

// It is not recommended to put function definitions

// in a header file. Ideally there should be only

// function declarations. Purpose of this code is

// to only demonstrate working of header files.

void add(int a, int b)

printf("Added value=%d\n", a + b);

void multiply(int a, int b)

printf("Multiplied value=%d\n", a * b);

2. Including the .h file in other program : Now as we need to include stdio.h as


#include in order to use printf() function. We will also need to include the above
header file myhead.h as #include”myhead.h”. The ” ” here are used to instructs
the preprocessor to look into the present folder and into the standard folder of
all header files if not found in present folder. So, if you wish to use angular
brackets instead of ” ” to include your header file you can save it in the standard
folder of header files otherwise. If you are using ” ” you need to ensure that the
header file you created is saved in the same folder in which you will save the C
file using this header file.
3. Using the created header file :

// C program to use the above created header file

#include <stdio.h>

#include "myhead.h"

int main()

add(4, 6);

pg. 44
APC_IIIrd_UNIT_NOTES Rakesh Pandit

/*This calls add function written in myhead.h

and therefore no compilation error.*/

multiply(5, 5);

// Same for the multiply function in myhead.h

printf("BYE!See you Soon");

return 0;

Output:
Added value:10
Multiplied value:25
BYE!See you Soon
NOTE : The above code compiles successfully and prints the above output only if
you have created the header file and saved it in the same folder the above c file is
saved.
Important Points: The creation of header files are needed generally while writing large C
programs so that the modules can share the function definitions, prototypes etc.
• Function and type declarations, global variables, structure declarations and in
some cases, inline functions; definitions which need to be centralized in one file.
• In a header file, do not use redundant or other header files; only minimal set of
statements.
• Don’t put function definitions in a header. Put these things in a separate .c file.
• Include Declarations for functions and variables whose definitions will be visible
to the linker. Also, definitions of data structures and enumerations that are
shared among multiple source files.
• In short, Put only what is necessary and keep the header file concised.

pg. 45

You might also like