|
C Programming Tutorials
Basics of C:
Facts about C
Why to Use C
C Program File
C Compilers
Program Structure:
Simple C Program
C
Program Compilation
Basic DataTypes:
DataTypes
Modifiers
Qualifiers
Arrays
Variable Types:
Local Variable
Global
Variable
Storage Classes:
auto storage class
register storage
class
static storage
class
extern storage
class
Using Constants:
Defining Constants
The enum Data Types
Operator Types:
Arithmetic Operators
Logical Operators
Bitwise Operators
Assignment Operators
Misc
Operators
Control Statements:
Branching
Looping
Input and Output:
printf() function
scanf() function
Pointing to Data:
Pointers and Arrays
Pointer
Arithmetic
Pointer Arithmetic
with arrays
Functions:
Using functions
Declaration and
Definition
Strings:
Reading and Writing
Strings
String Manipulation Function
Structured DataTypes:
Structure
Pointer to Structure
Working with Files:
Files
Basic I/O
Bits:
Bits Manipulation
Bits Field
Pre-Processors:
Pre-Processors Examples
Parameterized Macros
Macro
Caveats
Useful Concepts
Built-in Library Functions:
String Manipulation
Function
Memory Management
Function
Buffer
Manipulation
Character
Functions
Error Handling
Functions
Soft Skills
Communication Skills
Leadership Skills
.........More
|
|
C Programming Tutorials
Pre-Processors
The C Preprocessor is not part of the compiler, but is a separate step in the
compilation process. In simplistic terms, a C Preprocessor is just a text
substitution tool. We'll refer to the C Preprocessor as the CPP.
All preprocessor lines begin with #
-
The unconditional directives are:
#include - Inserts a particular header from another file
#define - Defines a preprocessor macro
#undef - Undefines a preprocessor macro
-
The conditional directives are:
#ifdef - If this macro is defined
#ifndef - If this macro is not defined
#if - Test if a compile time condition is true
#else - The alternative for #if
#elif - #else an #if in one statement
#endif - End preprocessor conditional
-
Other directives include:
# - Stringization, replaces a macro parameter with a string constant
## - Token merge, creates a single token from two adjacent ones
Pre-Processors Examples:
Analyze following examples to understand various directives
| #define MAX_ARRAY_LENGTH 20 |
Tells the CPP to replace instances of MAX_ARRAY_LENGTH with
20. Use #define for constants to increase readability.
#include <stdio.h>
#include "myheader.h" |
Tells the CPP to get stdio.h from System Libraries and add
the text to this file. The next line tells CPP to get myheader.h from the local
directory and add the text to the file.
#undef FILE_SIZE
#define FILE_SIZE 42 |
Tells the CPP to undefined FILE_SIZE and define it for 42.
#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif |
Tells the CPP to define MESSAGE only if MESSAGE isn't defined
already.
#ifdef DEBUG
/* Your debugging statements here */
#endif |
Tells the CPP to do the following statements if DEBUG is
defined. This is useful if you pass the -DDEBUG flag to gcc. This will define
DEBUG, so you can turn debugging on and off on the fly!
Stringize (#):
The stringize or number-sign operator ('#'), when used within a macro
definition, converts a macro parameter into a string constant. This operator may
be used only in a macro that has a specified argument or parameter list.
When the stringize operator immediately precedes the name of one of the macro
parameters, the parameter passed to the macro is enclosed within quotation marks
and is treated as a string literal. For example:
#include <stdio.h>
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
int main(void)
{
message_for(Carole, Debra);
return 0;
} |
This will produce following result using stringization macro
message_for
| Carole and Debra: We love you! |
Token Pasting (##):
The token-pasting operator (##) within a macro definition combines two
arguments. It permits two separate tokens in the macro definition to be joined
into a single token.
If the name of a macro parameter used in the macro definition is immediately
preceded or followed by the token-pasting operator, the macro parameter and the
token-pasting operator are replaced by the value of the passed parameter. Text
that is adjacent to the token-pasting operator that is not the name of a macro
parameter is not affected. For example:
#define tokenpaster(n) printf ("token" #n " =
%d", token##n)
tokenpaster(34); |
This example results in the following actual output from the
preprocessor:
| printf ("token34 = %d", token34); |
This example shows the concatenation of token##n into
token34. Both the stringize and the token-pasting operators are used in this
example.
Parameterized Macros:
One of the powerful functions of the CPP is the ability to simulate functions
using parameterized macros. For example, we might have some code to square a
number:
int square(int x)
{
return x * x;
} |
We can instead rewrite this using a macro:
| #define square(x) ((x) * (x)) |
Macros with arguments must be defined using the #define
directive before they can be used. The argument list is enclosed in parentheses
and must immediately follow the macro name. Spaces are not allowed between and
macro name and open parenthesis. For example:
| #define MAX(x,y) ((x) > (y) ? (x) : (y)) |
Macro Caveats:
-
Macro definitions are not stored in the object file. They
are only active for the duration of a single source file starting when they
are defined and ending when they are undefined (using #undef), redefined, or
when the end of the source file is found.
-
Macro definitions you wish to use in multiple source
files may be defined in an include file which may be included in each source
file where the macros are required.
-
When a macro with arguments is invoked, the macro
processor substitutes the arguments into the macro body and then processes
the results again for additional macro calls. This makes it possible, but
confusing, to piece together a macro call from the macro body and from the
macro arguments.
-
Most experienced C programmers enclose macro arguments in
parentheses when they are used in the macro body. This technique prevents
undesired grouping of compound expressions used as arguments and helps avoid
operator precedence rules overriding the intended meaning of a macro.
-
While a macro may contain references to other macros,
references to itself are not expanded. Self-referencing macros are a special
feature of ANSI Standard C in that the self-reference is not interpreted as
a macro call. This special rule also applies to indirectly self-referencing
macros (or macros that reference themselves through another macro).
NEXT >> Useful Concepts
Have a Question ?
post your questions here. It
will be answered as soon as possible.
Check
C Aptitude Questions
for more C Aptitude Interview Questions with Answers
Check
C Interview Questions
for more C Interview Questions with Answers
|