C Preprocessor & Macro |
|
Macro substitution directives |
|
We have already met this facility, in its simplest form it allows us to define textual substitutions using #define statement. |
|
The #define statement can be used for more, however, than simply defining symbolic constants. |
|
In particular, it can be used to define macros; its, single identifiers that are equivalent to expressions, complete statement or groups of statements. Macros resemble function in this sense. |
|
They are defined in an altogether different manner than functions, however, and they are treated differently during the compilation process. |
|
Format: #define identifier string |
|
e.g.: #define MAXSIZE 256 |
|
This will lead to the value 256 being substituted for each occurrence of the word MAXSIZE in the file. |
|
Example: |
|
 |
|
Out put of the program |
|
 |
|
This program contains the macro area, which represents the expression length* width. |
|
When the program is compiled, the expression length * width will replace the identifier area within the printf statement, so that printf statement will become |
|
Printf("\narea =%d", length *width); |
|
Note that the format string " \n area =%d" is unaffected by the #define statement. |
|
When the program is executed, the values for length and width are entered interactively from the keyboard, and the corresponding value for area is displayed. |
|
A typical interactive session is shown below. The user's responses are underlined, as usual. |
|
Length =_3 |
Width =_4 |
Area=12 |
|
Macro definitions are customarily placed at the beginning of a file, ahead of the first function definition. |
|
The scope of a macro definition extends from its point of definition to the end of the file. However, a macro defined in one file is not recognized within another file. |
|
Multilane macros can be defined by placing a backward slash (\) the end of each line except the last. |
|
This feature permits a single macro (i.e. a single identifier) to represent a compound statement. |
|
Here is another simple c program that contains multilane macro: |
|
 |
|
Out put of the program |
|
 |
|
Macros are sometimes used in place of functions within a program. |
|
The use of a macro in place of a function eliminates the time delays associated with function calls. |
|
If a program contains many reported function calls, the time savings resulting from the use of macros can become significant. |
|
On the other hand, macro substitution will take place whenever a reference to a macro appears within a program. |
|
Thus, a program that contains several references to the same macro may become unreasonably long. We therefore face a tradeoff between execution speed and size of the compiled object program. |
|
The use of a macro is most advantageous in applications where there are relatively few functions calls but the function is called repeatedly. |
|
Using #define to Create Functional Macros |
|
#define can also be given arguments which are used in its replacement. The definitions are then called macros. |
|
Macros work rather like functions, but with the following minor differences. |
|
Since macros are implemented as a textual substitution, there is no effect on program performance (as with functions). |
|
Recursive macros are generally not a good idea. |
|
Macros don't care about the type of their arguments. Hence macros are a good choice where we might want to operate on reals, integers or a mixture of the two. |
|
Macros are full of traps for the unwary programmer. In particular the textual substitution means that arithmetic expressions are liable to be corrupted by the order of evaluation rules. |
|
Here is an example of a macro which won't work: |
|
#define DOUBLE(x) x+x |
|
Now if we have a statement |
|
a = DOUBLE(b) * c; |
|
This will be expanded to |
|
a = b+b * c; |
|
And since * has a higher priority than +, the compiler will treat it as. |
|
a = b + (b * c); |
|
The problem can be solved using a more robust definition of DOUBLE |
|
#define DOUBLE(x) (x+x) |
|
Here the brackets around the definition force the expression to be evaluated before any surrounding operators are applied. This should make the macro more reliable. |
|
In general it is better to write a C function than risk using a macro. |
|
|
|
|
C Preprocessor & Macro |
|
File inclusion |
|
The preprocessor directive #include is an instruction to read in the entire contents of another file at that point. |
|
This is generally used to read in header files for library functions. Header files contain details of functions and types used within the library. |
|
It must be included before the program can make use of the library functions. |
|
Library header file names are enclosed in angle brackets, < >. These tell the preprocessorto look for the header file in the standard location for library definitions. |
|
Example: #include |
|
another use for #include for the programmer is where multi-file programs are being written. |
|
Certain information is required at the beginning of each program file. This can be put into a file called globals.h and included in each program file. |
|
Local header file names are usually enclosed by double quotes, " ". It is conventional to give header files a name which ends in .h to distinguish them from other types of file. |
|
Our globals.h file would be included by the following line. #include "globals.h" |
|
|
|
|
C Preprocessor & Macro |
|
Compiler control directive |
|
The C Preprocessor offer a feature known as conditional compilation, which can be used to switch on or off a particular line or group of lines in a program. |
|
This is achieved by the inserting #ifdef or #endif. |
|
Conditional selection of code using #ifdef,#endif. |
|
The preprocessor has a conditional statement similar to' C's if else. |
|
It can be used to selectively include statements in a program. This is often used where two different computer types implement a feature in different ways. It allows the programmer to produce a program which will run on either type. |
|
The keywords for conditional selection are; #ifdef, #else and #endif. #ifdef |
|
takes a name as an argument, and returns true if the name has a current definition. The name may be defined using a #define, the -d option of the compiler. |
|
#else |
|
is optional and ends the block beginning with #ifdef. It is used to create a 2 way optional selection. |
|
#endif |
|
ends the block started by #ifdef or #else. |
|
Where the #ifdef is true, statements between it and a following #else or #endif are included in the program. |
|
Where it is false, and there is a following #else, statements between the #else and the following #endif are included. |
|
This is best illustrated by an example. |
|
Using #ifdef for Different Computer Types |
|
Conditional selection is rarely performed using #defined values. A simple application using machine dependent values is illustrated below: |
|
 |
