Document
Document
Contents 7 Statements 40
7.1 Simple Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
1 Who am I? Who are You? 3 7.2 Compound Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
7.3 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2 Overview 4 7.4 Looping Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.1 Quick Tour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 7.5 while Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.2 Standard Input, Standard Output . . . . . . . . . . . . . . . . . . . . . . . 5 7.6 do statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.3 Redirecting Output and Input . . . . . . . . . . . . . . . . . . . . . . . . . 6 7.7 Avoid Confusing == with = . . . . . . . . . . . . . . . . . . . . . . . . . . 44
7.8 Using a constant or single variable as a test condition . . . . . . . . . . . . 46
3 C++ and iostreamlibrary 7 7.9 while and the null statement . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.1 An overview of the iostream library . . . . . . . . . . . . . . . . . . . . 7 7.10 for Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
7.11 Comparing while and for . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4 Continuing our tour 9
7.12 if and switch Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.1 hello.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
7.13 break, continue, goto . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.2 Basic Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
7.14 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.3 Input characters without skipping whitespace . . . . . . . . . . . . . . . . 10
4.4 I/O of other data to standard output and from standard input . . . . . . . . . 11 8 Functions 52
4.5 Reading into strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 8.1 Defining Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.6 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 8.2 Calling Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.7 Reading till the end of file . . . . . . . . . . . . . . . . . . . . . . . . . . 13 8.3 Using return Value from Functions . . . . . . . . . . . . . . . . . . . . . 54
4.8 Infinite Loop while reading . . . . . . . . . . . . . . . . . . . . . . . . . . 14 8.4 Function Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5 Data Types 14
5.1 Integer Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5.2 Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1. Who am I? Who are You? 3 2. Overview 4
12 Multidimensional Arrays and arrays of pointers 68 How we will work in these classes
12.1 Arrays of pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 • We will learn by doing
12.2 Memory Allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.3 Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 – I will explain something for a short time
12.4 Command Line Arguments: argc, argv . . . . . . . . . . . . . . . . . . . 72 – you will then try it out for a short time
• My name is Nick Urbanik • Most of the Linux and UNIX operating systems are written in C.
2.2 Standard Input, Standard Output 5 2.3 Redirecting Output and Input 6
C is portable
#include <iostream>
Why is this better than printf() and scanf()?
• If you are using a very old C++ compiler, put this instead: • std::cin, std::cout and std::cerr “know” the type of data they are working with, so
• there is no need for you to remember which format string is needed for which data
#include <iostream.h> type;
• The library defines three standard stream objects: • “it all just works”
4.3 Input characters without skipping 10
4. Continuing our tour 9 whitespace
4.1 hello.cpp • Variables are declared and defined with a data type and a name.
• Program hello.cpp: • First character of a variable must be letter or underscore (_). Special characters (e.g.,
$ and #) are illegal.
// A first program in C++
#include <iostream> • Some people (including me!) recommend using lowercase letters and underscores
int main( void ) only.
{
std::cout << "Hello World\n";
4.3 Input characters without skipping whitespace
}
Input characters without skipping whitespace
• Output for Program hello.cpp:
• We can input and output characters one at a time:
Hello World • Program one-char-io.cpp:
• Aim: make the program as easy for a human to understand as possible • You can use the iostream member function std::cin.get() to input characters one
at a time, including whitespace:
• Saves money: less time to change/update program = less money.
#include <iostream>
int main( void )
4.2 Basic Syntax {
char letter ;
Format of main() function without parameters
std::cin.get( letter );
std::cout << letter ;
int main( void )
}
{
hdeclarationsi;
hstatementsi;
}
4.4 I/O of other data to standard output 11
and from standard input 4.5 Reading into strings 12
4.4 I/O of other data to standard output and from standard input • A string is an array of characters, i.e., text.
Input and output with iostream • The length of the string can be defined with a number enclosed in brackets. e.g., array
• Simple input and output operations using iostream library objects std::cout and of 10 characters with name lname:
std::cin
char lname[ 10 ];
• Program celcius.cpp:
#include <iostream>
int main( void )
{
double fahr = 212, cel;
cel = ( 5.0 / 9.0 ) * ( fahr − 32 );
std::cout << fahr << " deg F => "
<< cel << " deg C\n";
}
4.6 Loops 13 4.8 Infinite Loop while reading 14
• Data is represented in memory by a sequence of bits, arranged into bytes, eight bits to Integer and floating point data types
a byte
• Types of integer data (each has an unsigned counterpart):
• These bits could represent
– character
– strings or characters
– integer
– integers
– short integer
– floating point values
– long integer
– memory addresses
– long long integer
– binary values representing music or video
• Types of floating point values:
– ...
– single precision (float)
• Each item of data has a data type
– double precision (double)
• The data type determines how the program will interpret the data
– long double precision (long double)
Declaration & data types • The range of values that can be held are machine dependent.
• A variable declaration consists of a data type and an identifier, followed by a semi- • The ranges of integer types are in limits.h
colon:
• The ranges of floating types are in float.h
hData Typei hVariable Namei hsemicoloni
5.1 Integer Types
• Example: Signed integers — 1
int count; • An unsigned integer has only positive values while a signed integer can have a positive
or negative value.
• Signed Integers:
Basic data types Keywords
character char
signed character signed char int use: standard integer
unsigned character unsigned char
integer int size: system dependent, usually size of a word.
unsigned integer int range: INT_MIN to INT_MAX, defined in limits.h. For 4
long integer long byte word, −231 − 1 to 231 , i.e., −2147483648 to
unsigned long integer unsigned long 2147483647
long long integer long long example declaration: int num;
unsigned long long integer unsigned long long
short integer short example constant: 1000
floating point float or double or long double
5.1 Integer Types 17 5.2 Characters 18
Signed integers — 2
unsigned int
long use: large numbers
size: system dependent; always same size as int
size: usually 4 bytes. range: 0 to UINT_MAX. For 4 byte word, 0 to 232 − 1, i.e., 4294967295
31 31
range: LONG_MIN to LONG_MAX. For 4 bytes, −2 to 2 − 1, i.e., declaration: unsigned int unum; or unsigned unum;
−2147483648 to 2147483647
constants: 5530u
example declaration: long lnum;
example constant: 5212000L
Unsigned integers — 2
short use: smaller numbers
unsigned long
size: 2 bytes or same size as integer
size: usually 4 bytes; always same size as long
range: SHRT_MIN to SHRT_MAX. For 2 bytes, −215 to 215 − 1, i.e., −32768 range: 0 to UINT_MAX. For 4 byte, 0 to 232 − 1 = 4294967295
to 32767
example declaration: unsigned long ulnum;
declaration: short snum;
example constant: 76212000uL
constants: 120
unsigned short
long long size: usually 2 bytes; always same size as short int
range: 0 to USHRT_MAX. For 2 bytes, 0 to 65536
long long use: very large numbers example declaration: unsigned short usnum;
size: usually 8 bytes. example constant: 34000u
range: for 8 bytes, −263 to 263 − 1, i.e., −9,223,372,036,854,775,808
to 9,223,372,036,854,775,807
5.2 Characters
example declaration: long long lnum;
Characters
example constant: 5212000LL
• When working with characters, use the type char.
unsigned long long use: very large positive numbers • Note that the type char can be signed or unsigned, depending on the compiler.
example declaration: unsigned long long lnum; size: usually 8 bits; CHAR_BIT in limits.h
example constant: 5212000LL range: CHAR_MIN to CHAR_MAX. For 1 byte, could be −27 to
27 − 1, i.e., −127 to 128 or 0 to 255
example declaration: char ch;
Unsigned integers — 1
example constant: ’a’
5.3 Octal, Hexadecimal Output with 20
5.2 Characters 19 ostream
#include <iostream>
Characters: signed, unsigned
int main( void )
• specify the type as signed or unsigned only if you care. {
char letter = ’A’; // ’A’ is character constant
int num = letter ;
signed char char ch1 = ’b’; // ASCII code = 98
char ch2 = ’B’; // ASCII code = 66
size: usually 8 bits; CHAR_BIT in limits.h
std::cout << "letter = " << letter
range: SCHAR_MIN to SCHAR_MAX. For 1 byte, −27 to 27 − 1,
<< ", num = " << num << ’\n’;
i.e., −127 to 128
std::cout << "letter + 1 = " << letter + 1
example declaration: signed char ch; << ", num = " << num << ’\n’;
std::cout << ch1 << " - " << ch2
example constant: ’a’
<< " = " << ch1 − ch2 << std::endl;
}
unsigned char
Output for Program princhar.cpp:
size: usually 8 bits; CHAR_BIT in limits.h
letter = A, num = 65
range: 0 to UCHAR_MAX. For 1 byte, 0 to 28 − 1 = 255
letter + 1 = 66, num = 65
example declaration: unsigned char ch; b - B = 32
• The long integer qualifier L can also used with the octal and hexadecimal
• Example of octal constant: 0553000L
• Example of hexadecimal constant: 0x2f6c7a333L
5.3 Octal, Hexadecimal Output with 21
ostream 5.4 Floating Point Types 22
Program printvar.cpp std::dec Changes the state of the ostream to displaying all integer type numbers
in decimal
#include <iostream> std::showbase a state that displays octal with leading “0”, hexadecimal with
#include <iomanip> leading “0x”
Output for Program printvar.cpp example constants: floating point notation: 3.4567 exponential notation: 4.788e+5,
3e1
num (dec) = 77, (oct) = 0115, (hex) = 0x4d
small (oct) = 0173, little (hex) = 0x7b
big (dec) = 88000, large (dec) = -43000 Floating point data types — long double
unum = 45000, ubig = 330000000
small (dec) = 123, little (dec) = 123 long double
• We need to include iomanip here for the manipulators: size: bigger than the size of double.
std::oct Changes the state of the ostream to displaying all integer type numbers range: LDBL MIN to LDBL MAX defined in float.h
in octal. All numbers printed while in this state are in octal. example declaration: long double ldnum;
std::hex Changes the state of the ostream to displaying all integer type numbers example constants: 3.4567L exponential notation: 4.788e+5L
in hexadecimal
5.4 Floating Point Types 23 5.5 Named Constants 24
Program float-io.cpp
operands
Enumerated types — 2
6.1 Arithmetic Expressions
• Program enum-3.cpp:
Arithmetic operators — unary
#include <iostream>
• Unary arithmetic operators:
enum weather { clouds = 30, rain = 5,
sunny = 255, storm = 1 }; + plus, or positive
enum boolean { TRUE = 1, FALSE = 0 };
− negative
int main( void )
{
−6 negative 6
weather today = rain;
std::cout << clouds << ’ ’ << rain << ’ ’ −( −6 ) positive 6
<< sunny << ’ ’ << storm << ’\n’; −( 3 − 7 ) positive 4
std::cout << "today: " << today << ’\n’;
} −y change the sign of operand y
6.2 Arithmetic Operators and 27
Precedence 6.3 All Operators and their Precedence 28
• Additive operators: 2 + 4 * 5 − 3
• One operator may take precedence over another. • The following table lists the precedence and assciativity of operators.
6 * 2 • Relational, equality, and logical expressions compare their operands. the result of the
comparison is the integer value of either one or zero.
• If there are no parentheses, precedence determines the order of evaluation
• If an operation compares successfully, the result of the expression is an integer value
• All operators are ranked according to their precedence. of 1. If an operation compares fails, the result of the expression is an integer value of
0.
• Operators with greater precedence are evaluated first.
6.4 Relational Expressions 29 6.5 Logical Expressions 30
expr !(expr)
Arithmetic assignment operators
T non-zero F 0
F 0 T 1 • provide a shorthand applying an arithmetic operation to a variable
– j += 3; is equivalent to j = j + 3;
Program countdig.cpp
– j *= 3; is equivalent to j = j * 3;
/* Counts only the numeric characters ’0’ - ’9’ • List of arithmetic assignment operators:
read from standard input */
+= add and then assign
#include <iostream> −= subtract and then assign
int main( void )
{ *= multiply and then assign
int n = 0; /= divide and then assign
char c;
%= modulo; assign remainder
while ( std::cin >> c ) {
if ( c >= ’0’ && c <= ’9’ ) 6.7 Increment, Decrement Operators
n = n + 1;
} Increment and decrement assignment operators
std::cout << "Count of digits = " << n << ’\n’;
} • an assignment operation in which 1 is added/subtracted to a variable and the result
assigned to that variable.
6.8 Comma Operator 33 6.9 Arithmetic if Expressions 34
• The increment or decrement operator can operate in two ways: Prefix places the in- • Example:
crement or decrement operator before its operand. Postfix places the increment or
decrement operator after its operand. r = ( 3 * 5, 8.00 + 2.5, num = 5 );
• Example: • The result is the value of the last expression in its list i.e.,
x = 32;
y = ++x; r = num = 5
imply x = 32 + 1 = 33 and y = x = 33 • The main use of comma is in the headers of for loops:
• But for ( i = 0, j = n; i < n; ++i, −−j )
x = 32;
y = x++; 6.9 Arithmetic if Expressions
imply y = x = 32 and x = 32 + 1 = 33 Arithmetic if Expressions
if ( a > b )
6.8 Comma Operator max = a;
Comma operator expressions else
max = b;
• The comma operator expression is an expression that consists of a list of other expres-
sions.
• The comma does not perform any operation on these expressions.
– they are simply evaluated sequentially as if they were a series of statements.
6.10 Bitwise Operators 35 6.10 Bitwise Operators 36
6.10 Bitwise Operators • The bitwise exclusive OR operator, ^, results in 1 if the corresponding two bits are
different:
Bitwise operators — 1
• The bitwise operations allow the programmer to manipulate specific bits.
bit m bit m m ^ n
• The bitwise operations can be combined with masks to turn specific bits on and off.
0 0 0
• The bitwise AND operation, &, is used to clear specific bits in an integer operand,
leaving the other bits unchanged. 0 1 1
1 0 1
• The bitwise OR operation, |, is used to set specific bits in an integer operand, leaving
the other bits unchanged 1 1 0
• Here is the truth table for the bitwise AND operation: • There are two shift operators:
bit m ∼m
0 1
1 0
6.10 Bitwise Operators 37 6.11 Casts 38
#include <iostream> ∗ so the signed value 0xfffffff0 (−16) shifted right two places is 0xfffffffc
#include <iomanip>
• Notice that when shifted right: • The operand may be any expression
• If a floating point value is cast to an integer, the floating point fraction is lost. 7 Statements
– Example: Statements: an introduction
( int ) 3.75
• A C program is a sequence of declarations and statements.
– resulting value is 3
• We have seen:
• Casts overide the compiler’s concept of correctness — use rarely
– how to declare variables, and
Conversions – how to create expressions using operators
– examples of putting this all together.
• Expressions can include operands of different number types
• Now let’s look at statements.
• Example: An integer can be multiplied by a float.
• C handled operands of different types by converting one of them into the same type as Statements: intro — 2
that of the other operand.
• We can turn an expression such as x = 0 or std::cout << "a" into a statement simply
• Conversion determines which operand to convert by a process of promotion and de- by putting a semicolon at the end:
motion.
x = 0;
std::cout << "a";
Conversions: promotion
• In expressions with two different types of operands, the operand with the smaller type • We can join these into a compound statement by putting braces { } around them.
is always promoted to that of the largest type. • There are some which are used to create loops and make decisions. These are some-
• Example: times called control-flow statements.
int num = 6;
float cost; 7.1 Simple Statements
cost = num * 5; Expression statements
• The expression num * 5 results in the integer 30 and will be promoted to a float, • An expression statement consists of any valid expression, followed by a semicolon.
30.0 before assigned into the cost variable.
• Often the expression is an assignment operation or a function call.
Conversions: demotion • Example:
• Demotion from a floating point type to an integer type results in the loss of the floating count = 8;
point’s fraction. num = 3 + 4;
calc();
• Example:
int num; • However, the expression could just as easily be an arithmetic expression or relational
float cost = 62.65; expression.
num = cost;
• Example:
• The fraction will be cut off, leaving just the integer, 62. The value 62 is then assigned 4 + 5; // nothing done with the result, 9.
to the variable num. ( n < 3 );
7.2 Compound Statements 41 7.3 Scope 42
• If there is no expression in the expression statement, nothing happens. This is called #include <iostream>
as the null statement. int main( void )
{
• Example: int num = 10;
float cost = 100.0;
; // just a semicolon {
float cost = 50.0;
num = 5;
7.2 Compound Statements std::cout << "Inside: " << cost
<< ", " << num << ’\n’;
Compound Statements
}
std::cout << "Outside: " << cost
• A compound statement is a statement composed of one or more statements.
<< ", " << num << ’\n’;
• A compound statement consists of opening and closing braces within which statements }
are placed.
• Output of program blocks.cpp:
• Example:
Inside: 50, 5
{ Outside: 100, 5
num = 6;
fact = ( 5 − 3 );
std::cout << fact << ", " << num << ’\n’;
7.3 Scope
} Scope
• Variables can be declared at the beginning of compound statement. A compound • the compiler searches for an identifier defined in the innermost scope first
statement with variable declarations is referred to as a block. • then searches the scopes that the enclose current scope. . .
• The body of a function is a compound statement itself, and is often referred to as the • . . . until it reaches global scope
function block.
– global scope is outside of any block
Program blocks.cpp
• identifiers defined in an inner scope “hide” identifiers defined in an outer scope
• For example, in program blocks.cpp, there are two variables called cost in differ-
ent nested scopes
– The inner output statement prints the value of the cost variable defined in the
inner scope
– The outer output statement prints the cost defined in the outer scope.
7.4 Looping Statements 43 7.6 do statement 44
• Loops are implemented with three iteration statements: • The do statement is a variation on the while statement.
– while • Instead of the test occurring at the beginning of the loop, it occurs at the end,
– do • Example:
– for
i = 0;
• Each statement repeats a statement called the body of the loop do {
std::cout << "abc\n";
• The body of the loop can be any statement, including: ++i; // loop counter
} while ( i < 4 );
– compound statement, or
– another loop, or Program square-1.cpp
– a null statement.
#include <iostream>
7.5 while Statement
int main( void )
while statement {
int num;
• while loop consists of the keyword while, a test expression in parentheses, and a std::cout << "Enter a number: ";
statement. std::cin >> num;
• statement is repeated for as long as the test expression evaluates to a non-zero value. while ( num != 0 ) {
int square = num * num;
while ( htest expressioni ) std::cout << "Square of " << num
hstatementi; << " = " << square << ’\n’;
std::cout << "Enter a number (0 to quit): ";
• Example: std::cin >> num;
}
i = 0; // initialize the loop counter }
while ( i < 5 ) {
std::cout << "ABC "; • This program has a major problem.
++i; // update the loop counter
// very important • What happens if we input a character that is not part of an integer?
} // the loop becomes infinite
// without this statement that
// changes the loop counter
7.7 Avoid Confusing == with =
Test Expression
• The test expression for the while, for, and if statements can be any valid expression,
• Example:
7.8 Using a constant or single variable 46
7.7 Avoid Confusing == with = 45 as a test condition
– assignment operation
– simple primary expression consisting of a variable or a constant #include <iostream>
• A zero result evaluated is considered to be false while any non-zero result is true. /* This program shows problems that come from
confusing assignment with comparison */
Traps with = and ==
int main( void )
• Don’t confuse comparison with assignment in a test expression. {
int quit = 0, num = 1, square;
while ( i = k ) { ... } while ( quit = 0 ) // Oh dear; always false
{
• If k equals 0, the test will always be false // the loop body will never be executed
square = num * num;
• If k is not equal to zero, the test will always be true. std::cout << "Square of " << num
<< " = " << square << ’\n’;
• Examples of incorrect test expressions:
if ( num = 10 ) // Oh dear; always true
while ( n = 0 ) { /* always false */ ... } quit = 1;
num++;
while ( n = 3 ) { /* always true, an infinite loop */ ... }
}
}
• The correct way to write these test expressions is:
while ( n == 0 ) {
...
7.8 Using a constant or single variable as a test condition
}
Using a constant or single variable as a test condition
while ( n == 3 ) {
... • Constants are often used to write infinite loops.
}
• Variables are used as a shorthand for comparing the value of the variable to zero.
Program square-2.cpp
7.9 while and the null statement 47 7.10 for Statement 48
int main( void ) • The for statement consists of three expressions followed by a statement.
{
for ( hexpression 1i; hexpression 2i; hexpression 3i )
int num;
while ( 1 ) { // or for (;;) hstatementi;
std::cout << "Please enter a number: ";
• hexpression 1i is executed once, before loop begins. It is often used to initialize vari-
if ( ! ( std::cin >> num ) )
break;
ables used in the test expression.
int square = num * num; • hexpression 2i is the test expression for the loop. When it evaluates as false, the loop
std::cout << "Square of " << num stops.
<< " = " << square << ’\n’;
char ch; • hexpression 3i update expression. It is executed within the loop and is usually used to
std::cout << "Another square? (y/n) "; update variables used in the test expression.
if ( std::cin >> ch && ch != ’y’ )
break;
Example of for loop
}
}
for ( int i = 1; i < 3; ++i ) {
std::cout << "OK\n";
}
• The jump statements are non-structured control statements that allow the program to
if and else jump across statements.
• The if statement can choose between several choices using else:
• Strickly speaking, these are not allowed in structured programming.
if ( hconditioni ) {
• However, break and continue are especially useful.
doThis();
} else if ( hcondition 2i ) { • break and continue statements are used with while, for, and switch statements.
doThat();
} else { • break provides an exit condition other than that of the statement’s test expression.
doTheOther();
}
7.14 Exercises 51 8. Functions 52
Example of use of continue 2. Save your source to a different file name, but replace all the ifs (except the first) to
else ifs.
• Kernighan and Ritchie provide this example of using continue:
3. Run your two programs and compare the output.
for ( i = 0; i < n; ++n ) {
if ( a[ i ] < 0 ) // skip negative elements 4. Write a program contianing a while loop and a for loop that both output data and do
continue; the same thing.
// do positive elements
}
8 Functions
• See also my example program cat.cpp Functions — 1
goto: use it seldom • A big program may be too complex to hold in your head.
• goto and label statements allow the program to jump to any statement. • I need a way to break a big problem into many small, easy-to-understand problems.
• Using goto can cause the program to become very hard to understand • One way to break a problem into small problems is to divide a problem into small
parts that can be written as functions.
• Use it only when you really have to
• A function is a number of statements that:
– An example is to break out of a nested loop from the inner loop
– Perform one easily-understood job
for ( i = small; i < big; ++i ) – are given a single name.
for ( j = small2; j < bigger ; ++j )
if ( i == j ) • A function is a little bit like a simple IC, with input pins and output pins.
goto equal;
equal:
Functions — 2
• equal here is a label
• A function may have inputs and outputs:
7.14 Exercises
1. Write a program using the following code fragment as a guide:
x sin() y
int i = 10;
if ( i > 0 )
std::cout << "i > 0\n";
if ( i > 1 )
std::cout << "i > 1\n"; • The function call:
if ( i > 2 )
std::cout << "i > 2\n"; y = sin( x );
// . . .
if ( i > 10 ) can be represented by the block diagram above.
std::cout << "i > 10\n";
• The inputs go in the parentheses: ()
else
std::cout << "something else\n"; • The output of the function can be assigned, as above.
8.3 Using return Value from 54
8.1 Defining Functions 53 Functions
Functions — 3
• To write and use functions in your program, there are two things to consider: // Program to call a function
• When you define the function, you write the statements that the function will perform #include <iostream>
when it is called. // function definition:
void calc( void )
• When you want to use the function, we say we call the function. {
std::cout << "Now in Calc\n";
}
8.1 Defining Functions
Function definition int main( void )
{
• A function definition consists of a header and a body. std::cout << "Hello World\n";
calc();
• header contains the function name, its return type, and parameter types. std::cout << "Now in Main\n";
}
• The body of a function is a block, which usually contains variable declarations and
statements.
hreturn typei hfunction_namei( hparameter listi ) 8.3 Using return Value from Functions
{
hvariable definitionsi; Functions as expressions
.
.
. • A function call is an expression whose value is the function’s return value.
hstatementsi;
} • Program calc-2.cpp
#include <iostream>
• Example:
float calc( void )
void calc( void ) {
{ return 8.0 * 5.35;
int num; }
num = 5;
} int main( void )
{
float res1 = calc();
8.2 Calling Functions float res2 = 7 + 5 * calc();
if ( calc() > 5 )
Function definition and call Program nowincal.cpp std::cout << "Larger\n";
std::cout << "res1 = " << res1
<< ", res2 = " << res2 << ’\n’;
}
8.3 Using return Value from 55 8.3 Using return Value from 56
Functions Functions
• The return statement consists of the keyword return, an expression, and a semicolon.
#include <iostream>
• Syntax: return hexpressioni; short getnum( void )
{
• The hexpressioni is called the return expression. long num = 2147483647L;
std::cout << "Number is " << num << ’\n’;
• return statement will: return num;
}
– end the processing of a function
– make execution continue from where the function was called, and int main( void )
– specify the function’s return value. {
long res = getnum(); // return value inconsistency
std::cout << "result is " << res << ’\n’;
Function return value: example Program calc-3.cpp }
• In this example the parameters match • An array is a collection of objects, all of the same data type.
• The declaration below declares an array of 5 integers. The array name is mynums • Once an array has been declared, its objects can be referenced and used in expressions.
int mynums[ 5 ]; • The array name, together with the position of an object in the array is used to reference
an object.
• Many different kinds of arrays may be declared, each having its own data type and • The objects in an array are arranged in sequence, starting from zero. The number of an
number objects. object’s place in that sequence is referred to as either the object’s index or subscript.
int total[10]; an array of ten integers (i.e. total[0], total[1], . . . • In the example above, we can see
total[9])
char name[40]; an array of forty characters (i.e. name[0], mynums[ 0 ] = 3; // first object
name[1], . . . name[39]) mynums[ 1 ] = 4; // second object
mynums[ 2 ] = 5; // third object
mynums[ 3 ] = 6; // fourth object
Array initialisation mynums[ 4 ] = 7; // fifth object
• Example: this for loop prints each number in the array: • Note that the string definitions str and letters are equivalent.
int nums[ 4 ] = { 42, 1000, 7, 103 }; • Note that a string is automatically ended with a special character called the null char-
for ( int i = 0; i < 4; ++i ) acter, ’\0’
std::cout << "this num is " << nums[ i ] << ’\n’;
Arrays of characters: strings — 2
Using constants for array size
• Because the string has the extra ’\0’ character at the end, the array of characters
• In the listing below, the same symbolic constant, max, is used in both the array decla-
must be long enough to hold it.
ration and the test for the last array object in the for statement.
#include <iostream> • Example:
const int max = 4;
int main( void ) char string2[ ] = "string";
{
int mynums[ max ] = { 23, 8, 11, 31 }; • . . . has seven characters, so this would be wrong:
for ( int i = 0; i < max; ++i )
std::cout << mynums[ i ] << ’ ’; char string3[ 6 ] = "string"; // too short!
std::cout << ’\n’;
}
• but these are okay:
Working with strings • There are 3 elements involved in this referencing process:
• The standard C++ strings library is the best choice for simplicity, but the Borland – a pointer variable
3.1 compiler does not seem to support it – an address
• The standard library that comes with (nearly) every C compiler provides lots of func- – and another variable
tions for working with strings.
Pointer holds address
• To use them, put:
• A pointer variable holds the address of another variable of a particular type
#include <string.h>
• Program pointer-1.cpp
• at the top of your program.
• Here are some: #include <iostream>
int main( void )
• strlen() — give the length of a string {
int num = 12;
• strcpy () — copy one string to another string int *nptr ;
• strcmp() — compare two strings nptr = #
std::cout << "num holds " << num
• strcat() — join one string onto the end of another << " and nptr points to " << *nptr << ’\n’;
std::cout << "The address held in nptr is " << nptr
<< ’\n’;
Working with strings 2 }
• Example using strlen():
• Output of program pointer-1.cpp:
int len;
len = strlen( "a string" ); // len = 8 num holds 12 and nptr points to 12
The address held in nptr is 0xbfafade8
• Example using strcpy ():
10.1 Pointers as Function Parameters
char str1[ 100 ], str2[ ] = "a string";
strcpy ( str1, str2 ); Pointers as Function Parameters
• The right way is to pass the address of a and b like this: swap( &a, &b ); and define C Arrays and pointers
the function like this:
• The name of an array is the same as the location of the first element, so these two
void swap( int *x, int *y ) statements are equivalent:
{
int temp = *x; pa = &a[ 0 ];
*x = *y ; pa = a;
*y = temp;
} • These statements are also true:
a[ i ] == *( a + i );
• This is how to change the value of a parameter. &a[ i ] == a + i;
• An expression made of an array and index has an equivalent expression made with a
11 Arrays and Pointers pointer and offset.
11.1 Strong relationship between arrays and pointers • Important: we can do
C Arrays are very low level ++pa; // okay; now pa points to a[ 1 ]
Program array-parameter.cpp • If the length of the array passed to mean() is 100, then that number must be passed as
#include <iostream> a separate parameter.
int ar [ 10 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
void check array parameter ( int a[ ] ) 12 Multidimensional Arrays and arrays of pointers
{
std::cout << "sizeof( a ) = " << sizeof( a ) << ’\n’; 12.1 Arrays of pointers
std::cout << "sizeof( ar ) = " << sizeof( ar ) << ’\n’;
} Arrays of pointers
int main( void ) • Arrays of pointers are very commonly used in C, because this gives much greater
{ flexibility than alternatives (see slide §71)
check array parameter ( ar );
int nelements = sizeof( ar ) / sizeof ar [ 0 ]; • Can easily sort an array of pointers; copy only the address, not the data
std::cout << "sizeof( ar ) = " << sizeof( ar ) << ’\n’
• Can define an array of pointers to lines like this:
<< "number of elements in ar[ ] is " << nelements
<< ’\n’; const int maxlines 10000;
} char *line[ maxlines ];
• Output of array-parameter.cpp
• We must make sure that we allocate memory using the new operator for this as we
sizeof( a ) = 4 read lines.
sizeof( ar ) = 40
sizeof( ar ) = 40 12.2 Memory Allocation
number of elements in ar[] is 10
Allocating memory with new
Passing arrays to functions — 3
• If we don’t know how much data we will read, we need to allocate memory as we
• To work properly, you need to pass the length of an array as a separate parameter need it
together with the array.
– The new operator allocates memory as it is needed
• Example: – deallocate (free) memory with the delete operator
double mean( int nums[ ], int len ) • If allocating a scalar value, use syntax like this:
{
int sum = 0;
for ( int i = 0; i < len; ++i ) {
hpointeri = new htypei;
sum += nums[ i ];
} and free the memory like this:
if ( len == 0 ) return 0;
return ( double ) sum / len; delete hpointeri;
}
• if allocating an array or string, use syntax like this:
• Note that it makes no difference to write the parameter as int nums[ 100 ], since that
length information will not be passed to the function as part of the int nums[ 100 ] hpointeri = new htypei[ hlengthi ];
parameter
12.2 Memory Allocation 69 12.2 Memory Allocation 70
• the result from new is a null pointer if the memory cannot be allocated. // Read all of input into memory. Normally we would process one line
// at a time, as we read it.
– Always check the return value of new
// Read each line into a string
Example use of new: Program new-1.cpp // allocate memory for the string and copy the string into that memory
// add the newly allocated string to an array of pointers
• Program new-1.cpp does the following:
int read lines( char *lines[ ], int maxnlines )
– dynamically allocate an array of ten integers {
– terminate if allocation doesn’t succeed const int maxlinelen = 8000;
char line[ maxlinelen ];
– put a value into each element of the array int nlines = 0;
– print each value while ( std::cin.getline( line, maxlinelen ) ) {
int len = std::cin.gcount(); // includes space for ’\0’
– free up the memory
char *p;
if ( nlines >= maxnlines
#include <iostream>
| | ( p = new char[ len ] ) == NULL ) {
#include <stdlib.h>
return −1;
} else {
int main( void )
strcpy ( p, line );
{
lines[ nlines++ ] = p;
const int maxn = 10;
}
int *a = new int[ maxn ];
}
if ( a == NULL ) {
return nlines;
std::cerr << "Out of memory!\n";
}
exit( 1 );
}
for ( int i = 0; i < maxn; ++i )
a[ i ] = i + 1;
for ( int i = 0; i < maxn; ++i ) Program new.cpp— 2
std::cout << "a[ " << i << " ] = "
<< a[ i ] << ’\n’;
delete [ ] a;
}
Program new.cpp— 1
12.4 Command Line Arguments: argc, 72
12.3 Multidimensional Arrays 71 argv
• Note that this is wrong, and just uses the comma operator:
void write lines( char *lines[ ], int nlines ) int entry = matrix[ 1, 2 ]; // WRONG!!!
{ %
while ( nlines−− > 0 )
std::cout << *lines++ << ’\n’;
} 12.4 Command Line Arguments: argc, argv
void free lines( char *lines[ ], int nlines ) argc and argv
{
while ( nlines−− > 0 ) • The main() function takes two optional parameters that are always called argc and
delete [ ] *lines++; argv :
}
int main( int argc, char *argv [ ] )
int main( void )
{ • parameter argc is the number of arguments on the command line including the pro-
const int maxlines = 10000; gram name
char *line[ maxlines ];
• parameter argv is a pointer to an array of command line arguments
int nlines = read lines( line, maxlines );
if ( nlines >= 0 ) { • if the program echo is called like this:
write lines( line, nlines );
free lines( line, nlines ); echo this is a test
} else {
std::cerr << "Input is too big to read\n"; • then argc is 5, argv [ 0 ] is "echo", argv [ 1 ] is "this", argv [ 2 ] is "is",
} argv [ 3 ] is "a", argv [ 4 ] is "test" and finally argv [ 5 ] is the null pointer.
}
Program echo.cpp
• A structure consists of a set of data objects that can be referenced as one object. • After this, person will contain the same values as in the next slide.
• We can define a variable person of the type struct employee like this:
13.1 Passing Structures to Functions
struct employee {
int id; Accessing a structure through a pointer
float salary ;
}; • Given a pointer to a struct declared as:
// somewhere else:
struct employee person; struct employee {
int id;
float salary ;
• We can now refer to the two values in the variable person as person.id and person.salary };
struct employee person;
Initialising struct variables struct employee *p = &person;
• We can initialise a structure when it is defined by putting a list of values in braces, as • we could access the members with the arrow operator ‘−>’ like this:
we do for arrays
p−>id = 8;
• The first item in that list initialises the first element of the structure,
p−>salary = 80000;
• the second item initialises the second element of the structure, std::cout << "ID = " << p−>id << ’\n’;
std::cout << "Salary = $" << p−>salary << ’\n’;
• ...
13.1 Passing Structures to Functions 75 13.2 typedef 76
• There is nothing magic about the “−>” operator; it is just a shorthand used, because
we often access members of structures through pointers
#include <iostream>
• Note that “p−>id” is equivalent to “(*p).id ”, and “p−>salary ” is equivalent to struct complex {
“(*p).salary ”. int re;
int im;
};
Passing Structures to Functions
complex cadd( complex z1, complex z2 )
• Unlike arrays, structures are passed to functions by value {
complex zt;
• That means that your function only gets a copy of the structure.
zt.re = z1.re + z2.re;
• If you want to modify the original structure, you need to either: zt.im = z1.im + z2.im;
return zt;
– return the modified structure, or }
– pass a pointer to the structure. int main( void )
{
Passing Structures: example complex za;
Here we use the struct employee defined previously. Passing structure by value za.re = 1;
za.im = 2;
struct employee raise salary ( struct employee p, float raise ) complex zb = za;
{ complex zc = cadd( za, zb );
p.salary += raise; std::cout << "zc.re = " << zc.re
return p; << ", zc.im = " << zc.im << ’\n’;
} }
// in another function:
struct employee manager = { 50, 100000 }; Output of program complex.cpp:
manager = raise salary ( manager, 20000 );
zc.re = 2, zc.im = 4
Passing a pointer to structure:
13.2 typedef
void raise salary ( struct employee *p, float raise )
{ typedef
p−>salary += raise;
} • A typedef is used to allow the programmer to give another name to a type.
// in another function:
struct employee manager = { 50, 100000 }; • typedef htypei hNAMEi;
raise salary ( &manager, 20000 ); defines hNAMEi as a new name for the existing type htypei
• Example:
• Often typedef is used with struct variables to avoid needing to type the word “struct”
14. Reading and Writing Files 77 14.3 Binary files 78
• To open a file for binary input or output, use the extra parameter std::ios::binary
when defining the ofstream or ifstream object:
14.5 Reading a Line at a time: 80
14.4 Character I/O 79 getline()
• Program copy-file-to-output.cpp:
#include <iostream>
#include <fstream> #include <iostream>
// . . . #include <fstream>
std::ofstream fout( "data.out", std::ios::app | std::ios::binary ); #include <stdlib.h>
if ( ! fout ) { int main( void )
std::cerr << "error: unable to open binary file " {
<< "’data.out’ for appending\n"; char ch;
exit( 1 ); std::ifstream fin( "abc.txt" );
} if ( ! fin ) {
std::cerr << "Cannot open file abc.txt\n";
• Here we open a binary file for input: exit( 1 );
}
#include <iostream> // skips whitespace.
#include <fstream> // while ( fin >> ch )
// . . . // std::cout << ch;
std::ifstream fin( "data.in", std::ios::in | std::ios::binary ); while ( fin.get( ch ) )
if ( ! fin ) { std::cout.put( ch );
std::cerr << "error: unable to open binary file " }
<< "’data.in’ for reading\n";
exit( 1 ); Character I/O with Text Files — 2
}
• Program copyfile.cpp
Binary files — 2 #include <iostream>
#include <fstream>
• Here we open a binary file for output: #include <stdlib.h>
int main( void )
{
#include <iostream> char ch;
#include <fstream> std::ifstream fin( "abc.txt" );
// . . . std::ofstream fout( "mmm.txt" );
std::ofstream fout( "data.out", std::ios::out | std::ios::binary ); if ( ! fin | | ! fout ) {
if ( ! fout ) { std::cerr << "Problem opening files\n";
std::cerr << "error: unable to open binary file " exit( 1 );
<< "’data.out’ for writing\n"; }
exit( 1 ); // The following skips white space:
} // while ( fin >> ch )
// fout << ch;
while ( fin.get( ch ) )
14.4 Character I/O fout.put( ch );
}
Character Input and Output
• We can treat a file as a stream of characters. The istream member function get() 14.5 Reading a Line at a time: getline()
and the ostream member function put() read and write one character at a time.
Working with Lines in Text Files
14.6 I/O of other data to/from Text 81
Files 15. Guidelines 82
• We often want to work with one line of a text file at a time Reading other data from Text Files — 2
• the istream member function getline() reads from a file and places it in a string or • We can read formatted text from text files just as we can from standard input with
character array, without the ending newline. std::cin
std::cin.getline( hstring or character arrayi, hmaximum lengthi ); • Program filein.cpp:
• getline() returns false if there is any error. #include <iostream>
#include <fstream>
Program copy-lines-from-file.cpp
: #include <stdlib.h>
int main( void )
#include <iostream> {
#include <fstream> int num;
#include <stdlib.h> std::ifstream fin( "abc.txt" );
if ( ! fin ) {
int main( void ) std::cerr << "Cannot open abc.txt\n";
{ exit( 1 );
const int maxline = 100; }
char line[ maxline ]; fin >> num;
std::ifstream fin( "abc.txt" ); std::cout << "we got ’" << num
if ( ! fin ) { << "’ from abc.txt\n";
std::cerr << "Cannot open file abc.txt\n"; }
exit( 1 );
}
while ( fin.getline( line, maxline ) ) 15 Guidelines
std::cout << line << ’\n’;
} 15.1 Style Guidelines
Program layout: rules of thumb
• We can write formatted text to text files just as we can to standard output with std::cout printf ( "%d", i );
• I suggest you put your main() function last. Program design: top-down
– avoids the need to put “function prototypes” that need unnecessary extra main- • Top-down design looks at the big picture first, forgetting the details.
tainance
• Write pseudocode including only these important, big steps, leaving out small steps at
• Use modern books about C, not very old ones. first. This is like your main() function.
• Indent your program to make it easy to follow. • Write more pseudocode for each of these big steps, giving more detail, but not the
smallest details. These are written rather like function definitions.
• Indent the body of loops and if statements.
• For each step, write out more pseudocode like more function definitions, until you
15.2 Program Design have enough detail to begin writing your source code.
Program design • Check your design carefully before you move on.
• “Real” programs need to be designed; they may be too complicated to hold in your
15.3 Modules
head all at one time.
Making an application from many modules
• Sitting at the keyboard and typing a program as you think it up may work for small
programs, but bigger programs written this way will become very messy and expensive • Most useful C or C++ programs are written in separate modules
to maintain.
• Each module corresponds to:
– The result is rather like a rough sketch to try out ideas.
– one .c, .C, .cc, .cpp, or .cxx file (lets call this the source file), and
– You may want to start again after the experience you get from this “sketch”
– one .h, .H, .hh, or .hpp file (we call this the header file).
• The greatest cost for a program is usually in maintaining it.
• Each header file lists the publicly exported names: type definitions, global variables,
• Flowcharts: and function prototypes
– are okay for simple programs – Avoid defining variables or functions in header files
– are good for representing complicated, unstructured looping and branching
• It makes this set of names as small as possible to reduce the interaction between mod-
– But: a flowchart can easily become more complicated than the program itself! ules
Pseudocode: a basic design tool • All non-public functions defined in the source files are defined with the keyword
static so that they cannot be linked to from other modules.
• Pseudocode is a more practical way to show how your program will work.
Modules — silly example
• Pseudocode is a mixture of: English and structured C programming statements, such
as if, while, do. main.cpp:
• Pseudocode should be simpler and easier to understand than the final program source
code
• Pseudocode should be written before you type in your new program!
15.3 Modules 85 16. Some Things to Read 86
static variables
#include <iostream>
• A variable defined with the keyword static is visible only within its file, and does not
#include "calc.h"
conflict with a variable with the same name defined in another file
#include "main.h"
• the static keyword can (and should) be used with functions that are to be used only
int glob;
within one file
int main( void ) • The static keyword can be used inside functions and blocks
{
glob = 10; – It is initialised once, and its value remains even between function calls. See
int sum = calc( 15 ); Program static.cpp:
std::cout << "sum = " << sum << ’\n’;
}
#include <iostream>
main.h: void show times called( void )
{
#ifndef MAIN H static int called = 0;
#define MAIN H std::cout << "called " << ++called << " times\n";
}
extern int glob; int main( void )
{
#endif for ( int i = 0; i < 5; ++i )
show times called();
}
Modules — silly example (continued)
• output of static.cpp:
calc.cpp:
#include "main.h"
called 1 times
#include "calc.h"
called 2 times
int calc( int n ) called 3 times
{ called 4 times
return glob + n; called 5 times
}
[2] Bjarne Stroustrup. The C++ Programming Language (Special 3rd Edition). Addison-
Wesley, 2004, ISBN 0201889544.
[3] Tom Adamson and James L. Antonakos and Kenneth C. Mansfield Jr. Structured C for
Engineering and Technology, Third Edition. Prentice Hall, 1998.