void sum(char *, int, ...)

C Program Design
Supplements
主講人:虞台文
Content






Who takes the return value of main()?
Using Command-Line arguments
Variable-Length Argument Lists
Program Termination by exit and atexit
Unconditional Branching with goto
C Preprocessor
C Program Design
Supplements
Who takes the return
value of main()?
main()
int main( void )
{
/* declaration of variable */
/* operations */
return result; /* who takes the result? */
}
Example: Unix grep
grepExample.txt
Ah Love! could you and I with Fate conspire
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
grep "ould" grepExample.txt
Ah Love! could you and I with Fate conspire
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
Example: Unix grep
grepExample.txt
Ah Love! could you and I with Fate conspire
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
grep "ould" grepExample.txt
Ah Love! could you and I with Fate conspire
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
Pseudo Code 
The Idea to Fulfill the Task
count = 0;
while (there's another line)
if (the line contains the pattern)
print it
count++;
return count;
Pseudo Code 
The Idea to Fulfill
How? the Task
Define functions to mind the detail.
count = 0;
while (there's another line)
if (the line contains the pattern)
print it
count++;
return count;
Pseudo Code 
The Idea to Fulfill the Task
count = 0;
int getline(char
line[], int
max)
while (there's
another
line)
int strindex(char
source[], char
if (the
line contains
thesearchfor[])
pattern)
print it
count++;
return count;
count = 0;
while (there's another line)
if (the line contains the pattern)
print it
Example: MyGrep
count++;
return count;
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int max);
int strindex(char source[], char searchfor[]);
char pattern[] = "ould";
/* pattern to search for */
/* find all lines matching pattern */
int main( void )
{
char line[MAXLINE];
int count = 0;
while (getline(line, MAXLINE) > 0)
if (strindex(line, pattern) >= 0) {
printf("%s", line);
count++;
}
return information to
return count;
}
. . . . . . . . . . . . . . . . . .
OS
while (there's another line)
if (the line contains the pattern)
print it
Example: MyGrep
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int max);
int strindex(char source[], char searchfor[]);
char pattern[] = "ould";
forward references
/* pattern to search for */
/* find all lines matching pattern */
main()
{
char line[MAXLINE];
int count = 0;
while (getline(line, MAXLINE) > 0)
if (strindex(line, pattern) >= 0) {
printf("%s", line);
found++;
}
return information to
return count;
}
. . . . . . . . . . . . . . . . . .
OS
Batch Files
Ah Love! could you and I with Fate conspire
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
Example: MyGrep
練習:
1.
2.
3.
完成以上程式,並測試之。
撰寫一程式讀取使用者從標準輸入裝置中輸
入之字元直到發生EOF止,該程式會將所讀
取到的字元總數回傳給作業系統後結束執行。
撰寫一批次檔驗證你能正確收到上題程式之
回傳資料,並做適當顯示。
C Program Design
Supplements
Using Command-Line
arguments
Pass arguments to main on DOS or UNIX
int main( int argc, char *argv[] )
argument
count
Example:
argument
vector
>mycopy input output
argc: 3
argv[ 0 ]: "mycopy"
argv[ 1 ]: "input"
argv[ 2 ]: "output"
// mycopy.c
#include <stdio.h>
Example
int main( int argc, char *argv[] )
{
FILE *inFilePtr; /* input file pointer */
FILE *outFilePtr; /* output file pointer */
int c;
/* define c to hold characters input by user */
/* check number of command-line arguments */
if ( argc != 3 ){
printf( "Usage: mycopy infile outfile\n" );
return 0;
}
/* if input file can be opened */
if ( ( inFilePtr = fopen( argv[ 1 ], "r" ) ) != NULL ) {
/* if output file can be opened */
if ( ( outFilePtr = fopen( argv[ 2 ], "w" ) ) != NULL ) {
/* read and output characters */
while ( ( c = fgetc( inFilePtr ) ) != EOF ) {
fputc( c, outFilePtr );
} /* end while */
} /* end if */
else { /* output file could not be opened */
printf( "File \"%s\" could not be opened\n", argv[ 2 ] );
} /* end else */
}
else { /* input file could not be opened */
printf( "File \"%s\" could not be opened\n", argv[ 1 ] );
} /* end else */
return 0; /* indicates successful termination */
} /* end main */
C Program Design
Supplements
Variable-Length
Argument Lists
printf
Examples
scanf
int printf(const char *format, ...);
int scanf(const char *format, ...);
Variable-Length Argument List
Type and Macros  stdarg.h
Identifier
Explanation
va_list
A type suitable for holding information needed by macros va_start,
va_arg and va_end. To access the arguments in a variable-length
argument list, an object of type va_list must be defined.
va_start
A macro that is invoked before the arguments of a variable-length
argument list can be accessed. The macro initializes the object declared
with va_list for use by the va_arg and va_end macros.
va_arg
A macro that expands to an expression of the value and type of the next
argument in the variable-length argument list. Each invocation of
va_arg modifies the object declared with va_list so that the object
points to the next argument in the list.
va_end
A macro that facilitates a normal return from a function whose variablelength argument list was referred to by the va_start macro.
#include <stdarg.h>
#include <stdio.h>
Example
void sum(char *, int, ...);
int main(void)
{
sum("10+15+13=%d.\n",3,10,15,13);
sum("11+12+13+14+15=%d\n",5,11,12,13,14,15);
return 0;
}
void sum(char *string, int num_args, ...)
{
int sum=0;
int loop;
va_list ap;
va_start(ap,num_args);
for( loop=0; loop < num_args; loop++ )
sum+=va_arg(ap,int);
printf(string,sum);
va_end(ap);
}
C Program Design
Supplements
Program Termination by
exit and atexit
exit
exit & atexit

Function exit
–
–
–
–

atexit
Forces a program to terminate
Parameters – symbolic constants EXIT_SUCCESS or
EXIT_FAILURE
Returns an implementation-defined value
Example:
exit( EXIT_SUCCESS );
Function atexit
atexit( functionToRun );
–
–
–
Registers functionToRun to execute upon successful program
termination

atexit itself does not terminate the program

Functions called in reverse register order
Register up to 32 functions (multiple atexit() statements)
Called function cannot take arguments or return values
#include <stdio.h>
#include <stdlib.h>
void print( void ); /* prototype */
Example
int main( void )
{
int answer; /* user's menu choice */
atexit( print ); /* register function print */
printf( "Enter 1 to terminate program with function exit"
"\nEnter 2 to terminate program normally\n" );
scanf( "%d", &answer );
/* call exit if answer is 1 */
if ( answer == 1 ) {
printf( "\nTerminating program with function exit\n" );
exit( EXIT_SUCCESS );
} /* end if */
printf( "\nTerminating program by reaching the end of main\n" );
return 0; /* indicates successful termination */
} /* end main */
/* display message before termination */
void print( void )
{
printf( "Executing function print at program "
"termination\nProgram terminated\n" );
} /* end function print */
#include <stdio.h>
#include <stdlib.h>
void print( void ); /* prototype */
Example
int main( void )
{
int answer; /* user's menu choice */
atexit( print ); /* register function print */
printf( "Enter 1 to terminate program with function exit"
"\nEnter 2 to terminate program normally\n" );
scanf( "%d", &answer );
/* call exit if answer is 1 */
if ( answer == 1 ) {
printf( "\nTerminating program with function exit\n" );
exit( EXIT_SUCCESS );
} /* end if */
printf( "\nTerminating program by reaching the end of main\n" );
return 0; /* indicates successful termination */
} /* end main */
/* display message before termination */
void print( void )
{
printf( "Executing function print at program "
"termination\nProgram terminated\n" );
} /* end function print */
C Program Design
Supplements
Unconditional
Branching with goto
Unconditional Branching with goto

Unstructured programming
–
–

Use when performance crucial
break to exit loop instead of waiting until condition
becomes false
goto statement
–
–
–
Changes flow control to first statement after specified
label
A label is an identifier followed by a colon (i.e. start:)
Quick escape from deeply nested loop
goto start;
#include <stdio.h>
Example
int main( void )
{
int count = 1; /* initialize count */
start: /* label */
if ( count > 10 ) {
goto end;
} /* end if */
printf( "%d
count++;
", count );
goto start; /* goto start on line 9 */
end: /* label */
putchar( '\n' );
return 0; /* indicates successful termination */
} /* end main */
C Program Design
Supplements
C Preprocessor
C Preprocessor

Preprocessing
–
–
–
–
–

Occurs before a program is compiled
Inclusion of other files
Definition of symbolic constants and macros
Conditional compilation of program code
Conditional execution of preprocessor directives
Format of preprocessor directives
–
–
Lines begin with #
Only whitespace characters before directives on a line
Preprocessor Directives


#include
#define
–
–






Symbolic Constants
Macros
Conditional Compilation
#error and #pragma
# and ## Operators
Line Numbers
Predefined Symbolic Constants
Assertions
#include

Copy of a specified file included in place of the
directive
#include <filename>
–
–
Searches standard library for file
Use for standard library files
#include "filename"
–
–

Searches current directory, then standard library
Use for user-defined files
Used for:
–
–
Programs with multiple source files to be compiled
together
Header file – has common declarations and definitions
(classes, structures, function prototypes)
#define: Symbolic Constants
#define identifier replacement-text
When program compiled, all occurrences of symbolic
constant replaced with replacement text.
Example:
#define PI 3.14159
area = PI * r * r;
area = 3.14159 * r * r;
#define: Symbolic Constants

Using meaningful names for symbolic constants

By convention, using only uppercase letters and
underscores.
Example:
#define PI 3.14159
area = PI * r * r;
area = 3.14159 * r * r;
#define: Macro
Examples:
#define max(a, b) a > b ? a : b
x = max(y+7, 9);
Compiler
performs text
substitution
x = y+7 > 9 ? y+7 : 9;
#define: Macro
Examples:
#define max(a, b) a > b ? a : b
x = max(y+7, 9);
Compiler
performs text
substitution
x = y+7 > 9 ? y+7 : 9;
#define: Macro
Examples:
#define max(a, b) a > b ? a : b
x = 10;
y = 20;
z = 11 + max(x, y) + 9;
#define: Macro
Examples:
#define max(a, b) a > b ? a : b
x = 10;
y = 20;
z = 11 + max(x, y) + 9;

z = 11 + x > y ? x : y + 9;
#define: Macro
Examples:
#define max(a, b) a > b ? a : b
#define max(a, b) ((a) > (b) ? (a) : (b))
#define: Macro
More Examples:
#define PI 3.14159
#define CIRCLE_AREA(x) (PI * (x) * (x))
#define RECTANGLE_AREA( x, y ) ((x) * (y))
#undef


Undefines a symbolic constant or macro
If a symbolic constant or macro has been
undefined it can later be redefined