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

C Preprocessor Directives Explained

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

C Preprocessor Directives Explained

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

first->data = 10;

#include <stdio.h> first ->next = second;


#include <stdlib.h>
second->data = 20;
struct Node { second->next = third;
int data;
struct Node* next; third->data = 30;
}; third->next = NULL;

int main() { struct Node* temp = first;


struct Node* first = NULL; printf("Linked List: ");
struct Node* second = NULL; while (temp != NULL) {
struct Node* third = NULL; printf("%d -> ", temp->data);
temp = temp->next;
first = (struct Node*)malloc(sizeof(struct Node)); }
second = (struct Node*)malloc(sizeof(struct Node)); printf("NULL\n");
third = (struct Node*)malloc(sizeof(struct Node));
free(first);
free(second);
free(third);
return 0;
}
#include <stdio.h>

void staticfunc() {
static int count = 0;
count++;
printf("Count = %d\n", count);
}

int main() {
staticfunc();
staticfunc();
return 0;
}
Unit 6
static
Preprocessor Directives
•It is a program that processes our source program before it is passed to the compiler.
•All preprocessor directives starts with hash # symbol.

Before a C program is compiled it is passed through another program called


‘Preprocessor’. The C program is often known as ‘Source Code’.

The Preprocessor works on the source code and creates ‘Expanded Source Code’. If the
source code is stored in a file PR1.C, then the expanded source code gets stored in a file
PR1.i.

It is this expanded source code that is sent to the compiler for compilation.
Command (with
Stage Output File Description
gcc)

.i → Expanded Expands macros, includes headers,


Preprocessing gcc -E file.c -o file.i
Source File removes comments

Converts expanded code to


Compilation gcc -S file.i -o file.s .s → Assembly Code
assembly

Assembly gcc -c file.s -o file.o .o → Object File Converts assembly to machine code

(no extension) → Links libraries to create final


Linking gcc file.o -o file
Executable program
Process Flow of Preprocessor Directives
• A developer writes a C program-> and the program checks if there are any
preprocessor directives available.

• If available, it will perform the action event of pre-processor, and the compiler will
generate the object code. The code will then be executed by the linker.

• In case no preprocessor directives are available, it will go to the compiler. The


compiler will then generate the object code followed by execution of the code by
linker.
C provides us the following preprocessor directives :

(a) Macro expansion

(b) File inclusion

(c) Conditional compilation

(d) Miscellaneous directives


Sr.N #endif
Directive & Description 9
o. Ends preprocessor conditional.
1 #define #error
Substitutes a preprocessor macro. 10
Prints error message on stderr.
2 #include
It helps to insert a certain header from another file. #pragma
11 Issues special commands to the compiler,
3 #undef using a standardized method.
Undefines a preprocessor macro.
4 #ifdef
Returns true if certain macro is defined.
5 #ifndef
Returns true if certain macro is not defined.
6 #if
Tests if a compile time condition is true.
7 #else
The alternative for #if.
8 #elif
#else and #if in one statement.
Major Types of Preprocessor Directives

Macro Expansion
In Macro expansion, we can specify two types of Macros

We can also pass arguments to macros; it can be described with arguments that perform
similarly as functions.

Syntax:
#define name substitute text
#define LIMIT 50
void main()
{
int j;
for (j=1;i<=LIMIT; j++)
{
printf("\n%d", j);
}
}

#define LIMIT 50
This statement is called ‘macro definition’ or more commonly, just a ‘macro’. During
preprocessing, the preprocessor replaces every occurrence of LIMIT in the program with
50.
When we compile the program, before the source code passes to the compiler, it is
examined by the C preprocessor for any macro definitions.

When it sees the #define directive, it goes through the entire program in search of the
macro templates; wherever it finds one, it replaces the macro template with the
appropriate macro expansion.

