Saturday, October 4, 2014

Preprocessors in C

THE PREPROCESSOR
The define statement is used to make programs more readable, and allow the inclusion of macros. Consider the following examples,
#define TRUE 1 /* Do not use a semi-colon , # must be first character on line */
#define FALSE 0
#define NULL 0
#define AND &
#define OR |
#define EQUALS ==
game_over = TRUE;
while( list_pointer != NULL )
................
MACROS
Macros are inline code which are substituted at compile time. The definition of a macro, which accepts an argument when referenced,
#define SQUARE(x) (x)*(x)
y = SQUARE(v);
In this case, v is equated with x in the macro definition of square, so the variable y is assigned the square of v. The brackets in the macro definition of square are necessary for correct evaluation.
The expansion of the macro becomes y = (v) * (v);
Naturally, macro definitions can also contain other macro definitions,
#define IS_LOWERCASE(x) (( (x)>='a') && ( (x) <='z') )
#define TO_UPPERCASE(x) (IS_LOWERCASE (x)?(x)-'a'+'A':(x))
while(*string) {
*string = TO_UPPERCASE (*string);
++string;
}
CONDITIONAL COMPILATIONS
These are used to direct the compiler to compile/or not compile the lines that
follow
#ifdef NULL
#define NL 10
#define SP 32
#endif
In the preceding case, the definition of NL and SP will only occur if NULL has been defined prior to the compiler encountering the #ifdef NULL statement. The scope of a definition may be limited by
#undef NULL
This renders the identification of NULL invalid from that point onwards in the source file.
Typedef
This statement is used to classify existing C data types, eg,
typedef int counter; /* redefines counter as an integer */
counter j, n; /* counter now used to define j and n as integers */
typedef struct {
int month, day, year;
} DATE;
DATE todays_date; /* same as struct date todays_date */

ENUMERATED DATA TYPES
Enumerated data type variables can only assume values which have been previously declared.
enum month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
enum month this_month;
this_month = feb;
In the above declaration, month is declared as an enumerated data type. It consists of a set of values, jan to dec. Numerically, jan is given the value 1, feb the value 2, and so on. The variable this_month is declared to be of the same type as month, then is assigned the value associated with feb. This_month cannot be assigned any values outside those specified in the initialization list for the declaration of month.
Example:
#include <stdio.h>
main()
{
char *pwest = "west",*pnorth = "north", *peast="east", *psouth = "south";
enum location { east=1, west=2, south=3, north=4};
enum location direction;
direction = east;
if( direction == east )
printf("Cannot go %s\n", peast);
}
The variables defined in the enumerated variable location should be assigned initial
values.
DECLARING VARIABLES TO BE REGISTER BASED
Some routines may be time or space critical. Variables can be defined as being register based by the following declaration,
register int index;
DECLARING VARIABLES TO BE EXTERNAL
Here variables may exist in separately compiled modules, and to declare that the variable is external,
extern int move_number;
This means that the data storage for the variable move_number resides in another source module, which will be linked with this module to form an executable program. In using a variable across a number of independently compiled modules, space should be allocated in only one module, whilst all other modules use the extern directive to access the variable.
NULL STATEMENTS
These are statements which do not have any body associated with them.
/* sums all integers in array a containing n elements and initializes */
/* two variables at the start of the for loop */
for( sum = 0, i = 0; i < n; sum += a[i++] )
;
/* Copies characters from standard input to standard output until EOF is reached */
for( ; (c = getchar ()) != EOF; putchar (c));
COMMAND LINE ARGUMENTS
It is possible to pass arguments to C programs when they are executed. The brackets which follow main are used for this purpose. argc refers to the number of arguments passed, and argv[] is a pointer array which points to each argument which is passed to main. A simple example follows, which checks to see if a single argument is supplied on the command line when the program is invoked.
#include <stdio.h>
main( int argc, char *argv[] )
{
if( argc == 2 )
printf("The argument supplied is %s\n", argv[1]);
else if( argc > 2 )
printf("Too many arguments supplied.\n");
else
printf("One argument expected.\n");
}
Note that *argv[0] is the name of the program invoked, which means that
*argv[1] is
a pointer to the first argument supplied, and *argv[n] is the last argument. If no arguments
are supplied, argc will be one. Thus for n arguments, argc will be equal to n + 1. The program is called by the command line, myprog argument1.

No comments:

Post a Comment