|
Out put of the program |
|
 |
|
Note: sun is defined automatically on SUN computers. vax is defined automatically on VAX computers. ibm is defined automatically on IBM pc's else type not defined message will be displayed (different types of computer) |
|
Using #ifdef to Temporarily Remove Program Statements |
|
#ifdef also provides a useful means of temporarily "blanking out" lines of a program. |
|
The lines in question are preceded by #ifdef NEVER and followed by #endif. Of course you should ensure that the name NEVER isn't defined anywhere. |
|
|
|
|
Command line parameter of C |
|
Command line parameter |
|
You may have been wondering about the empty parentheses in the first line of the main function, i.e. main(). |
|
The parentheses may contain special arguments that allow parameters to be passed to main from the operating system. |
|
Most versions of C permit two such arguments, which are traditionally called argc and argv, respectively. |
|
The first of these, argc, must be an integer variable, while the second, argv, is an array of pointers of characters; i.e., an array of strings. |
|
Each string in this array will represent a parameter that is passed to main. The value ofargc will indicate the number of parameters passed. |
|
Example: The following outline indicates how the arguments argc and argv are defined within main. |
|
Vod main(int argc, char *argv[]) |
{ |
..... |
} |
|
The first line can be written without the keyword void, i.e., |
|
main(int argc, char *argv[]) |
|
A program is normally executed by specifying the name of the program within a menu-driven environment. |
|
Some compilers also allow a program to be executed by specifying the name of the program (actually, the name of the file containing the compiled object program) at the operating system level. |
|
The program name is then interpreted as an operating system command. Hence, the line in which its appears is generally referred to as a command line. |
|
In order to pass one or more parameters to the program when it is executed from the operating system, the parameters must follow the program name on the command line. |
|
E.g.: Program-name parameter 1 parameter 2 . . . parameter n |
|
The individual items must be separated from one another either by blank spaces or by tabs. |
|
Some operating systems permits blank spaces to be included within a parameter provided the entire parameter is enclosed in quotation marks. |
|
The program name will be stored as the first item in argv, followed by each of the parameters. Hence, if the program name is followed by n parameters. |
|
There will be (n+1) entries in argv, ranging from argv [0] to argv [n]. Moreover, argc will automatically be assigned the value (n+1). |
|
Note that the value for argc is not supplied explicitly from the command line. |
|
An example program which will be executed from a command line: |
|
 |
|
Out put of the program |
|
 |
