Main Program Revisited. Reading Assignment. K.N. King Chapter 3, 22. K.N. King Sections Example of Argument Processing

Similar documents
students taking CSC181F in the Fall term 1999/2000 at the These lecture notes are provided for the personal use of University of Toronto

File I/O. Preprocessor Macros

CS240: Programming in C

System Software Experiment 1 Lecture 7

CSci 4061 Introduction to Operating Systems. Input/Output: High-level

UNIT IV-2. The I/O library functions can be classified into two broad categories:

Content. Input Output Devices File access Function of File I/O Redirection Command-line arguments

Standard C Library Functions

Input / Output Functions

Input/Output and the Operating Systems

Systems Programming. 08. Standard I/O Library. Alexander Holupirek

Standard File Pointers

CS113: Lecture 7. Topics: The C Preprocessor. I/O, Streams, Files

Mode Meaning r Opens the file for reading. If the file doesn't exist, fopen() returns NULL.

C mini reference. 5 Binary numbers 12

Copyright The McGraw-Hill Companies, Inc. Permission required for reproduction or display.

Quick review of previous lecture Ch6 Structure Ch7 I/O. EECS2031 Software Tools. C - Structures, Unions, Enums & Typedef (K&R Ch.

UNIT-V CONSOLE I/O. This section examines in detail the console I/O functions.

File Access. FILE * fopen(const char *name, const char * mode);

Advanced C Programming Topics

File IO and command line input CSE 2451

2009 S2 COMP File Operations

Topic 8: I/O. Reading: Chapter 7 in Kernighan & Ritchie more details in Appendix B (optional) even more details in GNU C Library manual (optional)

Darshan Institute of Engineering & Technology for Diploma Studies Unit 6

Computer Programming Unit v

PROGRAMMAZIONE I A.A. 2017/2018

ITC213: STRUCTURED PROGRAMMING. Bhaskar Shrestha National College of Computer Studies Tribhuvan University

EECS2031. Modifiers. Data Types. Lecture 2 Data types. signed (unsigned) int long int long long int int may be omitted sizeof()

Contents. A Review of C language. Visual C Visual C++ 6.0

UNIX Shell. The shell sits between you and the operating system, acting as a command interpreter

The Design of C: A Rational Reconstruction (cont.)

25.2 Opening and Closing a File

C How to Program, 6/e by Pearson Education, Inc. All Rights Reserved.

CSCI 171 Chapter Outlines

Unit 6 Files. putchar(ch); ch = getc (fp); //Reads single character from file and advances position to next character

ENG120. Misc. Topics

C Basics And Concepts Input And Output

File (1A) Young Won Lim 11/25/16

C PROGRAMMING. Characters and Strings File Processing Exercise

Chapter 12. Files (reference: Deitel s chap 11) chap8

Goals of C "" The Goals of C (cont.) "" Goals of this Lecture"" The Design of C: A Rational Reconstruction"

Basic I/O. COSC Software Tools. Streams. Standard I/O. Standard I/O. Formatted Output

211: Computer Architecture Summer 2016

C Input/Output. Before we discuss I/O in C, let's review how C++ I/O works. int i; double x;

CS246 Spring14 Programming Paradigm Files, Pipes and Redirection

The Design of C: A Rational Reconstruction (cont.)" Jennifer Rexford!

C How to Program, 6/e by Pearson Education, Inc. All Rights Reserved.

CSE2301. Introduction. Streams and Files. File Access Random Numbers Testing and Debugging. In this part, we introduce

Course organization. Course introduction ( Week 1)

Computational Methods of Scientific Programming Fall 2007

SWEN-250 Personal SE. Introduction to C

IO = Input & Output 2

Pointers cause EVERYBODY problems at some time or another. char x[10] or char y[8][10] or char z[9][9][9] etc.

Lecture 7: Files. opening/closing files reading/writing strings reading/writing numbers (conversion to ASCII) command line arguments

Accessing Files in C. Professor Hugh C. Lauer CS-2303, System Programming Concepts

Preprocessing directives are lines in your program that start with `#'. The `#' is followed by an identifier that is the directive name.

Computer Programming: Skills & Concepts (CP) Files in C

Standard I/O in C, Computer System and programming in C

Continued from previous lecture

Computer Programming: Skills & Concepts (CP1) Files in C. 18th November, 2010

UNIX System Programming

Rule 1-3: Use white space to break a function into paragraphs. Rule 1-5: Avoid very long statements. Use multiple shorter statements instead.

File I/O. Arash Rafiey. November 7, 2017

CMPT 102 Introduction to Scientific Computer Programming. Input and Output. Your first program

Library Functions. General Questions

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

Lecture 03 Bits, Bytes and Data Types

Should you know scanf and printf?

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

CSC 1107: Structured Programming

Pointers and File Handling

C programming basics T3-1 -

C-Refresher: Session 10 Disk IO

The Design of C: A Rational Reconstruction: Part 2

Input/Output: Advanced Concepts

CS 261 Fall Mike Lam, Professor. Structs and I/O

CSC 1107: Structured Programming

Introduction to file management

C Fundamentals & Formatted Input/Output. adopted from KNK C Programming : A Modern Approach

Organization of a file

System Programming. Standard Input/Output Library (Cont d)

Model Viva Questions for Programming in C lab

Binghamton University. CS-220 Spring Includes & Streams

1 The CTIE processor INTRODUCTION 1

LANGUAGE OF THE C. C: Part 6. Listing 1 1 #include <stdio.h> 2 3 int main(int argc, char *argv[]) PROGRAMMING

M.CS201 Programming language

Lecture 9: File Processing. Quazi Rahman

EM108 Software Development for Engineers

Data File and File Handling

CSC209H Lecture 3. Dan Zingaro. January 21, 2015

C: How to Program. Week /June/18

Naked C Lecture 6. File Operations and System Calls

CSE 230 Intermediate Programming in C and C++ Input/Output and Operating System

File Handling. Reference:

Chapter 14 - Advanced C Topics

CSI 402 Lecture 2 Working with Files (Text and Binary)

CYSE 411/AIT681 Secure Software Engineering Topic #12. Secure Coding: Formatted Output

2/9/18. CYSE 411/AIT681 Secure Software Engineering. Readings. Secure Coding. This lecture: String management Pointer Subterfuge

Files and Streams Opening and Closing a File Reading/Writing Text Reading/Writing Raw Data Random Access Files. C File Processing CS 2060

fopen() fclose() fgetc() fputc() fread() fwrite()

Transcription:

Reading Assignment Main Program Revisited void main( int argc, char * argv[] ) K.N. King Chapter 3, 22 K.N. King Sections 13.7 argc is the number of command line arguments that have been passed to the main program argv is a pointer to an array of strings which are the arguments to the program argv[ 0 ] is the name that was used to invoke the program. argv[ 1 ] to argv[ argc ] are the arguments that were passed to the program. argv[ argc + 1 ] is always NULL mymain fee fie foo fum argc 4 argv mymain fee fie foo fum 305 306 Example of Argument Processing main( int argc, char argv[] ) { /* Argument Processing */ for (argc--, argv++; argc > 0; argc--, argv++) { /* process options marked with - */ if (**argv == - ) { /* A flag argument */ /* Process all flags in this arg, e.g. -AbDf */ while (*++(*argv)) { switch (**argv) { case x : /* process one flag */ break; default: fprintf(stderr, "Unknown flag: %c ; ", **argv); exit(1); } } } else /* Process everyting else */ process( *argv ); /* Do something to argument */ } } 307 HOW TO Access Environment Information #include stdlib.h char * getenv ( const char * name ) ; In the Unix Shell you can set environment variables that can be used to communicate information to programs. Execute the Unix command printenv to see what your current environment variables are. The getenv function can be used by a program to retrieve the current value of environment variables from Unix. The argument name is the name of an an environment variable, getenv returns a pointer to a string containing the value currently assigned to name and NULL if name is not defined. Example: Define TMPDIR=/bigSpace/tmp in environment. 308

Input and Output in C #include stdio.h A stream is any source of input or any destination for output. A file pointer ( of type FILE * ) is the standard way to refer to streams in C programs. The three standard streams are automatically ready to use when a program starts execution. By convention, standard error is used for printing error messages. These messages can be redirected to a destination that is different than standard output. stdio.h defines three standard streams File Pointer Stream Default Meaning stdin Standard Input Keyboard input stdout Standard Output Terminal Screen stderr Standard Error Terminal Screen The command that invokes a program may redirect the meaning of the standard streams to be a file, a device or another program. Programs are usually written to work on the standard streams. If a program needs more sources or destinations it can create them as it s executing. 309 310 Text and Binary Files Character Input (Text Files) stdio.h supports two kinds of files. Text Files generally contain characters and are usually easily readable or printable. Text files are viewed as a sequence of lines where lines are separated by the NEWLINE character ( \n ). Binary files contain raw data in the encoded in the internal representation used by the hardware. int fgetc(file * stream ) int getc(file * stream ) int getchar( void ) char *fgets( char * S, int N, FILE * stream ) int ungetc( int C, FILE * stream ) Read one character from stream Inline version of fgetc getc(stdin) Reads at most N - 1 characters into array S Stops on newline. S is null terminated Push character c back onto stream Binary files can be used to store arrays, structures and other more complicated data structures. Generally binary input and output is much more efficient than text input and output since no conversion to/from the binary internal representation is required. Character input functions return the special value EOF on end of file or error. WARNING: getc, fgetc and getchar return int not char. String input functions return NULL on end of file or error. 311 312

Character Input Examples int ch; FILE * fp; while ((ch = getc(fp))!= EOF) { } fgets(str, sizeof(str), fp); /* reads a line from fp */ fgets(str, sizeof(str), stdin); /* read a line from standard input */ #include <ctype.h> while (isdigit(ch = getc(fp))) { } ungetc(ch, fp); /* puts back last value of ch */ HOW TO Handle Errors and End of File Every call on an input function must check for possible end of file or error. WARNING: The value of EOF returned by fgetc, getc and getchar is NOT a valid char value. Always read characters into an int variable, check for EOF and then assign the input to a char variable. The function int feof( FILE * stream ) returns true if an end of file has been detected while reading stream. Note that this function does not return true until an attempt has been made to read past the end of file. 313 314 Character Output (Text Files) int fputc( int C, FILE * stream ) writes character C on stream int putc( int C, FILE STAR stream ) inline version of fputc int putchar( int C ) putc(c, stdout) int fputs( const char * S, FILE * stream) writes string S on stream int puts( const char * S) fputs( S, stdout) Output functions return EOF on error. Examples: FILE * fp ; putchar( ch ) ; /* writes ch to stdout */ putc( ch, fp ) ; /* writes ch to fp */ Formatted Output A format string is used to specify the exact layout of each line of printed output. The format string may contain text which is output literally The format string contains format control characters which cause data values to be printed. Embed ASCII control characters (e.g. \n (newline), \t (tab) and \f (pagefeed)) in format string for line and page control WARNING: Be Careful to exactly match format string with argument list. Mismatches cause crashes. Sink for output can be standard stream, file or string puts( "Hello world!" ) ; /* writes to stdout */ fputs( "Hello world!", fp ) ; /* writes to fp */ 315 316

printf function printf(const char * format, expressionlist ) expressionlist is a list of expressions separated by commas format is a string that specifies formating for printed output Expressions in the expression list are matched in order with format control characters in format WARNING: most versions of C do NOT check that you ve got this right. Be especially careful about char vs. string and different sizes of integers and reals. Format Control Characters %C %-C %widthc %.precc C is any format control character A preceding - sign causes the field to be left justified width and prec are integer constants. width specifies the printed width of the field in characters. prec specifies number of digits after decimal point for floating point numbers width or precision can be * which causes value to be taken from next argument 317 318 Output Format Control Characters c single character p void *, pointer s string f real, normal notation d integer, signed decimal e real, scientific notation i integer, signed decimal E real, scientific notation u integer, unsigned decimal g real, shorter of e, f, notation o integer, unsigned octal G real, shorter of E, f, notation Examples of formatted output printf("csc209s Assignment %d\n", anumb ); sprintf( buffer, "(%s%c%s)", left_op, operator, right_op ); fprintf(myfile, "%-d %s %e\n", count, name, result ); x X integer, unsigned hexadecimal integer, unsigned hexadecimal printf("pointer value is %p (%x)\n", p, p ) ; printf("%.*f", 4, x); printf("%.*f", WIDTH, x); printf("%*.4f", 12, x); 319 320

fprintf & sprintf fprintf(file * stream,const char * format, expressionlist) sprintf(char * S,const char * format, expressionlist) format and expressionlist same as printf. fprintf writes output to the designated file sprintf writes output to the designated string WARNING: Be Careful to always give a file as first argument to fprintf and a string as first argument to sprintf. Make sure that string for sprintf is large enough to hold any possible result including a trailing null character. HOW TO Use Files in C InaCprogram,afileisahandle that is used to access some external source or destination for data. The FILE * data type is a pointer to a control block that specifies the type of a stream, how to access the stream and the current location in the stream for input or output. The system establishes default streams for stdin, stdout and stderr. These can be overridden via redirection at the Unix command level. The fopen function is used to set up an association between an external file and a stream in the program. The fclose function is used to terminate the association set up by fopen. 321 322 File Open FILE * fopen( const char * filename, const char * mode ) ; File Close int fclose( FILE * stream ) Opens named file and returns stream pointer or NULL if open fails. Files must be opened before they are used for reading or writing. Modes include: r open for reading w create text file for writing, discard previous contents Flush any unwritten data to output stream Discard any unread input in input stream Deallocates buffer, closes stream. File should not be used after it is closed. a r+ w+ a+ open for append or create open for update (read & write) create text file for update open or create for append & update Returns zero if successful; otherwise returns EOF WARNING: Always check that fopen has returned a non-null pointer. 323 324

scanf - formatted input User supplies format string, as in printf. Format string specifies order and format of input items. User provides addresses of variables in which to store input items. scanf attempts to read from its input source and match the input stream against the format string. Successful matches cause values to be assigned to the variables. scanf returns number of variables assigned to, which may be less than the number of items requested. scanf function int scanf(char *format,varaddresslist ) format is a format string specifying the expected input format varaddresslist is a list of addresses of variables. Use either pointers to allocated memory or & variable to generate the address of local variables. Always check number of assignments done by scanf Always provide a variable ADDRESS for each data item in the format list 325 326 scanf format string One more consecutive white-space in a scanf format string match zero or more white-space in the input stream. Ordinary characters are expected to match the characters in the input stream Conversion items beginning with % cause data values to be read and assigned to the next unassigned variable. An assignment suppression character * after the % causes a data item to be read by suppresses assignment to the variable. Use this to skip over unwanted input. scanf automatically skips over white-space (blank, tab, newline, carriage return, etc.) in its input % can be followed by an integer constant width specifier that controls the number of input characters read. e.g %1s to read 1 character at a time. scanf conversion characters a Char Type Variable d decimal integer int * i integer (any) int * o octal integer int * u unsigned integer unsigned * x hex integer int * c character (no ws skip) char * s string char * e float float * f float float * g float float * a See King pages 493-494 for a discussion of conversion modifiers. 327 328

int i, j ; long k ; double X ; char ch, str[100]; int nscanned ; scanf examples nscanned = scanf("%d%i", & i, & j ); nscanned = scanf("%s is %c", str, & ch ); fscanf and sscanf int fscanf( FILE * stream, char * format, varaddresslist ) int sscanf( char * source, char * format, varaddresslist ) fscanf like scanf except input comes from designated file sscanf like scanf except input comes from character string Example: fscanf(infile, %s, str ); /* read string from file */ sscanf(str, %d%d, &i, &j ); /* extract two int from str */ nscanned = scanf("%*d%d", & i); nscanned = scanf("%le%ld", & X, & k ); 329 330 HOW TO Use sscanf and ssprintf sprintf can be used in a program to build up complicated character strings. More efficient than using several strcpy/strcat operations. Provides access to all of the builtin conversion routines from internal representation to characters. scanf can be used in a program to scan strings and extract information. Provides access to the internal conversion routines. Can read input with fgets and then try alternative analysis with different scanf calls. Allows you to validate input without crashing the program. WARNING: make sure string argument to sprintf is long enough to hold any possible output. Block Input and Output size t fread( void * ptr, size t size, size t nmemb, FILE * stream ) size tfwrite(const void * ptr, size t size, size t nmemb, FILE * stream ) fread reads an array from a stream to memory (ptr) in a single operation fwrite copies an array from memory (ptr) to a stream in a single operation ptr is the address of the data to transfer size is the size of each element of an array in bytes nmemb is the number of array elements to write/read return value of fread is the number of elements read return value of fwrite is the number of elements written Good Technique: check return value against nmemb 331 332

HOW TO Use fread & fwrite Use fread and fwrite to move blocks of binary information between memory and disk files. fread and fwrite are much more efficient than fprintf and fscanf for moving large amounts of data to/from disk. The function setvbuf can be used to disable buffering when reading and writing binary information. This may improve speed. WARNING: reading and writing any data structure containing pointers (including char * ) will NOT produce a correct result. Example Test case Write 100,000 random double numbers to a file. fwrite was about 150 times faster then fprintf. Read 100,000 random double numbers from a file. fread was about 40 times faster than fscanf. Binary file was 800,000 bytes, text file was 1,300,000 bytes. You can set size to total number of bytes to transfer and nmemb to one. This may be faster. 333 334 Example of Binary Input/Output struct dstruct { double xcoord, ycoord, zcoord ; long redcolor, greencolor, bluecolor ; } ; struct dstruct data[ 10000 ] ; FILE * datafile ; assert( ( datafile = fopen( "myfile", "w" ) ) ); fwrite( & data[ 0 ], sizeof( struct dstruct ), 10000, datafile ); fclose( datafile ); assert( ( datafile = fopen( "myfile", "r" ) ) ); fread( & data[ 0 ], sizeof( struct dstruct ) * 10000, 1, datafile ); fclose( datafile ); Seek & Tell long ftell( FILE * stream ) int fseek( FILE * stream, long offset, int origin ) ftell returns the current position in the file stream fseek sets the file position for stream. Position is set offset bytes from origin origin is one of: SEEK_SET - start of file SEEK_CUR - current position SEEK_END - end of file Use SEEK_SET with value from ftell Use fseek( file, 0L, SEEK CUR ) to reset internal file pointers between read and write operations on the same file. 335 336

Reading Assignment C Preprocessor Processes program text before compiler Implements K.N. King Chapter 14 Section 26.1 Source Include mechanism Conditional compilation Macro Definition and Use 337 338 Source inclusion Used to decompose large programs into manageable pieces Most common usage is: foo.h - interface file foo.c - implementation foo.o - compiled implementation Interface file contains: function headers shared definitions structs, constants,types, macros Avoid shared variables Programs that use foo include foo.h to get interface and get linked with foo.o to get the implementation /* File house.h - Interface to house.c */ /* Hide real representation inside house.c */ #define HOUSE HEIGHT 2.0 #define HOUSE WIDTH 3.0 #define ATTIC HEIGHT 0.7 Example Interface File extern void DrawHouse(double x, double y) ; extern void DrawOutline(double x, double y) ; extern void DrawWindows(double x, double y) ; extern void DrawDoor(double x, double y) ; extern void DrawBox(double x, double y, double width, double height) ; extern void DrawTriangle(double x, double y, double base, double height) ; extern void DrawCenteredCircle(double x, double y, double r) ; 339 340

#include #include "filename" #include <systemfile> filename is the name of the file to include. Compiler searches through a standard list of directories looking for it. Usually start with current directory. Macros A macro is a piece of text that is used repeatedly in a program. Use macros for: defining literal constants defining short pieces of ugly code hiding details from the user Macros affect the source program text just before the program is compiled. The second form specifies a system interface file. The compilers search starts in the directory /usr/include Good Technique: Use only the first form of include. The compiler will still find system files, but you can customize include files if you have to. 341 342 Macro Definition #define macroname text #define BUFSIZE ( 1024 ) #define NULL ( (void * )0) Simple Macro Examples macroname is the name of the macro Good Technique: use UPPERCASE NAMES for macros to make them stand out a program that uses them The text (if any) on the same line following the macro name becomes the definition of the macro. Use the backslash character ( \ ) at the end of a line to extend long definitions. Examples: #define A SIZE ( 15 ) #define PROMPT ( Hi: ) #define TRUE ( 1 ) #define FALSE ( 0 ) #define TWO PI (2*3.14159) #define RESET i=j=k=0 ; #define POLYX ( x * (x * (3.14 * x + 2.78) + 1.35) - 2.16 ) #define CLEARA int i ; for (i=0;i< N ; ) \ A[i++] = 0 ; 343 344

Macro Parameters Examples Macro with Parameters #define macroname( macroparmlist ) text Macros can be defined with simple text parameters that are substituted as directed in the body of the macro Parameters are identifiers listed in parentheses after the macro name Use this form for declarations or code fragments with substitutable parts Parameter substitution is text substitution macroparmlist is a list of identifiers separated by commas Examples: #define SCALE(x) ((x)*10) #define MIN(x,y) ( (x) < (y)? (x) : (y) ) #define POLY(x) ( (x)*((x)*(3.14*(x)+2.78)+1.35)-2.16 ) #define FILLARRAY( arr, val, n) \ int i; for (i=0 ; i < (n) ; ) arr[i++] = val; Examples of use: j = SCALE( i + 1 ) ; if (MIN(i, j ) == 0 ) y = POLY( y+7.0 ) ; FILLARRAY( mydata, 100, 3.14 ) ; 345 346 HOW TO Use Macros Macro Use For macros without parameters, just write name of macro in program, C preprocessor substitutes macro body for name For macros with parameters, follow macro name with list of macro parameters enclosed in parentheses. The text of each parameter is substituted into the macro body Examples: char buf1[ BUFSIZE ] ; int alldone = FALSE ; float circumference = TWO PI * r ; i = MAX( 1, i ) ; SWAP( A[k], A[k+1] ); STOPHERE ; Use macros for program parameterization and as an abstraction tool. Don t use it to make programs unreadable or obscure. Make body of macro a complete expression or statement Macros with expression parameters should be designed to work with any valid expression passed as an argument. Good Technique: Wrap parameter names in parentheses to avoid unexpected expansions and to force error message for invalid parameters Good Technique: Macros that look like statements should behave like statements. Wrap body in and. Do not put ; at end. The truly paranoid will use each macro parameter exactly once. 347 348

More Macro Examples #define DATARRAY(name,size) float name[size] #define MAX( a, b ) ((a) > (b)? (a) : (b) ) #define SWAP( x, y ) int t =(x); x = (y); y = t #define CRASH_AND_BURN( why ) \ fprintf(stderr, Bailing out of program due to error %s\n, why ); \ abort(); \ #define MALLOC( size, type, pointer ) \ void * mtemp ; \ mtemp = malloc( (size) ) ; \ assert (mtemp); \ pointer = ( type ) mtemp ; \ Conditional Compilation Used to selectively include or exclude parts of a program Used for: Optional code (e.g. debugging) Machine customization Operating system customization Select based on: defined and undefined macro names compiler flags -Dname, -Dname=value, -Uname compile time expressions, can use most C operators Conditionals may be nested Note use of ( ) around expressions and around statements. mtemp is used in MALLOC to achieve the one-touch property. 349 350 Preprocessor Constant Expressions The conditional expression that the preprocessor can evaluate are made up of Integer constants defined using #define. Integer constants defined using the compiler option -Dname=constant use of the defined( identifier ) function which has the value one if the identifier has been defined in the preprocessor at that point. Almost all C arithmetic and logical operators. Logical expressions can be used to define complicated conditions. Symbols predefined by the compiler, e.g. i486, GNUC Generally these symbols identify the hardware, the compiler and the operating system. Use the command gcc -dm -E to see your definitions. #if head #if constant-expression #ifdef identifier #ifndef identifier The three forms of if head listed above are used at the start of a preprocessor conditional statement. the first form is true if the constant (i.e. compile time) expression evaluates to non-zero. This expression can include use of the defined(identifier) predicate Second form is true if identifier has been defined using #define or by the compiler -D option. Third form is true if identifier has not been defined using #define or it has been undefined using the compiler -U option. 351 352

Preprocessor Conditional Statement if-head text #elif constant-expression text #else text #endif text is any program text. It may be arbitrarily long. It may contain nested conditionals. If if-head evaluates to true, text is included in the program The elif part may be repeated as many times as required. The else part is optional. If it appears, then the text following the #else is included in the program if none of the preceding if or elifs have evaluated to true. 353 #if examples #if X==3 int data3[ 100 ] ; #else int data2[ 50 ], data1[ 200 ] ; #endif #ifdef DEBUG fprintf(stderr, Made it as far as Checkpoint Charlie\n ); #endif #ifndef ONCE #define ONCE #endif #if defined(unix) defined( unix ) #include < stdio.h> #elif defined(vms) #include < VMSstdio.h> #else #include D:/SYS/INCLUDE/STDIO.H #endif 354 HOW TO USE #if et.al. KISS Use conditional compilation sparingly to customize your program for different environments. Use indentation and paragraphing to indicate matching #if, #else and #endif. Complicated #if structures are a symptom of bad program design. As with any use of conditionals, make sure all cases are covered and each logical expression does what you expect. KISS Functions with a Variable Number of Arguments There is a mechanism in C that allows you to write your own functions that take a variable number of arguments like printf and scanf. The include file stdarg.h defines three macros void va start( va list ap, parmn ) ; type-name va arg( va list ap, type-name ) ; void va end( va list ap ) ; that can be used to access variable length argument lists in a safe and portable way. A function that takes a variable number of arguments must have at least one named argument. An ellipsis ( ) is used to tell the compiler that the function takes an arbitrary number of arguments. Example int dolist( int first,... ) ; 355 356

HOW TO Use Variable Length Argument Lists Declare a variable of type va list to hold an index into the variable length argument list while it is being processed. Example va list ap ; The variable argument list comes after the last named parameter. Call va start to initialize the argument pointer ap to the first variable argument va start( ap, first ) ; The function va arg is used to fetch a variable argument and advance to the next argument in the list. argval = va arg( ap, type-name ) ; where type-name is the type of the variable ( argval ) being assigned to. Call the function va end va end( ap ) ; to clean up after argument processing. You can cycle through the argument list more than once by calling va start to reinitialize the argument pointer. You can use more than one argument pointer on the same list. 357