CS代写 LINES 100

The C Preprocessor

Object Code Files
• the C compiler can produce an object code version of a .c file that is machine language but not linked with other parts of your program

Copyright By PowCoder代写 加微信 powcoder

• these object code files end in .o

Compiling multi-file programs
Source code Name.c
Declarations Name.h
Assembly code Name.s
Object code Name.o
Preprocessor
C compiler

Compiling multi-file programs
Source code Name.c
Declarations Name.h
Object code Name.o
Preprocessor
C compiler

Compiling and Linking
• the C compiler can be instructed to produce the .o file from the .c using the -c flag, eg:
gcc -c util.c
• several .c or .o files can be combined to produce an executable program:
gcc myprog.c util.o -o myprog

• theobjectcodefilesarelinkedtogetherto form the final executable program
• afterchanginga.cfileweonlyneedto recompile the affected file into its object code (.o) form and then relink all the .o files to produce the executable

Preprocessor commands
• preprocessor commands are lines starting
eg #include
• The C preprocessor interprets these lines

Including Text from other files
• The#includestatementisusedtoincludetext from another file into your program file at that point
• Cprogramstypicallyconsistofmanysource code files that each contain a small number of functions
• functionsworkoncommondatastructures and so need declarations of the data structure to be included in each file

Including Text from other files
• rather than copy the declarations into every file (error prone!) we can use include files
• Useful for: – externs
– typedefs
– struct definitions
• can even nest the included files

Two Files: before
myprog.c decs.h
/* My Program */
#include “decs.h”
int main(int argc, char *argv[])
/* Declarations */
extern int count;
struct employee {

After preprocessor:
extern int count;
struct employee {
int main(int argc, char *argv[])
Included text

• By convention, the names of included files end in “.h”
• So called “header” files because they tend to be included near the head of the program file

• Why shouldn’t you include actual code?
• Why should you include relevant header files rather than simply have them in the code?

Defined Symbols
• An identifier symbol can be given a value by the preprocessor
#define LINES 100
• The preprocessor will replace the identifier LINES with the string 100 whenever it finds it in the program

Before preprocessor
myprog.c decs.h
/* My Program */
#include “decs.h” char page[LINES] int main(int argc,
char *argv[]) {
/* Declarations */
#define LINES 100

After preprocessor
Included text
char page[100]
int main(int argc, char *argv[])
Symbol replaced

Any replacement string
• The replacement string can be any string of characters:
#define LINES 5*10*20

Before preprocessor
myprog.c decs.h
/* My Program */
#include “decs.h” char page[LINES] int main(int argc,
char *argv[]) {
/* Declarations */
#define LINES 5*10*20

After preprocessor
Symbol replaced
char page[5*10*20]
int main(int argc, char *argv[])

• The replacement string can be any string of characters and replaces the symbol exactly
#define LINES 10+10

Before preprocessor
myprog.c decs.h
/* My Program */
#include “decs.h” char page[LINES] int main(int argc,
char *argv[]) {
pagesize = LINES * 5; }
/* Declarations */
#define LINES 10+10

After preprocessor
Symbol replaced
char page[10+10]
int main(int argc, char *argv[])
pagesize = 10+10 * 5;

• Always bracket expressions in defined symbols:
#define LINES (10+10)

Defined symbols: macros with parameters
• A macro looks like a function with parameters
• A macro is processed by the preprocessor: replacing symbols in the body by parameters
#define min(a,b) ((a) < (b) ? (a):(b)) Ternary operator ?: a 600
…. /* code for wide windows */

Conditional inclusion
Both #ifdef and #if can have an #else eg
#ifdef DEBUG
…. /* Debugging version */
… /* production version */ #end

Conditional inclusion
#if can have an #elif eg
#if WIDTH > 600
…. /* wide version */
#elif WIDTH > 400
… /* medium version */
… /* narrow version */ #endif

Before preprocessor
#include “declarations.h”
int main(int argc, char *argv[]) {
#ifdef DEBUG
printf(“MyProg (debug version)\n”); #else
printf(“MyProg (production version)\n”); #endif
return 0; }

declarations.h
#define DEBUG

After preprocessor
int main(int argc, char *argv[]) {
printf(“MyProg (debug version)\n”); }

Controlling the preprocessor from the gcc command
gcc -DWIDTH=600 prog.c has the same effect as
#define WIDTH 600
at the beginning of the program
#define or #undef within the program overrides the command line setting

gcc -Didentifier is equivalent to
#define identifier
multiple -D arguments can be used:
gcc -DWIDTH=600 -DTEST prog.c

Useful for debugging
gcc -DEBUG prog.c
#ifdef EBUG
#define DEBUG(m) printf(“debug: %s\n”, (m)) #else
#define DEBUG(m) /* null statement */ #endif
DEBUG(“called proc fn”); …

#ifdef DEBUG printf(…)
enum {DEBUG = 0} …
if (DEBUG)
printf(…)
Alternatives
compared with

Pre-defined Symbols
• the preprocessor defines several symbols automatically
• the most useful of these are:
__LINE__ contains the current line number at any point
__FILE__ contains the name of the current program file

When would you need them?
• _ _LINE_ _? • _ _FILE_ _?

Debug example revisited
gcc -DEBUG prog.c
continuation indicator
#ifdef EBUG
#define DEBUG(m) \
printf(“debug: %s at line %d in file %s\n”, \ (m), __LINE__, __FILE__)
#define DEBUG(m) /* null statement */ #endif
DEBUG(“called doit function”); …

#include revisited
• the normal form of #include has a file name in double quotes – this specifies a relative or absolute path for the file
• if the file name is enclosed in <> the file is searched for in /usr/include
• the preprocessor can be instructed to look in other directories using the
-I directory flag
• this allows you to have your own directory for include files

#include
• the preprocessor will look in
/usr/include for the defs.h file
• if we use the command
gcc -I/home/john/include myprog.c
the preprocessor will look in /home/john/include for the file

#define IF if( #define THEN ) #define BEGIN { #define END }
IF a == 1 THEN BEGIN
dothat(); END
A new language! Unreadable for the next programmer.

Preprocessor as a tool • gcc -E ….
• runs just the preprocessor
• can be used as a tool exploiting – #define call by name
– #ifdef for conditional generation

Example: hack templates
• Generate text in different forms as required: – #include parts
– #define to replace parts

Role of preprocessor
• lotsofitaround,especiallyfor – machine-dependencies
– OS versions
• prettyhardtoreadcodewithlotsofconditional compilation through it
• howtodebugtheconditionalcompilations proprocessor “code”?

• the preprocessor is very useful for configuring programs
– different versions – debugging
• not found in Java
• image: https://packagecontrol.io/packages/C%20Improved

End of Segment

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com