Вы находитесь на странице: 1из 46

1

Chapter 20 - C Legacy Code Topics


Outline 20.1 20.2 20.3 20.4 20.5 20.6 20.7 20.8 20.9 20.10 20.11 20.12 20.13 Introduction Redirecting Input/Output on UNIX and DOS Systems Variable-Length Argument Lists Using Command-Line Arguments Notes on Compiling Multiple-Source-File Programs Program Termination with exit and atexit The volatile Type Qualifier Suffixes for Integer and Floating-Point Constants Signal Handling Dynamic Memory Allocation with calloc and realloc The Unconditional Branch: goto Unions Linkage Specifications

2003 Prentice Hall, Inc. All rights reserved.

20.1 Introduction Several advanced topics in chapter Many capabilities specific to OS


Especially UNIX and/or DOS

Chapter for C++ programmers working with C legacy code

2003 Prentice Hall, Inc. All rights reserved.

20.2 Redirecting Input/Output on UNIX and DOS Systems Standard I/O


Keyboard (input) and screen (output) Can redirect I/O
Inputs can come from a file, output can go to a file

Redirect symbol (<)


Operating system feature (not C++ feature!)
UNIX and DOS

$ myProgram < input


myProgram is an executable file input is a data file $ is the command-line prompt

Input to program now comes from file input, not the keyboard
2003 Prentice Hall, Inc. All rights reserved.

20.2 Redirecting Input/Output on UNIX and DOS Systems Pipe command ( | )


Output of one program becomes input of another $ firstProgram | secondProgram Output of firstProgram goes to secondProgram

Redirect output ( > )


Output of program goes to a file $ myProgram > myFile
Output goes to myFile (erases previous contents)

2003 Prentice Hall, Inc. All rights reserved.

20.2 Redirecting Input/Output on UNIX and DOS Systems Append output (>>)
Output of program appends to end of file $ myProgram >> myFile
Output goes to end of myFile

2003 Prentice Hall, Inc. All rights reserved.

20.3 Variable-Length Argument Lists In C++, we use function overloading


Variable-length arguments for programmers working with C Create functions with unspecified number of arguments

Function format
Include <cstdarg> Use ellipsis () at end of parameter list
Must be last item in parameter list Must be one named parameter before ellipsis

double myFunction(int i, );

2003 Prentice Hall, Inc. All rights reserved.

20.3 Variable-Length Argument Lists Usage (inside function)


Declare object of type va_list
Holds data needed by other macros va_list myList;

Run macro va_start


First argument is va_list object Second is last parameter before ellipsis starts va_start( myList, i );

2003 Prentice Hall, Inc. All rights reserved.

20.3 Variable-Length Argument Lists Usage


Access arguments with macro va_arg
First argument is va_list
Second is the expected type of variable Returns the value myArg = va_arg( myList, double );

Can use different data types for different arguments

Run macro va_end


va_end( myList );

2003 Prentice Hall, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

// Fig. 20.2: fig20_02.cpp // Using variable-length argument lists. #include <iostream> using std::cout; using std::endl; using std::ios; #include <iomanip> using using using using std::setw; std::setprecision; std::setiosflags; std::fixed;

Outline
fig20_02.cpp (1 of 3)

#include <cstdarg> double average( int, ... ); int main() { double double1 double double2 double double3 double double4

Note use of ellipsis in the prototype, and one defined argument before it.

= = = =

37.5; 22.5; 1.7; 10.2;

2003 Prentice Hall, Inc.


All rights reserved.

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

cout << << << << << << << << << << << <<

fixed << setprecision( 1 ) << "double1 = " double1 << "\ndouble2 = " << double2 << "\ndouble3 = " double3 << "\ndouble4 = " << double4 << endl setprecision( 3 ) "\nThe average of double1 and double2 is " average( 2, double1, double2 ) "\nThe average of double1, double2, and double3 is " average( 3, double1, double2, double3 ) "\nThe average of double1, double2, double3" " and double4 is " average( 4, double1, double2, double3, double4 ) endl;