Only after this procedure has been completed, is the program handed over to the
compiler.
# include <stdio.h>
# define AND &&
# define OR ||
int main( )
{
int f = 1, x = 4, y = 90 ;
if ( ( f < 5 ) AND ( x <= 20 OR y <= 45 ) )
printf ( "Your PC will always work fine...\n" ) ;
else
printf ( "In front of the maintenance man\n" ) ;
return 0 ;
}
# include <stdio.h>
# define AND &&
# define ARANGE ( a > 25 AND a < 50 )
int main( )
{
int a = 30 ;
if ( ARANGE )
printf ( "within range\n" ) ;
else
printf ( "out of range\n" ) ;
return 0 ;
}
A #define directive could be used to replace even an entire C statement.

# include <stdio.h>
# define FOUND printf (" Success\n" ) ;

int main( )
{
char signature ;
if ( signature == 'Y' )
FOUND
else
printf ( "Safe... as yet !\n" ) ;
return 0 ;
}
Macros with Arguments

#define AREA(a) (3.14 * a * a)


void main()
{
float r = 3.5, x;
x = AREA (r);
printf ("\n Area of circle = %f", x);
}
File Inclusion
For file inclusion, we can use the #include.

Syntax:
#include TypeYourfilename

#include <stdio.h>
#include "myheader.h“

These directives tell the CPP to get stdio.h from System Libraries and add the text to the
current source file. The next line tells CPP to get myheader.h from the local directory and
add the content to the current source file.
Conditional Compilation
# if TEST <= 5
#include<stdio.h> printf("sums") ;
# define TEST 6 # elif TEST <=10
int main( ) Printf("dividend");
{ # else
# if TEST <= 5 printf("sttts") ;
printf("sss") ; # endif

# else
printf("statements") ;
# endif
}
Miscellaneous Directives
There are two more preprocessor directives available, though they are not very commonly
used. They are:
(a) #undef
(b) #pragma

#undef Directive
On some occasions, it may be desirable to cause a defined name to become ‘undefined’.
This can be accomplished by means of the #undef directive. In order to undefine a macro
that has been earlier #defined, the directive,

# undef macro template


#pragma Directive

This directive is another special-purpose directive that you can use to turn on or off
certain features. Pragmas vary from one compiler to another.

#pragma startup and #pragma exit: These directives allow us to specify functions that are
called upon program startup (before main( )) or program exit (just before the program
terminates).
# include <stdio.h>
void fun1( ) ;
void fun2( ) ;
# pragma startup fun1
# pragma exit fun2
int main( )
{
printf ( "Inside main\n" ) ;
return 0 ;
}
void fun1( )
{
printf ( "Inside fun1\n" ) ;
}
void fun2( )
{
printf ( "Inside fun2\n" ) ;
}
Types of Predefined Macros
___TIME___ defines the current time using a character literal in “HH:MM: SS” format.

___STDC___ specifies as 1 when the compiler complies with the ANSI standard.

___TIMESTAMP___ specifies the timestamp “DDD MM YYYY Date HH:MM: SS”. It is


used to define the date and time of the latest modification of the present source file.

___LINE___ consists of a present line number with a decimal constant.

___FILE___ includes the current filename using a string literal.

___DATE___ shows the present date with a character literal in the “MMM DD YYYY”
format.
Based on Macro Function
Type Checking Macros don’t perform type Functions perform type checking
checking, which means macro will and give a compilation error if we
be executed even if you pass pass the wrong data type
arguments with incorrect data arguments.
type.
Debugging It is harder to debug code with It is easier to debug code with
macros as it is difficult to functions.
understand the result of
substituting many macros.
Overloading We cannot overload macros. We can overload functions and
provide different functionality for
different sets of arguments.
Performance Macros are faster than functions as Functions are generally slower.
there is no function call overhead.
Length Usually single line. We can write It can span across any number of
multiline macros using a backslash lines (no restrictions).
character at the end of each line.
ctype.h header file

The ctype.h header file of the C Standard Library declares several functions that are useful
for testing and mapping characters.

isalnum()
checks alphanumeric character

isalpha()
checks whether a character is an alphabet or not

isdigit()
checks numeric character

islower()
checks lowercase alphabet
ispunct()
checks punctuation

isspace()
check white-space character

isupper()
checks uppercase alphabet

tolower()
converts alphabet to lowercase