|
This program allows an unspecified number of parameters to be entered from the command line. |
|
When the program is executed, the Count value for argc and the elements of argv will be displayed as separate lines of output. |
|
Sample red white blue |
|
then the program will be executed, resulting in the following output. |
|
argc =4 |
argv [0]=sample.exe |
argv [1]=red |
argv [2]=white |
argv [3]=blue |
|
The output tells us that four separate items have been entered form the command line. |
|
The first is the program name, sample. exe, followed by the three parameters., red. White and blue. |
|
Each item is an element in the array argv. (Name that sample.exe is the name of the object file resulting from the compilation of the source code sample. C.) |
|
Similarly, if the command line is |
|
Sample red "white blue" |
|
The resulting output will be |
|
argc=3 |
argv [0]=sample.exe |
argv [1]=red |
argv [2]=white blue |
|
In, this case the string "white blue" will be interpreted as a single parameter, because of the quotation marks. |
|
Once the parameters have been entered, they can be utilized within the program in any desired manner. |
|
One particularly common application is to specify the names of data files as command line parameter. |
|
|
|
|
Header file |
|
Introduction |
|
The C provides a large number of C functions as libraries. Some of these implement frequently used operations, while others are very specialized in their application. |
|
Wise programmers will check whether a library function is available to perform a task before writing their own version. |
|
This will reduce program development time. The library functions have been tested, so they are more likely to be correct than any function which the programmer might write. |
|
This will save time when debugging the program. For using these files ,certain files are needed to be included in the program which make call to these functions. |
|
These files are known as Header files and they contain macro definition ,type definition, and function declarations. |
|
These header files usually have an extension .h as stdio.h, ctype.h, string.h, math.h,stdlib.h, stdarg.h, time.h etc. |
|
|
|
|
Header file |
|
Use of library functions |
|
To use a function, ensure that you have made the required #includes in your C file. Then the function can be called as though you had defined it yourself. |
|
It is important to ensure that your arguments have the expected types; otherwise the function will probably produce strange results. |
|
Some libraries require extra options before the compiler can support their use. |
|
For example, to compile a program including functions from the math.h library the command might be cc mathprog.c -o mathprog –lm |
|
The final -lm is an instruction to link the maths library with the program. The manual page for each function will usually inform you if any special compiler flags are required. |
|
|
Header file |
|
Some Useful library functions |
|
There is a vast collections of function .Some of them are grouped together and listed below. |
|
String Function: |
|
strcpy | copies one string into another. |
strcat | appends one string to another. |
strcmp | compare one string to another. |
strcmpi | compare one string to another without case sensitive. |
strlen | calculates the length of a string. |
strrev | reserve a string. |
|
|
Mathematical Function: |
|
abs | returns absolute value of an integer. |
sin | calculate the sine. |
cos | calculate the arc cos. |
tan | calculate the arc tangent. |
acos | calculate the arc cosine. |
asin | calculate the arc sine. |
atan | calculate the arc tangent. |
ceil | rounds up. |
floor | rounds down. |
log | calculate the natural logarithm of x. |
pow | calculate x to the power of y. |
sqrt | calculate the positive square root of input value. |
|
|
Date & Time Function: |
|
asctime | converts date and time to ASCII. |
clock | determine process time. |
getdate | gets system date |
gettime | gets system time. |
setdate | sets DOS date |
settime | sets system time. |
time | gets time of day. |
|
|
Utility Function: |
|
abort() | abnormally terminates a process. |
bsearch() | binary search of an array. |
tolower() | translate character to lower case. |
toupper() | translate character to upper case. |
qsort() | sorting using the quick sort algorithm. |
exit() | terminate execution of a program. |
free() | frees allocated block. |
|
|
Character Class Test Functions: |
|
isupper() | check and returns non-zero if c is an upper case letter (A-Z). |
islower() | check and returns non-zero if c is a lower case letter (a-z). |
isspace(() | check and returns non-zero if c is a space tab, carriage return, newline, vertical tab, form feed etc. |
isascii() | tests whether a character is an ASCII (0 to 127) character. |
isalpha() | check and returns non-zero if c is a letter (A-Z or a-z). |
iscntrl() | tests whether a character is a control character. |
toascii() | translate character to ASCII format. |
tolower() | translate character to upper case. |
|
|
|
|
|
|
|
|
|
|
|
|
|
No comments:
Post a Comment