10

Outline
fig20_02.cpp (2 of 3)

return 0; } // end main

Call function with a variable number of arguments (passing the number of arguments as a parameter).

2003 Prentice Hall, Inc.


All rights reserved.

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

// calculate average Create a va_list object and double average( int count, ... ) { call macro va_start. double total = 0; count is the parameter va_list list; // for storing information needed by va_start

11

Outline
fig20_02.cpp (3 of 3)

before the ellipsis.

va_start( list, count ); // process variable length argument list for ( int i = 1; i <= count; i++ ) total += va_arg( list, double ); // end the va_start va_end( list ); return total / count; } // end function average

Extract each argument from list, treat as a double.

End the macros, helps with a normal function return.

2003 Prentice Hall, Inc.


All rights reserved.

double1 double2 double3 double4

= = = =

37.5 22.5 1.7 10.2

12

Outline
fig20_02.cpp output (1 of 1)

The average of double1 and double2 is 30.000 The average of double1, double2, and double3 is 20.567 The average of double1, double2, double3 and double4 is 17.975

2003 Prentice Hall, Inc.


All rights reserved.

13

20.4 Using Command-Line Arguments Can pass arguments to main in UNIX/DOS


Include parameters in main
int main( int argc, char *argv[] )

int argc
Number of arguments

char *argv[]
Array of strings that contains command-line arguments

Example: $ copy input output


argc: 3 argv[0]: "copy" argv[1]: "input" argv[2]: "output"

2003 Prentice Hall, Inc. All rights reserved.

14

20.4 Using Command-Line Arguments Upcoming example


Program to copy input file to output file copy input output Read a character from file input and write to file output
Stop when no more characters to read (EOF)

2003 Prentice Hall, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

// Fig. 20.3: fig20_03.cpp // Using command-line arguments #include <iostream> using std::cout; using std::endl; using std::ios; #include <fstream> using std::ifstream; using std::ofstream;

15

Outline
fig20_03.cpp (1 of 2)

Notice parameters in main.

int main( int argc, char *argv[] ) { // check number of command-line arguments if ( argc != 3 ) argv[1] is the cout << "Usage: copyFile infile_name outfile_name" << endl; else { ifstream inFile( argv[ 1 ], ios::in );

input file --

open for reading.

// input file could not be opened if ( !inFile ) { cout << argv[ 1 ] << " could not be opened" << endl; return -1;
} // end if

2003 Prentice Hall, Inc.


All rights reserved.

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

16
ofstream outFile( argv[ 2 ], ios::out ); // output file could not be opened if ( !outFile ) { cout << argv[ 2 ] << " could not be opened" inFile.close(); return -2;

Outline
argv[2] is the output file -open for writing. fig20_03.cpp (2 of 2) << endl;

} // end if
char c = inFile.get(); // read while ( inFile ) { outFile.put( c ); c = inFile.get(); } // end while // end else

// output character // read next character

Read a character from firstinFile character , and write to outFile. Loop stops when EOF reached.

return 0;

// end main

2003 Prentice Hall, Inc.


All rights reserved.

17

20.5 Notes on Compiling Multiple-SourceFile Programs Program with multiple source files
Function definition must be entirely in one file
Cannot be split up into multiple files

Global variables accessible to functions in same file


Must be defined in every file they are used Use extern to access global variable in another file Indicates variable defined later in file or in another file

Example
int myGlobal; (defined in file1) extern int myGlobal; (appears in file2)

2003 Prentice Hall, Inc. All rights reserved.

18

20.5 Notes on Compiling Multiple-SourceFile Programs Function prototypes


Can be used in other files, extern not needed

Include prototype in each file function used


Compile files together

Prototype indicates function defined later in same file, or in another file Example: loading header files
#include <cstring> Contains prototypes of functions We do not need to know where definitions are

2003 Prentice Hall, Inc. All rights reserved.

19