toupper()
converts to uppercase alphabet
isalnum()
checks alphanumeric character #include <stdio.h>
#include <ctype.h>
int main()
This function accepts one {
argument - a character and char c;
returns an integer value 1 or int result;
0. c = '5';
result = isalnum(c);
Returns 1 if argument is an printf("When %c is passed, return value is %d\n", c, result);
alphanumeric character.
Returns 0 if argument is c = '+';
result = isalnum(c);
neither an alphabet nor a printf("When %c is passed, return value is %d\n", c, result);
digit.
return 0;
}
#include <stdio.h>
#include <ctype.h>
int main()
{
char ch
printf("Enter a character: ");
scanf("%c", &ch);

if (isalnum(c) == 0)
printf("%c is not an alphanumeric char.", c);
else
printf("%c is an alphanumeric char.", c);

return 0;
}
isalpha()
#include <stdio.h>
This function accepts one #include <ctype.h>
argument - a character and int main()
returns an integer value 1 or 0. {
char c;
Returns non-zero number if c = 'Q';
argument is an alphabet. printf("%d", isalpha(c));
Returns 0 if argument is not an
alphabet. c = 'q';
printf("%d", isalpha(c));

return 0;
}
Stdio.h

This function is used to print the character, string, float, integer, octal
printf() and hexadecimal values onto the output screen

scanf() This function is used to read a character, string, numeric data from
keyboard.
getc() It reads character from file
gets() It reads line from keyboard
getchar() It reads character from keyboard
puts() It writes line to o/p screen
putchar() It writes a character to screen
f open() All file handling functions are defined in stdio.h header file

f close() closes an opened file


getw() reads an integer from file
putw() writes an integer to file
f getc() reads a character from file
putc() writes a character to file
f putc() writes a character to file
f gets() reads string from a file, one line at a time
f puts() writes string to a file
f eof() finds end of file
f printf() writes formatted data to a file
f scanf() reads formatted data from a file
f getchar reads a character from keyboard
f putchar writes a character from keyboard
f seek() moves file pointer position to given location
SEEK_SET moves file pointer position to the beginning of the file
SEEK_CUR moves file pointer position to given location
SEEK_END moves file pointer position to the end of file.
f tell() gives current position of file pointer
rewind() moves file pointer position to the beginning of the file
putc() writes a character to file
remove() deletes a file
STDLIB.H
stdlib.h is a header file and also the Standard Library of C programming language that
declares various utility functions for type conversions, memory allocation, algorithms, and
other similar use cases.
Function Description
This function is used to allocate space in memory during the execution of the
malloc() program.

This function is also like malloc () function. But calloc () initializes the allocated
calloc() memory to zero. But, malloc() doesn’t

This function modifies the allocated memory size by malloc () and calloc ()
realloc() functions to new size

This function frees the allocated memory by malloc (), calloc (), realloc () functions
free() and returns the memory to the system.

Abort() Causes the program to terminate abnormally.


Functio
Description
n

abs() Returns the absolute value of x.

Rand() Returns a pseudo-random number in the range of 0 to RAND_MAX.

Exit() This function causes normal process termination.


#include <stdio.h>
#include <stdlib.h>
int main () {
int i, n;

n = 5;
for( i = 0 ; i < n ; i++ ) {
printf("%d\n", rand() % 50);
}

return(0);
}
Macro Description
This is a special pointer that does not point to any valid data.
NULL
In case of failure, this is the return value for the exit function.
EXIT_FAILURE
In case of success, this is the return value for the exit function
EXIT_SUCCESS
This represents the maximum value returned by the rand() function.
RAND_MAX
#include <stdio.h>
#include <stdlib.h>
int main () {
int i, n;

n = 5;
for( i = 0 ; i < n ; i++ ) {
printf("%d\n", rand());
}

return(0);
}
ASSERT.H

Asserts are used in programs if the developer wishes to assert or make assumptions.
The assert.h header file of the C Standard Library provides a macro called assert which
can be used to verify assumptions made by the program and print a diagnostic message
if this assumption is false.

[Link]. Function & Description


void assert(int expression)
1 This is actually a macro and not a function, which can be used to add
diagnostics in your C program.
The C library macro void assert(int expression) allows diagnostic information to be
written to the standard error file. In other words, it can be used to add diagnostics in
your C program.

void assert(int expression);

