Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 46

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

Outline

// Fig. 20.2: fig20_02.cpp


// Using variable-length argument lists.
#include <iostream>

fig20_02.cpp
(1 of 3)

using std::cout;
using std::endl;
using std::ios;
#include <iomanip>
using
using
using
using

std::setw;
std::setprecision;
std::setiosflags;
std::fixed;

#include <cstdarg>

Note use of ellipsis in the


prototype, and one defined
argument before it.

double average( int, ... );


int main()
{
double double1
double double2
double double3
double double4

=
=
=
=

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 <<
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<

return 0;
}

Outline

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;

// end main

fig20_02.cpp
(2 of 3)

Call function with a variable


number of arguments (passing
the number of arguments as a
parameter).

2003 Prentice Hall, Inc.


All rights reserved.

1
0

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

Outline

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

fig20_02.cpp
(3 of 3)

Extract each argument from


list, treat as a double.

End the macros, helps with a


normal function return.

return total / count;


}

// end function average

2003 Prentice Hall, Inc.


All rights reserved.

1
1

double1
double2
double3
double4

=
=
=
=

Outline

37.5
22.5
1.7
10.2

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

fig20_02.cpp
output (1 of 1)

2003 Prentice Hall, Inc.


All rights reserved.

1
2

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.

13

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.

14

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

Outline

// Fig. 20.3: fig20_03.cpp


// Using command-line arguments
#include <iostream>

fig20_03.cpp
(1 of 2)

using std::cout;
using std::endl;
using std::ios;
#include <fstream>
using std::ifstream;
using std::ofstream;

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;

input file -open for reading.

else {
ifstream inFile( argv[ 1 ], ios::in );
// 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.

1
5

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

Outline

ofstream outFile( argv[ 2 ], ios::out );

argv[2] is the output file -open for writing.


fig20_03.cpp
(2 of 2)

// output file could not be opened


if ( !outFile ) {
cout << argv[ 2 ] << " could not be opened" << endl;
inFile.close();
return -2;
} // end if
char c = inFile.get(); // read
while ( inFile ) {
outFile.put( c );
c = inFile.get();

Read a character from


first inFile,
characterand write to
outFile. Loop stops when
EOF reached.

// output character
// read next character

} // end while
// end else

return 0;
}

// end main

2003 Prentice Hall, Inc.


All rights reserved.

1
6

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.

17

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.

18

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.

19

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.

20

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.

21

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

Outline

// Fig. 20.4: fig20_04.cpp


// Using the exit and atexit functions
#include <iostream>

fig20_04.cpp
(1 of 2)

using std::cout;
using std::endl;
using std::cin;
#include <cstdlib>
void print();
int main()
{
atexit( print );

//

Register print to be called


when the program terminates.
print must return void and
take no arguments.
register function print

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

2003 Prentice Hall, Inc.


All rights reserved.

2
2

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

Outline

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

// end if

Call function exit, passing a


symbolic constant.

fig20_04.cpp
(2 of 2)

cout << "\nTerminating program by reaching the end of main"


<< endl;
return 0;
}

// end main

// 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.

2
3

Outline

Enter 1 to terminate program with function exit


Enter 2 to terminate program normally
2

fig20_04.cpp
output (1 of 1)

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

2003 Prentice Hall, Inc.


All rights reserved.

2
4

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.

25

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.

26

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.

27

20.9 Signal Handling


Signal

Explanation

SIGABRT

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.

SIGFPE

SIGILL
SIGINT

SIGSEGV
SIGTERM

2003 Prentice Hall, Inc. All rights reserved.

28

20.9 Signal Handling


Function raise

Takes signal number


Creates signal

2003 Prentice Hall, Inc. All rights reserved.

29

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

Outline

// Fig. 20.6: fig20_06.cpp


// Using signal handling
#include <iostream>

fig20_06.cpp
(1 of 3)

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 ) );

Register signalHandler to deal


with SIGINT events.

2003 Prentice Hall, Inc.


All rights reserved.

3
0

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;

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

// raise SIGINT when x is 25


if ( x == 25 )
raise( SIGINT );
cout << setw( 4 ) << i;
// 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.

3
1

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

Outline

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

fig20_06.cpp
(3 of 3)

int response;
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.

3
2

Outline

10

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

20
30
40
50
60
70
80
90

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.

3
3

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.

34

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.

35

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.

36

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

Outline

// Fig. 20.7: fig20_07.cpp


// Using goto.
#include <iostream>

fig20_07.cpp
(1 of 2)

using std::cout;
using std::endl;
#include <iomanip>
using std::left;
using std::setw;
int main()
{
int count = 1;
start:

Notice declaration of label


start

// label

// goto end when count exceeds 10


if ( count > 10 )
goto end;
cout << setw( 2 ) << left << count;
Note the
++count;

format of the goto


statement.

// goto start on line 17


goto start;

2003 Prentice Hall, Inc.


All rights reserved.

3
7

28
29
30
31
32
33
34
35
1

end:

Outline

// label

cout << endl;

fig20_07.cpp
(2 of 2)

return 0;
}
2

fig20_07.cpp
output (1 of 1)

// end main
3

10

2003 Prentice Hall, Inc.


All rights reserved.

3
8

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.

39

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.

40

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.

41

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

Outline

// 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;
};

fig20_08.cpp
(1 of 2)

Create a named union with


two data members. They share
the same memory.

// end union Number

int main()
{
Number value;

// union variable

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

// assign 100 to member integer1

"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.

4
2

26
27
28
29
30
31
32
33
34
35

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

Outline

// assign 100.0 to member double1

"Put a value in the floating member\n"


"and print both members.\nint:
"
value.integer1 << "\ndouble: " << value.double1
endl;

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

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.

4
3

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

Outline

// Fig. 20.9: fig20_09.cpp


// Using an anonymous union.
#include <iostream>

fig20_09.cpp
(1 of 2)

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

// declare local variables


int integer2 = 1;
double double2 = 3.3;
char *char2Ptr = "Anonymous";

2003 Prentice Hall, Inc.


All rights reserved.

4
4

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

Outline

// 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;

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

cout << char2Ptr << ' ';


charPtr = "union";
cout << charPtr << endl;
return 0;
}

// end main

1 2
3.3 4.4
Anonymous union

2003 Prentice Hall, Inc.


All rights reserved.

4
5

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.

46

You might also like