20.5 Notes on Compiling Multiple-SourceFile Programs Keyword static


In context of global variables/functions Can only be used by functions in same file
Internal linkage Globals/functions have external linkage by default

Used with utility functions called only in one file For functions
If defined before used, include static in definition Otherwise, use with prototype

Makefiles
make - utility to aid compilation and linking Saves effort of constantly recompiling for minor changes
2003 Prentice Hall, Inc. All rights reserved.

20

20.6 Program Termination with exit and atexit Function exit


Forces program to end Usually takes EXIT_SUCCESS or EXIT_FAILURE
Symbolic constants (#define) exit(EXIT_SUCCESS);

Returns value to environment, indicating success or failure


Exact value varies with system

2003 Prentice Hall, Inc. All rights reserved.

21

20.6 Program Termination with exit and atexit Function atexit


Takes pointer to function (function name)
atexit( myFunction ) Functions must take void, return void

Registers function to run when program ends successfully


When exit called, or when main terminates atexit does not terminate the program

Can register up to 32 functions


Use multiple atexit calls Called in reverse order of registration

2003 Prentice Hall, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

// Fig. 20.4: fig20_04.cpp // Using the exit and atexit functions #include <iostream> using std::cout; using std::endl; using std::cin; #include <cstdlib> void print(); int main() { atexit( print );

22

Outline
fig20_04.cpp (1 of 2)

//

Register print to be called when the program terminates. print must return void and take no function arguments. register print

print will be called if theexit" cout << "Enter 1 to terminate program with function << "\nEnter 2 to terminate program program endsnormally\n"; successfully.
int answer; cin >> answer;

2003 Prentice Hall, Inc.


All rights reserved.

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

// exit if answer is 1 if ( answer == 1 ) { cout << "\nTerminating program with function exit\n"; exit( EXIT_SUCCESS ); } // end if

23

Outline
fig20_04.cpp (2 of 2)

cout << "\nTerminating program by reaching the end of main" << endl; return 0; } // end main

Call function exit, passing a symbolic constant.

// display message before termination void print() { cout << "Executing function print at program termination\n" << "Program terminated" << endl; } // end function print

2003 Prentice Hall, Inc.


All rights reserved.

Enter 1 to terminate program with function exit Enter 2 to terminate program normally 2 Terminating program by reaching the end of main Executing function print at program termination Program terminated Enter 1 to terminate program with function exit Enter 2 to terminate program normally 1 Terminating program with function exit Executing function print at program termination Program terminated

24

Outline
fig20_04.cpp output (1 of 1)

2003 Prentice Hall, Inc.


All rights reserved.

25

20.7 The volatile Type Qualifier volatile qualifier


Indicates variable may be altered outside of program Variable not under control of program
Compiler cannot perform certain optimizations

2003 Prentice Hall, Inc. All rights reserved.

26

20.8 Suffixes for Integer and Floating-Point Constants C++ has suffixes for constants
Integer suffixes
u or U (unsigned) l or L (long) ul or UL (unsigned long)
Without suffix, uses smallest type that can hold number Examples: 174u, 1322L, 7364ul

Floating point suffixes


f or F (float) l or L (long double) Without suffix, double Examples: 3.14159L, 1.28f

Incorrect suffix is compiler error


2003 Prentice Hall, Inc. All rights reserved.

27

20.9 Signal Handling Signal


Unexpected event, can terminate program
Interrupts (ctrl-c) Illegal instructions Floating-point exceptions (division by zero)

Function signal traps unexpected signals


<csignal> Takes signal number (symbolic constants defined) Takes pointer to function (function name)
Signal handler passed signal number

May be required to call signal again inside handler


Depends on system Reinitialize handler after it handles signal
2003 Prentice Hall, Inc. All rights reserved.

28

20.9 Signal Handling


Signal SIGABRT SIGFPE Explanation Abnormal termination of the program (such as a call to abort). An erroneous arithmetic operation, such as a divide by zero or an operation resulting in overflow. Detection of an illegal instruction. Receipt of an interactive attention signal. An invalid access to storage. A termination request sent to the program.

