160 likes | 310 Views
ECE 103 Engineering Programming Chapter 14 C Preprocessor. Herbert G. Mayer, PSU CS Status 7/16/2014 Initial content copied verbatim from ECE 103 material developed by Professor Phillip Wong @ PSU ECE. Syllabus. Preprocessor Directives Include Files Macros Named Constants.
E N D
ECE 103 Engineering ProgrammingChapter 14C Preprocessor Herbert G. Mayer, PSU CS Status 7/16/2014 Initial content copied verbatim from ECE 103 material developed by Professor Phillip Wong @ PSU ECE
Syllabus • Preprocessor Directives • Include Files • Macros • Named Constants
Preprocessor Directives Before a C program is compiled, the source code file is first handled by a preprocessor Source files prog_1.c stdio.h prog_2.c stdlib.h prog_3.c etc. math.h etc. User Header files Library Header files prog_1.h prog_2.h prog_3.h etc. Assembler Preprocessor Compiler To Linker 2
The preprocessor does this: Strips comments from the source code Acts on preprocessor directives The preprocessor does not compile code! Preprocessor directive → a special command recognized only by the preprocessor # symbol prefixes each directive Directives are used for: Modifying the compilation process Creating macro definitions
Common directives: #include f : Inserts the contents of a specified text file into the source code #define m : Defines a macro #undef m : Cancels a previously defined macro #if expr : Begins a conditional block →expr tested #ifdef m : Tests whether a macro is defined #ifndef m : Tests whether a macro is not yet defined #else : Alternative branch #elif expr : Else if →expr tested #endif : Ends a conditional block 4
Include Files C provides access to common functions (e.g., I/O, math routines) via external libraries Each library has a header file that may contain prototypes, macros, and definitions A header file is a text file with a .h extension Before accessing a library’s functions, use the #include directive to load its header file #includedirectives are typically placed at the beginning of the source file
Syntax: #include <filename> Angle bracket form → searches for a header file in the system include directory #include "filename" Quoted form → searches for a header file starting with the current working directory
Example: /* Loads system header for stdio library */ #include <stdio.h> /* Loads system header for math library */ #include <math.h> /* Loads user header file */ #include "mystuff.h" /* Loads user header file */ #include "../LIB/mylib.h"
Macros A preprocessor macro is used for: Defining a symbolic name for a constant value Defining a terse alias for something else To define a macro, use this directive: #define mnamemtext mname→ macro name, formal parameters allowed mtext→ substitution text At least one whitespace
The preprocessor expands macros in the C code Wherever it sees mname in the source file, it substitutes mtext in its place A macro definition can contain previously defined macros Macros are not at all the same as C variables! No storage is created in memory; macros only exist at compile-time An old C programming convention rules that macro names be fully capitalized to differentiate them from C variable names; this is NOT a language rule, hence NOT enforced by the C compiler!
Example: /* Pay rate in $ per hour */ /* Time in hours per week */ #include <stdio.h> #define RATE1 9.25 #define HRS_WK1 40 int main (void) { // main float rate2 = 22.50; float hrs_wk2 = 35; float pay1, pay2; /* Weekly pay in $ */ pay1 = RATE1 * HRS_WK1; pay2 = rate2 * hrs_wk2; printf("RATE1=%f\n",RATE1); return 0; } //end main [stdio.h definitions] [are inserted here ] int main (void) { // main float rate2 = 22.50; float hrs_wk2 = 35; float pay1, pay2; pay1 = 9.25 * 40; pay2 = rate2 * hrs_wk2; printf("RATE1=%f\n",9.25); return 0; } //end main Original source file After macro expansion 10
Macro expansion is very literal. Be careful of unintended side-effects Example:#define A 5 #define B A + 1 #define FACTOR1 A * B/3. + 6 #define FACTOR2 (A) * (B)/3. + 6 #define Tip_Rate 0.15 #define UINT unsigned int #define PRINTBLANK printf("\n")
Commenting Out Code By Using #if … #endif This is illegal in C90. Comments cannot be nested within other comments. /* x = r * cos(a); /* x component */ y = r * sin(a); /* y component */ */ This is legal in C90. The code within the #if 0 … #endif is removed from the source before it ever reaches the compiler. #if 0 x = r * cos(a); /* x component */ y = r * sin(a); /* y component */ #endif 12
Named Constants magic number → a non-obvious literal number or character that is directly embedded in a statement Avoid magic numbers. Use named constants instead! Example: /* Newton's equation of motion */ y = –0.5 * 9.81*t*t + 75.2*t + 2.5; What do these numbers mean? 9.81 = Earth’s gravitational acceleration g (m/s2) 75.2 = Initial velocity vy0 (m/s) in y-axis direction 2.5 = Initial position y0 (m) in y-axis direction 13
Example: #include <stdio.h> #define G_EARTH 9.81 // m/s^2 #define VELOCITY_Y0 75.2 // m/s #define POSITION_Y0 2.5 // m int main (void) { // main double t; // Time (s) double y; // Height (m) at time t printf( "Enter time (s): ” ); scanf( "%lf", &t ); y = -0.5 * G_EARTH * t * t + VELOCITY_Y0 * t + POSITION_Y0; printf( "y(%.2f s) = %.2f m\n", t, y ); return 0; } //end main 14
Question: Can I just use constants instead? Yes, you could define something like this: static const double g_earth = 9.81; Comparison of #define versus const 15