Lecture 1 Note: Introduction
1 Compiled Languages and C++
1.1 Why Use a Language Like C++?
At its core, a computer is just a processor with some memory, capable of running tiny
instructions like “store 5 in memory location 23459.” Why would we express a program as a text
file in a programming language, instead of writing processor instructions?
The advantages:
1. Conciseness: programming languages allow us to express common sequences of commands
more concisely. C++ provides some especially powerful shorthand’s.
2. Maintainability: modifying code is easier when it entails just a few text edits, instead of
rearranging hundreds of processor instructions. C++ is object oriented (more on that in
Lectures 7-8), which further improves maintainability.
3. Portability: different processors make different instructions available. Programs written as
text can be translated into instructions for many different processors; one of C++’s strengths
is that it can be used to write programs for nearly any processor.
C++is a high-level language: when you write a program in it, the shorthand’s are sufficiently
expressive that you don’t need to worry about the details of process or instructions. C++does
give access to some lower-level functionality than other languages (e.g. memory addresses).
1.2 The Compilation Process
A program goes from text files(or source files)to processor instructions as follows:
Object files are intermediate files that represent an incomplete copy of the program: each source
file only expresses a piece of the program, so when it is compiled into an object file, the object
file has some markers indicating which missing pieces it depends on. The linker
Takes those object files and the compiled libraries of predefined code that they rely on, fills in all
the gaps, and spits out the final program, which can then be run by the operating system (OS).
The compiler and linker are just regular programs. The step in the compilation processing which
the compiler reads the file is called parsing.
In C++, all these steps are performed ahead of time, before you start running a program. In some
languages, they are done during the execution process, which takes time. This is one of the
reasons C++ code runs far faster than code in many more recent languages.
C++ actually adds an extra step to the compilation process: the code is run through a
preprocessor, which applies some modifications to the source code, before being fed to the
compiler. Thus, the modified diagram is:
1.3 General Notes on C++
C++ is immensely popular, particularly for applications that require speed and/or access to some
low-level features. It was created in 1979 by Bjarne Stroustrup, at first as a set of extensions to
the C programming language. C++ extends C; our first few lectures will basically be on the C
parts of the language.
Though you can write graphical programs in C++, it is much hairier and less portable than text-
based (console)programs. We will be sticking to console programs in this course.
Everything in C++ is case sensitive: someName is not the same as SomeName.
Hello World
In the tradition of programmers everywhere, we’ll use a “Hello,world!” program as an entry
point into the basic features of C++.
1 // A Hello World program
2 #include <iostream >
3 using namespace std;
4 int main ()
5 cout << "Hello, world! \n";
6 return 0;
}
2.2 Tokens
Tokens are the minimal chunk of program that have meaning to the compiler –the smallest
meaningful symbols in the language. Our code displays all 6 kinds of tokens, though the usual
use of operators is not present here:
2.3 Lines-By-Line Explanation
1. // indicates that everything following it until the end of the line is a comment: it is ignored by
the compiler. Another way to write a comment is to put it between /* and */ (e.g. x = 1 +
/*sneaky comment here*/ 1;). A comment of this form may span multiple lines. Comments
exist to explain non-obvious things going on in the code. Use them: document your code
well!
2. Lines beginning with # are preprocessor commands, which usually change what code is
actually being compiled. #include tells the preprocessor to dump in the contents of another
file, here the iostream file, which defines the procedures for input/output.
int main() {...}defines the code that should execute when the program starts up. The curly braces
represent grouping of multiple commands into a block. More about this syntax is in the next few
lectures.
1. • cout << : This is the syntax for outputting some piece of text to the screen. We’ll discuss
how it works in Lecture 9.
• Namespaces: In C++, identifiers can be defined within a context – sort of a directory of
names – called a namespace. When we want to access an identifier defined in a
namespace, we tell the compiler to look for it in that namespace using the scope
resolution operator (::). Here, we’re telling the compiler to look for cout in the std
namespace, in which many standard C++ identifiers are defined.
A cleaner alternative is to add the following line below line 2:
using namespace std;
This line tells the compiler that it should look in the std namespace for any identifier we haven’t
defined. If we do this, we can omit the std:: prefix when writing cout. This is the recommended
practice.
• Strings: A sequence of characters such as Hello, world is known as a string. A string that
is specified explicitly in a program is a string literal.
• Escape sequences: The \n indicates a newline character. It is an example of an escape
sequence – a symbol used to represent a special character in a text literal. Here are all the C++
escape sequences which you can include in strings:
7. return 0 indicates that the program should tell the operating system it has completed
successfully. This syntax will be explained in the context of functions; for now, just include it
as the last line in the main block.
Note that every statement ends with a semi colon(except preprocessor commands and blocks
using {}). Forgetting these semi colons is a common mistake among new C++programmers.
3 Basic Language Features
So far our program doesn’t do very much. Let’s tweak it in various ways to demonstrate some
more interesting constructs.
3.1 Values and Statements
First, a few definitions:
• A statement is a unit of code that does something –a basic building block of a program.
• An expression is a statement that has a value – for instance, a number, a string, the sum
of two numbers, etc. 4+2, x-1, and "Hello, world!\n" are all expressions.
Not every statement is an expression. It makes no sense to talk about the value of an #include
statement, for instance.
3.2 Operators
We can perform arithmetic calculations with operators. Operators act on expressions to form a
new expression. For example, we could replace "Hello, world!\n" with (4 + 2) / 3, which would
cause the program to print the number 2. In this case, the + operator acts on the expressions 4
and 2 (its operands).
Operator types:
• Mathematical: +, -, *, /, and parentheses have their usual mathematical meanings,
including using -for negation. % (the modulus operator) takes the remainder of two numbers:
6%5 evaluates to 1.
• Logical: used for “and,” “or,” and so on. More on those in the next lecture.
• Bitwise: used to manipulate the binary representations of numbers. We will not focus on
these.
3.3 Data Types
Every expression has a type – a formal description of what kind of data its value is. For
instance,0 is aninteger,3.142 is a floating-point (decimal)number, and "Hello, world!\n" is a
string value(a sequence of characters). Data of different types take different amounts of memory
to store. Here are the built-in data types we will use most often:
Notes on this table:
• A signed integer is one that can represent a negative number; an unsigned integer will
never be interpreted as negative, so it can represent a wider range of positive numbers. Most
compilers assume signed if unspecified.
• There are actually 3 integer types: short, int, and long, in non-decreasing order of size(int
is usually a synonym for one of the other two). You generally don’t need to worry about which
kind to use unless you’re worried about memory usage or you’re using really huge numbers.
Thesamegoesforthe3floatingpointtypes,float, double, and long double, which arein non-
decreasing order of precision(there is usually some imprecision in representing real numbers on a
computer).
• The sizes/ranges for each type are not fully standardized; those shown above are the ones
used on most 32-bit computers.
An operation can only be performed on compatible types. You can add 34 and 3, but you can’t
take the remainder of an integer and a floating-point number.
An operator also normally produces a value of the same type as its operands; thus, 1/4 evaluates
to 0 because with two integer operands, / truncates the result to an integer. To get 0.25, you’d
need to write something like 1 / 4.0.
A text string, for reasons we will learn in Lecture 5, has the type char *.
4 Variables
We might want to give a value a name so we can refer to it later. We do these using variables. A
variable is a named location in memory.
For example, say we wanted to use the value 4+2 multiple times. We might call it x and use it as
follows:
1 #inlcude <iostream>
2 using namespace std;
3
4 int main() {
5 int x;
6 x = 4 + 2;
7 cout << x / 3 << “ “<<x * 2;
8
9 return 0;
10 }
(Note how we can print a sequence of values by “chaining” the << symbol.)
The name of a variable is an identifier token. Identifiers may contain numbers, letters, and
underscores(_), and may not start with a number.
Line 5 is the declaration of the variable x. We must tell the compiler what type x will be so that it
knows how much memory to reserve for it and what kinds of operations may be performed on it.
Line 6 is the initialization of x, where we specify an initial value for it. This introduces a new
operator: =, the assignment operator. We can also change the value of x later on in the code
using this operator.
We could replace lines 5 and 6 with a single statement that does both declaration and
initialization:
int x = 4 + 2;
This form of declaration/initialization is cleaner, so it is to be preferred.
5 Input
Now that we know how to give names to values, we can have the user of the program input
values. This is demonstrated in line 6 below:
1 #inlcude <iostream>
2 using namespace std;
3
4 int main() {
5 int x;
6 cin >> x;
7 cout << x / 3 << “ “<<x * 2;
8
9 return 0;
10 }
Just as cout << is the syntax for out putting values, cin >> (line6) is the syntax for inputting
values.
Memory trick: if you have trouble remembering which way the angle brackets go for cout and
cin, think of them as arrows pointing in the direction of data flow. cin represents the terminal,
with data flowing from it to your variables; cout likewise represents the terminal, and your data
flows to it.
6 Debugging
There are two kinds of errors you’ll run into when writing C++ programs: compilation errors and
runtime errors. Compilation errors are problems raised by the compiler, generally resulting from
violations of the syntax rules or misuse of types. These are often caused by typos and the like.
Runtime errors are problems that you only spot when you run the program: you did specify a
legal program, but it doesn’t do what you wanted it to. These are usually more tricky to catch,
since the compiler won’t tell you about them.
Lecture 2 Notes: Flow of Control
1 Motivation
Normally, a program executes statements from first to last. The first statement is executed, then
the second, then the third, and so on, until the program reaches its end and terminates. A
computer program likely wouldn't be very useful if it ran the same sequence of statements every
time it was run. It would be nice to be able to change which statements ran and when, depending
on the circumstances. For example, if a program checks a file for the number of times a certain
word appears, it should be able to give the correct count no matter what file and word are given
to it. Or, a computer game should move the player's character around when the player wants. We
need to be able to alter the order in which a program's statements are executed, the control flow.
2 Control Structures
Control structures are portions of program code that contain statements within them and,
depending on the circumstances, execute these statements in a certain way. There are typically
two kinds: conditionals and loops.
2.1 Conditionals
In order for a program to change its behavior depending on the input, there must a way to test
that input. Conditionals allow the program to check the values of variables and to execute (or not
execute) certain statements. C++ has if and switch-case conditional structures.
2.1.1 Operators
Conditionals use two kinds of special operators: relational and logical. These are used to
determine whether some condition is true or false.
The relational operators are used to test a relation between two expressions:
They work the same as the arithmetic operators (e.g., a > b) but return a Boolean value of either
true or false, indicating whether the relation tested for holds. (An expression that returns this
kind of value is called a Boolean expression.) For example, if the variables x and y have been set
to 6 and 2, respectively, then x > y returns true. Similarly, x < 5 returns false.
The logical operators are often used to combine relational expressions into more complicated
Boolean expressions:
The operators return true or false, according to the rules of logic:
The ! operator is a unary operator, taking only one argument and negating its value:
Examples using logical operators (assume x = 6 and y = 2):
!(x > 2) → false
(x > y) && (y > 0) → true
(x < y) && (y > 0) → false
(x < y) || (y > 0) → true
Of course, Boolean variables can be used directly in these expressions, since they hold true and
false values. In fact, any kind of value can be used in a Boolean expression due to a quirk C++
has: false is represented by a value of 0 and anything that is not 0 is true. So, “Hello, world!” is
true, 2 is true, and any int variable holding a non-zero value is true. This means !x returns false
and x && y returns true!
2.1.2 if, if-else and else if
The if conditional has the form:
if(condition)
{
statement
1
statemett2
…
}
The condition is some expression whose value is being tested. If the condition resolves to a value
of true, then the statements are executed before the program continues on. Otherwise, the
statements are ignored. If there is only one statement, the curly braces may be omitted, giving the
form:
if(condition)stat
ement
The if-else form is used to decide between two sequences of statements referred to as blocks:
if(condition)
{ statementA1
statementA2…
}
else
{ statement
statementB2…
}
If the condition is met, the block corresponding to the if is executed. Otherwise, the block
corresponding to the else is executed. Because the condition is either satisfied or not, one of the
blocks in an if-else must execute. If there is only one statement for any of the blocks, the curly
braces for that block may be omitted:
if (condition)
statementA1
else
statementB1
The else if is used to decide between two or more blocks based on multiple conditions:
if(condition1)
{statementA1state
mentA2…
}else if(condition2){
statementB1statementB2…
}
If condition1 is met, the block corresponding to the if is executed. If not, then only if condition2
is met is the block corresponding to the else if executed. There may be more than one else if,
each with its own condition. Once a block whose condition was met is executed, any else ifs
after it are ignored. Therefore, in an if-else-if structure, either one or no block is executed.
An else may be added to the end of an if-else-if. If none of the previous conditions are met, the
else block is executed. In this structure, one of the blocks must execute, as in a normal if-else.
Here is an example using these control structures:
1 #include <iostream>
2 using namespace std;
3
4 int main() {
5 int x = 6;
6 int y = 2;
7
8 if(x > y)
9 cout << “x is greater than y\n”;
10 else if(y > x)
11 cout << “y is greater than x\n”;
else
13 cout << “x and y are equal\n”;
14
15 return 0;
16 }
The output of this program is x is greater than y. If we replace lines 5 and 6 with
int x = 2;
int y = 6;
then the output is y is greater than x. If we replace the lines with
int x = 2;
int y = 2;
then the output is x and y are equal.
then the output is x and y are equal.
2.1.3 switch-case
The switch-case is another conditional structure that may or may not execute certain statements.
However, the switch-case has peculiar syntax and behavior:
switch(expression){
case constant1:statementA1statementA2...break;
case constant2:statementB1statementB2...break;
...
default:statementZ1statementZ2...
}
The switch evaluates expression and, if expression is equal to constant1, then the statements
beneath case constant 1: are executed until a break is encountered. If expression is not equal to
constant1, then it is compared to constant2. If these are equal, then the statements beneath case
constant 2: are executed until a break is encountered. If not, then the same process repeats for
each of the constants, in turn. If none of the constants match, then the statements beneath default:
are executed.
Due to the peculiar behavior of switch-cases, curly braces are not necessary for cases where there
is more than one statement (but they are necessary to enclose the entire switch-case). switch-
cases generally have if-else equivalents but can often be a cleaner way of expressing the same
behavior.
Here is an example using switch-case:
This program will print x is not 1, 2, or 3. If we replace line 5 with int x = 2; then the program
will print x is 2 or 3.
2.2 Loops
Conditionals execute certain statements if certain conditions are met; loops execute certain
statements while certain conditions are met. C++ has three kinds of loops: while, do-while, and
for.
2.2.1 while and do-while
The while loop has a form similar to the if conditional:
while(condition)
{
statement1
statement2
…}
As long as condition holds, the block of statements will be repeatedly executed. If there is only
one statement, the curly braces may be omitted. Here is an example:
This program will print x is 10.
The do-while loop is a variation that guarantees the block of statements will be executed at least
once:
do
{statement1statement2…
}while(condition);
The block of statements is executed and then, if the condition holds, the program returns to the
top of the block. Curly braces are always required. Also note the semicolon after the while
condition.
2.2.2 for
The for loop works like the while loop but with some change in syntax:
for(initialization; condition; incrementation)
{statement1statement2…
}
The for loop is designed to allow a counter variable that is initialized at the beginning of the loop
and incremented (or decremented) on each iteration of the loop. Curly braces may be omitted if
there is only one statement. Here is an example:
This program will print out the values 0 through 9, each on its own line.
If the counter variable is already defined, there is no need to define a new one in the initialization
portion of the for loop. Therefore, it is valid to have the following:
Note that the first semicolon inside the for loop's parentheses is still required.
A for loop can be expressed as a while loop and vice-versa. Recalling that a for loop has the form
for(initialization; condition; incrementation)
{statement1statemen
t2…
}
we can write an equivalent while loop as
initialization
while(condition){
statement1statement2…
incrementation
}
Using our example above,
is converted to
The incrementation step can technically be anywhere inside the statement block, but it is good
practice to place it as the last step, particularly if the previous statements use the current value of
the counter variable.
2.3 Nested Control Structures
It is possible to place ifs inside of ifs and loops inside of loops by simply placing these
structures inside the statement blocks. This allows for more complicated program behavior.
Here is an example using nesting if conditionals:
This program will print x is greater than y on one line and then x is equal to 6 on the next line.
Here is an example of nested Loops:
This program will print four lines of 0123.
Lecture 3 Functions
A function is a group of statements that together perform a task. Every C++ program
has at least one function, which is main(), and all the most trivial programs can define
additional functions.
You can divide up your code into separate functions. How you divide up your code
among different functions is up to you, but logically the division usually is such that
each function performs a specific task.
A function declaration tells the compiler about a function's name, return type, and
parameters. A function definition provides the actual body of the function.
The C++ standard library provides numerous built-in functions that your program can
call. For example, function strcat() to concatenate two strings, function memcpy() to
copy one memory location to another location and many more functions.
A function is known with various names like a method or a sub-routine or a procedure
etc.
Defining a Function
The general form of a C++ function definition is as follows –
A C++ function definition consists of a function header and a function body. Here are
all the parts of a function −
Return Type − A function may return a value. The return_type is the data type of the value
the function returns. Some functions perform the desired operations without returning a
value. In this case, the return_type is the keyword void.
Function Name − This is the actual name of the function. The function name and the
parameter list together constitute the function signature.
Parameters − A parameter is like a placeholder. When a function is invoked, you pass a
value to the parameter. This value is referred to as actual parameter or argument. The
parameter list refers to the type, order, and number of the parameters of a function.
Parameters are optional; that is, a function may contain no parameters.
Function Body − The function body contains a collection of statements that define what the
function does.
Example
Following is the source code for a function called max(). This function takes two
parameters num1 and num2 and return the biggest of both −
Function Declarations
A function declaration tells the compiler about a function name and how to call the
function. The actual body of the function can be defined separately.
A function declaration has the following parts
return_type function_name( parameter list );
For the above defined function max(), following is the function declaration −
int max(int num1, int num2);
Parameter names are not important in function declaration only their type is required,
so following is also valid declaration −
int max(int, int);
Function declaration is required when you define a function in one source file and you call
that function in another file. In such case, you should declare the function at the top of the
file calling the function.
Calling a Function
While creating a C++ function, you give a definition of what the function has to do. To
use a function, you will have to call or invoke that function.
When a program calls a function, program control is transferred to the called function.
A called function performs defined task and when it’s return statement is executed or
when its function-ending closing brace is reached, it returns program control back to
the main program.
To call a function, you simply need to pass the required parameters along with function
name, and if function returns a value, then you can store returned value. For example
−
#include <iostream>
using namespace std;
// function declaration
int max(int num1, int num2);
int main () {
// local variable declaration:
int a = 100;
int b = 200;
int ret;
// calling a function to get max value.
ret = max(a, b);
cout << "Max value is : " << ret << endl;
return 0;
}
// function returning the max between two numbers
int max(int num1, int num2) {
// local variable declaration
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
I kept max() function along with main() function and compiled the source code. While
running final executable, it would produce the following result –
Max value is: 200
Function Arguments
If a function is to use arguments, it must declare variables that accept the values of the
arguments. These variables are called the formal parameters of the function.
The formal parameters behave like other local variables inside the function and are created upon
entry into the function and destroyed upon exit.
While calling a function, there are two ways that arguments can be passed to a function −
[Link] Call Type & Description
1 Call by Value
This method copies the actual value of an argument into the formal parameter of the function.
In this case, changes made to the parameter inside the function have no effect on the
argument.
2 Call by Pointer
This method copies the address of an argument into the formal parameter. Inside the function,
the address is used to access the actual argument used in the call. This means that changes
made to the parameter affect the argument.
3 Call by Reference
This method copies the reference of an argument into the formal parameter. Inside the function,
the reference is used to access the actual argument used in the call. This means that changes
made to the parameter affect the argument.
By default, C++ uses call by value to pass arguments. In general, this means that
code within a function cannot alter the arguments used to call the function and above
mentioned example while calling max() function used the same method.
Default Values for Parameters
When you define a function, you can specify a default value for each of the last
parameters. This value will be used if the corresponding argument is left blank when
calling to the function.
This is done by using the assignment operator and assigning values for the arguments
in the function definition. If a value for that parameter is not passed when the function
is called, the default given value is used, but if a value is specified, this default value is
ignored and the passed value is used instead. Consider the following example −
#include <iostream>
using namespace std;
int sum(int a, int b = 20) {
int result;
result = a + b;
return (result);
}
int main () {
// local variable declaration:
int a = 100;
int b = 200;
int result;
// calling a function to add the values.
result = sum(a, b);
cout << "Total value is :" << result << endl;
// calling a function again as follows.
result = sum(a);
cout << "Total value is :" << result << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Total value is: 300
Total value is: 120
Lecture 4 Notes: Arrays and Strings
1 Array
So far we have used variables to store values in memory for later reuse. We now explore
a means to store multiple values together as one unit, the array.
An array is a fixed number of elements of the same type stored sequentially in memory.
Therefore, an integer array holds some number of integers; a character array holds some
number of characters, and so on. The size of the array is referred to as its dimension. To
declare an array in C++, we write the following:
type arrayName[dimension];
To declare an integer array named arr of four elements, we write int arr[4];
The elements of an array can be accessed by using an index into the array. Arrays in C++
are zero-indexed, so the first element has an index of 0. So, to access the third element in
arr, we write arr[2]; The value returned can then be used just like any other integer.
Like normal variables, the elements of an array must be initialized before they can be
used; otherwise we will almost certainly get unexpected results in our program. There are
several ways to initialize the array. One way is to declare the array and then initialize some
or all of the elements:
Another way is to initialize some or all of the values at the time of declaration:
int arr[4] = { 6, 0, 9, 6 };
Sometimes it is more convenient to leave out the size of the array and let the
compiler determine the array's size for us, based on how many elements we give it:
int arr[] = { 6, 0, 9, 6, 2, 0, 1, 1 };
Here, the compiler will create an integer array of dimension 8.
The array can also be initialized with values that are not known beforehand:
Note that when accessing an array the index given must be a positive integer from 0 to n-1,
where n is the dimension of the array. The index itself may be directly provided, derived
from a variable, or computed from an expression:
arr[5];
arr[i];
arr[i+3];
Arrays can also be passed as arguments to functions. When declaring the function, simply
specify the array as a parameter, without a dimension. The array can then be used as normal
within the function. For example:
The function sum takes a constant integer array and a constant integer length as its
arguments and adds up length elements in the array. It then returns the sum, and the
program prints out Sum: 28.
It is important to note that arrays are passed by reference and so any changes made to the
array within the function will be observed in the calling scope.
C++ also supports the creation of multidimensional arrays, through the addition of more
than one set of brackets. Thus, a two-dimensional array may be created by the following:
type arrayName[dimension1][dimension2];
The array will have dimension1 x dimension2 elements of the same type and can be thought
of as an array of arrays. The first index indicates which of dimension1 subarrays to access,
and then the second index accesses one of dimension2 elements within that subarray.
Initialization and access thus work similarly to the one-dimensional case:
The array can also be initialized at declaration in the following ways:
int twoDimArray[2][4] = { 6, 0, 9, 6, 2, 0, 1, 1 };
int twoDimArray[2][4] = { { 6, 0, 9, 6 } , { 2, 0, 1, 1 } };
Note that dimensions must always be provided when initializing multidimensional arrays, as it
is otherwise impossible for the compiler to determine what the intended element partitioning
is. For the same reason, when multidimensional arrays are specified as arguments to functions,
all dimensions but the first must be provided (the first dimension is optional), as in the
following:
int aFunction(int arr[][4]) { … }
Multidimensional arrays are merely an abstraction for programmers, as all of the elements
in the array are sequential in memory. Declaring int arr[2][4]; is the same thing as
declaring int arr[8];
2 Strings
String literals such as “Hello, world!” are actually represented by C++ as a sequence
of characters in memory. In other words, a string is simply a character array and can be
manipulated as such.
Consider the following program:
This program prints Hello, world! Note that the character array helloworld ends with a
special character known as the null character. This character is used to indicate the end of
the string.
Character arrays can also be initialized using string literals. In this case, no null character is
needed, as the compiler will automatically insert one:
char helloworld[] = “Hello, world!”;
The individual characters in a string can be manipulated either directly by the programmer
or by using special functions provided by the C/C++ libraries. These can be included in a
program through the use of the #include directive. Of particular note are the following:
• cctype (ctype.h): character handling
• cstdio (stdio.h): input/output operations
• cstdlib (stdlib.h): general utilities
• cstring (string.h): string manipulation
Here is an example to illustrate the cctype library:
This example uses the isalpha, isupper, ispunct, and tolower functions from the cctype
library. The is-functions check whether a given character is an alphabetic character, an
uppercase letter, or a punctuation character, respectively. These functions return a Boolean
value of either true or false. The tolower function converts a given character to lowercase.
The for loop beginning at line 9 takes each successive character from messyString until it
reaches the null character. On each iteration, if the current character is alphabetic and
uppercase, it is converted to lowercase and then displayed. If it is already lowercase it is simply
displayed. If the character is a punctuation mark, a space is displayed. All other characters are
ignored. The resulting output is this is a string. For now, ignore the (char)on line 11; we will
cover that in a later lecture.
Here is an example to illustrate the cstring library:
This example creates and initializes two strings, fragment1 and fragment2. fragment3 is
declared but not initialized. finalString is partially initialized (with just the null character).
fragment1 is copied into fragment3 using strcpy, in effect initializing fragment3 to I'm a s. strcat
is then used to concatenate fragment3 onto finalString (the function overwrites the existing null
character), thereby giving finalString the same contents as fragment3. Then strcat is used again
to concatenate fragment2 onto finalString. finalString is displayed, giving I'm a string!.
You are encouraged to read the documentation on these and any other libraries of interest to
learn what they can do and how to use a particular function properly. (One source is
[Link]