SIGILL SIGINT SIGSEGV SIGTERM

2003 Prentice Hall, Inc. All rights reserved.

29

20.9 Signal Handling Function raise


Takes signal number Creates signal

2003 Prentice Hall, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

// Fig. 20.6: fig20_06.cpp // Using signal handling #include <iostream> using std::cout; using std::cin; using std::endl; #include <iomanip> using std::setw; #include <csignal> #include <cstdlib> #include <ctime> void signalHandler( int ); int main() { signal( SIGINT, signalHandler ); srand( time( 0 ) );

30

Outline
fig20_06.cpp (1 of 3)

Register signalHandler to deal with SIGINT events.

2003 Prentice Hall, Inc.


All rights reserved.

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

// create and output random numbers for ( int i = 1; i <= 100; i++ ) { int x = 1 + rand() % 50; // raise SIGINT when x is 25 if ( x == 25 ) raise( SIGINT ); cout << setw( 4 ) << i;

31

Outline
Note call to function raise.
fig20_06.cpp (2 of 3)

// output endl when i is a multiple of 10 if ( i % 10 == 0 ) cout << endl; } // end for

return 0; } // end main

2003 Prentice Hall, Inc.


All rights reserved.

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

// handles signal void signalHandler( int signalValue ) { cout << "\nInterrupt signal (" << signalValue << ") received.\n" << "Do you wish to continue (1 = yes or 2 = no)? "; int response;

32

Outline
fig20_06.cpp (3 of 3)

cin >> response;


// check for invalid responses while ( response != 1 && response != 2 ) { cout << "(1 = yes or 2 = no)? "; cin >> response; } // end while

// determine if it is time to exit if ( response != 1 ) exit( EXIT_SUCCESS );

May be required to reinitialize.

// call signal and pass it SIGINT and address of signalHandler signal( SIGINT, signalHandler );
} // end function signalHandler

2003 Prentice Hall, Inc.


All rights reserved.

10 20 30 40 50 60 70 80 90

33

11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57 58 59 61 62 63 64 65 66 67 68 69 71 72 73 74 75 76 77 78 79 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96 97 98 99 Interrupt signal (2) received. Do you wish to continue (1 = yes or 2 100

Outline
fig20_06.cpp output (1 of 1)

= no)? 1

1 2 3 4 Interrupt signal (2) received. Do you wish to continue (1 = yes or 2 = no)? 2

2003 Prentice Hall, Inc.


All rights reserved.

34

20.10 Dynamic Memory Allocation with calloc and realloc Dynamic memory allocation
Can create dynamic arrays

Function calloc
void *calloc(size_t nelmt, size_t size)
nelmt - number of elements in array size - size of each element

Returns pointer to dynamic array


Elements initialized to 0

2003 Prentice Hall, Inc. All rights reserved.

35

20.10 Dynamic Memory Allocation with calloc and realloc Function realloc
Resizes dynamic object
Data not modified if size increased If shrunk, beginning the same

void *realloc(void *ptr, size_t newSize)


ptr - pointer to object being reallocated newSize - new size of the object If ptr == 0, acts like malloc If newSize == 0 and ptr != 0, memory freed

Returns pointer to reallocated memory (NULL if no space)

2003 Prentice Hall, Inc. All rights reserved.

36

20.11 The Unconditional Branch: goto Unstructured programming


Use when performance crucial
Using break to exit loop

goto statement
goto label; Program jumps to first statement after label Label is an identifier and colon (start:)

Quick escape from deeply nested loop


goto start;

2003 Prentice Hall, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

// Fig. 20.7: fig20_07.cpp // Using goto. #include <iostream> using std::cout; using std::endl; #include <iomanip>

37

Outline
fig20_07.cpp (1 of 2)

using std::left; using std::setw;


