C - Session 14
C - Session 14
Created By
SATISH KHANNA
VEDAIIT
HYDERABAD
C Language
Session 14
• Function Pointers
• Pre-processor Directives
• Define Directives (Macros)
• Conditional Compilation Directives
• Include Directives
Function Pointers
• A function pointer can point to the starting address of the function
segment (A set of statements that define a function).
• It can then be used to invoke the referent function to which it is
currently pointing.
• As with any other pointer, the declaration of a function pointer is
dependent on the referent function’s prototype. A declaration of
function pointer, more specifically, depends on the signature of the
function and return type of the function.
• Declaration of a function pointer
Syntax: return-type (*pointer-name)(param-type-list);
Example:
int (*fptr1)(int, int);
The statement declares a function pointer fptr1 that can point to any
function that has two int parameters and also has an int return type.
Function Pointers
• Define two functions that have two int parameters & return an int
int findSum (int a, int b) {
return (a + b);
}
fptr = findSum;
int res = fptr(10, 20); // invokes findSum()
printf("%d\n", res); // OUTPUT: 30
fptr = findDiff;
res = (*fptr)(25, 15); // invokes findDiff()
printf("%d\n", res); // OUTPUT: 10
return 0;
}
Function Pointers
• Passing function pointer as an argument to another function
fptr1 = findSum;
res1 = compute(fptr1, 10, 20);
printf(“%d\n”, res1); // 30
fptr1 = findDiff;
res1 = compute(fptr1, 100, 40);
printf(“%d\n”, res1); // 60
Pre-processor Directives
• A pre-processor directive is an instruction to the pre-processor
program that is run as the first stage of compiling a C program.
• It can be given in a source code file or at command line during
compiling using options of gcc compiler.
• In the source code file a directive begins with a # symbol followed by
predefined directive. The directive is terminated using a newline.
This means, each directive should be on an independent line.
However, if a directive has to span to next line the newline should
be escaped using backslash \ character.
• In general the directives are of 4 types:
Define Directive
Conditional Compilation Directive
Include Directive
Other Directives
• Define Directive
This directive is used to associate a macro name with a string. The
macro name can then be used anywhere in the program where
associated string is required.
Pre-processor Directives
• At pre-processing stage the macro is blindly substituted with
associated string. The macro name can also have parameters.
• #define NAME[ (parameter name list) ] stringVal
• The directive defines a new macro named NAME and associates it
with the following string stringVal. The macro can optionally have
in parentheses one or more parameter names separated with
comma.
• Once defined, the macro NAME can be used anywhere in the
program where stringVal is required.
Macro name is in UPPERCASE, by convention.
• Macros are of 4 types:
Simple Macro
Macro with parameters
Nested Macro
Pre-defined Macros
Pre-processor Directives
• Simple Macro
#define SIZE 10
The directive defines a macro named SIZE with associated string 10.
Once SIZE is defined as a macro, it can be used anywhere in the
program where the value 10 is required.
For example, SIZE can be used in a declaration of an array and in a
loop for iterating through the array, as under:
int arr[SIZE], i;
for(i=0; i<SIZE; i++)
scanf("%d", &arr[i]);
At pre-processing stage wherever the macro SIZE is found it is
replaced with 10. However, the replacement does not occur if the
macro is in double quoted string.
Printf("SIZE=%d", SIZE); //Output: SIZE=10
• The value associated with the macro can be an expression. However,
the expression is not evaluated at the time of macro substitution.
#define M 7 + 20
#define N 5 + 4
• Pre-defined Macros
__LINE__ stores current line number of source code file
__DATE__ stores most recent date of compilation of program
__TIME__ stores most recent time of compilation of program
__func__ stores name of current function
__FILE__ stores name of program file
__STDC__ stores 1 if compiler complies with ANSI C standard
• CAUTION:
Be alert to the side effects of macros, before using a particular macro.
Pre-processor Directives
• Conditional Compilation Directives
The conditional compilation directives are used to include or exclude a
piece of code from compilation.
• Based on these directives the pre-processor selects which code from
the source code file should be passed to the compiler.
• The directives are:
#if #elif #else #endif
#ifdef #ifndef #undef defined
• For example, a macro with the same name cannot be defined again if
it is already defined earlier. So, the macro should be defined or even
undefined conditionally as under:
• #ifndef SIZE
#define SIZE
#endif
• #ifdef SIZE //OR #if defined SIZE
#undef SIZE
#endif
Pre-processor Directives
• When developing a C program for a given application it is known that
there are slight differences in the code being developed for different
O.S. or platforms.
Now, instead of developing separate programs, one for each platform,
it is better to develop a single program that works for all platforms by
including code using conditional compilation directives.
The pre-processor program identifies the platform based on
predefined macros for different platforms and includes code meant for
the specific platform being currently used.
• Example 1
#include<stdio.h>
int main() {
#ifdef _WIN32
printf("Windows 32-bit & 64-bit\n");
#elif defined _WIN64
printf("Windows 64-bit\n");
#elif defined __linux__
printf("Linux\n");
#elif defined __unix__
printf("Unix\n");
#else
printf("Some Other\n");
#endif
}OUTPUT: Linux
Pre-processor Directives
• Include Directive
#include<[path/]filename.h>
#include<stdio.h>
The directive includes the named header file (.h extension) into the
source code file at the place where this directive is placed.
The file to be included is searched at the standard installation
location (/usr/include).
It is also possible to provide path with file name or use command
line option -I<path> at compile time.
#include" [path/]filename.h"
#include "myfun.h"
Double quotes may be used around filename for user defined
header files.
• NOTE:
C does not allow same header file to be included more than once,
directly or indirectly.
Pre-processor Directives
• Providing Include Guards
Preventing double inclusion of header file file3.h
• File: file1.c
#include<file2.h>
#include<file3.h>
//code
• File: file2.h
#include<file3.h>
//code
• File: file3.h
#ifndef FILE3_H
#define FILE3_H
//code
#endif
• In file1.c the file file3.h is included twice; once directly and again
indirectly through file2.h
• To avoid double inclusion of file3.h the entire code of file3.h is placed
under conditional compilation. When file3.h is included for the first
time a new macro FILE3_H is defined and the code of file is actually
included.
However, when an attempt is made to include this file for the second
and subsequent time, the macro is already defined and prevents
inclusion of same code again.
Pre-processor Directives
• Other Directives
#line num [filename]
#error message
#warning message
# stringization operator
## concatenation operator
• Example 1
#include<stdio.h>
#define X 20
int main()
{
printf("%d\n", X);
#if X>10
#error X cannot be greater than 10
#endif
return 0;
}
OUTPUT: test.c:6:10: #error X cannot be greater than 10
Pre-processor Directives
• Example 2
#include<stdio.h>
#define paster(n) printf("token"#n"=%d", token##n);
int main() {
int token1 = 10, token2 = 20, token3 = 30;
paster(1);
paster(2);
paster(3);
return 0;
}
OUTPUT:
token1=10
token2=20
token3=30