expression − This can be a variable or any C expression.

If expression evaluates to TRUE, assert() does nothing.

If expression evaluates to FALSE, assert() displays an error message on stderr (standard


error stream to display error messages and diagnostics) and aborts program execution.
#include <assert.h>
#include <stdio.h>
int main () {
int a;
char str[50];

printf("Enter an integer value: ");


scanf("%d", &a);
assert(a >= 10);
printf("Integer entered is %d\n", a);

printf("Enter string: ");


scanf("%s", str);
assert(str != NULL);
printf("String entered is: %s\n", str);

return(0);
}
stdarg.h

The stdarg.h header defines a variable type va_list and three macros which can be used
to get the arguments in a function when the number of arguments are not known i.e.
variable number of arguments.

add(int a, int b) { add(int I, ...)


return a + b; {
}
}
add(int a, int b, int c) {
return a + b +c;
}
variable type defined in the header stdarg.h

va_list
This is a type suitable for holding information needed by the three macros va_start(),
va_arg() and va_end().
The type va_list shall be defined for variables used to traverse the list.

void va_start(va_list ap, last_arg)


This macro initializes ap variable to be used with the va_arg and va_end macros. The
last_arg is the last known fixed argument being passed to the function i.e. the argument
before the ellipsis.

The va_start() macro is invoked to initialize ap to the beginning of the list before any
calls to va_arg().
type va_arg(va_list ap, type)
This macro retrieves the next argument in the parameter list of the function with type
type.

The va_end()
This macro is used to clean up; it invalidates ap for use
#include<stdarg.h>
#include<stdio.h>
int sum(int, ...);
int main(void) {
printf("Sum of 10, 20 and 30 = %d\n", sum(3, 10, 20, 30) );
printf("Sum of 4, 20, 25 and 30 = %d\n", sum(4, 4, 20, 25, 30) );
return 0;
}
int sum(int num_args, ...) {
int val = 0;
va_list ap;
int i;
va_start(ap, num_args);
for(i = 0; i < num_args; i++) {
val += va_arg(ap, int);
}
va_end(ap);
return val;
}
Time.h

[Link] Function Name Explanation


This function returns the date and time in the format
1. asctime() day month date hours:minutes:seconds year.

This function returns the difference between the times


2. difftime() provided.

This function prints the UTC (Coordinated Universal Time) Time


3. gmtime()
and date.
Sr. No. Static library Shared library
Static library is the library in which all the On other hand Shared library is the library in which
code to execute the file is in one executable only the address of library is mentioned in the target
file and this file get copied into a target program while all the functions and code of library
1 application by a compiler, linker, or binder, are in a special place in memory space, and every
producing an object file and a stand-alone program can access them, without having multiple
executable. copies of them.

As mentioned in above point static library Shared libraries are get import at the time of
are resolved in a caller at compile-time and execution of target program by the Operating system
2 copied into a target application by a itself.
compiler, linker, or binder.

Static libraries are large in size as because On other Shared libraries are much smaller as
external programs are built in the because there is only one copy of dynamic library
3 executable file. that is kept in memory at the time of execution only
otherwise its location is remote.
4 For static libraries recompilation is required if any On other hand for Shared libraries there is no
changes were applied to external files. need to recompile the executable.
5 Static libraries take longer to execute, because While Shared libraries are faster because
loading into the memory happens every time while shared library code is already in the memory.
executing.
6 In Static library no compatibility issue has been On other hand in case of Shared library has
observed. compatibility issue as target program will not
work if library gets removed from the system .
Static Library

Prg1.C Prg2.C

int g_num(int a, int b) #include <stdio.h>


{ #include "prg_1.c"
if(a>b) extern int g_num(int, int);
return a;
else int main() {
return b; int a = 15, b = 3;
}
printf("Greater Number: %d\n", g_num(a, b));
return 0;
}
Shared Library

prg2.c
prg1.c (DLL file)
#include <stdio.h>
__declspec(dllexport) int g_num(int a, int b)
{ extern int g_num(int, int);
if (a > b)
return a; int main()
else {
return b; int a = 15, b = 3;
}
printf("Greater Number: %d\n", g_num(a, b));

return 0;
}

You might also like