int main() { int count = 1; start: // label

Notice declaration of label start

// goto end when count exceeds 10 if ( count > 10 ) goto end;

cout << setw( 2 ) << left << count; Note the ++count;
// goto start on line 17 goto start;

format of the goto statement.

2003 Prentice Hall, Inc.


All rights reserved.

28 29 30 31 32 33 34 35

38
end: // label

Outline
fig20_07.cpp (2 of 2) fig20_07.cpp output (1 of 1)

cout << endl; return 0; } // end main

10

2003 Prentice Hall, Inc.


All rights reserved.

39

20.12 Unions Union


Memory that contains a variety of objects
Data members share space Only contains one data member at a time

Conserves storage Only the last data member defined can be accessed Declaration same as class or struct
union Number { int x; float y; } ; Union myObject;

2003 Prentice Hall, Inc. All rights reserved.

40

20.12 Unions Union operations


Assignment to union of same type: = Taking address: & Accessing union members: . Accessing members using pointers: ->

2003 Prentice Hall, Inc. All rights reserved.

41

20.12 Unions Anonymous unions


No type name Does not create a type; creates an unnamed object
Contains only public data members

Data members accessed like normal variables


Use name, no . or -> required

If declared globally, must be static Example


union { int integer1; double double1; char *charPtr; }; // end anonymous union integer1 = 3;
2003 Prentice Hall, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

// Fig. 20.8: fig20_08.cpp // An example of a union. #include <iostream> using std::cout; using std::endl; // define union Number union Number { int integer1; double double1; }; // end union Number

42

Outline
fig20_08.cpp (1 of 2)

Create a named union with two data members. They share the same memory.

int main() { Number value;

// union variable // assign 100 to member integer1

value.integer1 = 100; cout << << << <<

"Put a value in the integer member\n" "and print both members.\nint: " value.integer1 << "\ndouble: " << value.double1 endl;

This will print the integer 100 as a double.

The program output is implementation dependent, but will show how ints and doubles are represented differently.
2003 Prentice Hall, Inc.
All rights reserved.

26 27 28 29 30 31 32 33 34 35

value.double1 = 100.0; cout << << << <<

// assign 100.0 to member double1

43

Outline
fig20_08.cpp (2 of 2) fig20_08.cpp output (1 of 1)

"Put a value in the floating member\n" "and print both members.\nint: " value.integer1 << "\ndouble: " << value.double1 endl;

return 0;

// end main

Put a value in the integer member and print both members. int: 100 double: -9.25596e+061 Put a value in the floating member and print both members. int: 0 double: 100

2003 Prentice Hall, Inc.


All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

// Fig. 20.9: fig20_09.cpp // Using an anonymous union. #include <iostream> using std::cout; using std::endl; int main() { Create an anonymous union. // declare an anonymous union The data members can be // members integer1, double1 and charPtr share the same space accessed without using a union { union name. int integer1; double double1; char *charPtr; }; // end anonymous union

44

Outline
fig20_09.cpp (1 of 2)

// declare local variables int integer2 = 1; double double2 = 3.3; char *char2Ptr = "Anonymous";

2003 Prentice Hall, Inc.


All rights reserved.

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

// assign value to each union member // successively and print each cout << integer2 << ' '; integer1 = 2; cout << integer1 << endl; cout << double2 << ' '; double1 = 4.4; cout << double1 << endl; cout << char2Ptr << ' '; charPtr = "union"; cout << charPtr << endl; return 0; } // end main

45

Outline
fig20_09.cpp (2 of 2) fig20_09.cpp output (1 of 1)

1 2 3.3 4.4 Anonymous union

2003 Prentice Hall, Inc.


All rights reserved.

46

20.13 Linkage Specifications Can call compiled C functions from C++ program
However, C does not encode function names like C++ Leads to problems linking

Linkage specifications
To link properly, tell compiler that function compiled in C For single functions
extern "C" function prototype

For multiple functions


extern "C" { function prototypes }
2003 Prentice Hall, Inc. All rights reserved.

Вам также может понравиться