The midterm will cover:
Basic C++ syntax (comments, declarations, definitions, directives, statements).
Statement flow: what a statement is, blocks.
Basic IO:
cin
andcout
, as well asget
for characters.Expressions and Variables: types of expressions, operators, variable declarations, assignment to variables. Strings and string operations.
Conditional statements
Looping statements
Basic C++ Syntax
What are the two forms of comments in C++?
Is the following a valid comment?
/*
Commented out
/*
Also commented out
*/
Still commented out
*/
What kind of declaration is this:
using namespace std;
How many statements are there in main
, below?
int main() {
cout << "Hello "; cout << "World!";
cout << endl;
int i;
cout << "Enter your age: ";
cin >> i;
cout << "Next year you'll be " << i+1 << " years old.";
cout << endl;
}
How many declarations?
Write out the skeleton program that we always start with. Add single-line comments to each line, explaining what it’s purpose is.
/*
comment
*/
#include <iostream>
using namespace std;
int main()
{
...
}
Re-write the following program into a easier format:
#include<iostream>
using namespace std;int main(
){cout<<"Hello\n"
;int i =
1;cin>>i;cout<< i<<
endl;}
Statement flow
What will the following print out?
int main() {
cout << "H";
cout << "e";
cout << "l";
cout << "l";
cout << "o";
cout << endl;
}
Can you rewrite this program to be shorter?
What will this program do?
int main() {
int i;
cout << "Enter your age: ";
cin >> i;
return 0;
cout << "Wow, that's old.";
}
What will this program do?
int main() {
cout << "One ";
{
cout << "potato, ";
cout << "two ";
{
cout << "potato ";
cout << "three potato, "
}
}
cout << "four!" << endl;
}
Describe, in English, what effect the following program will have on a
and
b
as input by the user:
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
int x = a < b ? a : b;
int y = a > b ? a : b;
cout << x << ", " << y << endl;
}
Basic IO
Assuming that the following is a complete program, what’s wrong with it?
/*
myprogram.cpp
*/
using namespace std;
int main()
{
cout << "Hello, world!" << endl;
}
Complete the following program so that it reads a single character from the user and then prints out its value:
#include <iostream>
using namespace std;
int main() {
cout << "Enter a character: ";
char c;
// Your code goes here
int code = c;
cout << "Its code is " << code << endl;
}
Strings
String methods:
Name | Description |
---|---|
s1 + s2 |
String concatenation |
s.length() |
Length of the string |
s.at(n) |
The character at position n |
s.substr(n,l) |
Substring starting at n of length l |
s.append(s2) |
Append s2 to the end of s |
s.find(p) |
Position where p first occurs |
s.rfind(p) |
Position where p last occurs |
s.insert(pos,s2); |
Insert s2 into the string at p |
string(x,'c') |
String of character c repeated x times |
Assume we have an input string that consists of three names, separated by commas. E.g.,
string data = "matt,scott,mark";
Write code using the string methods to add the name “ethan” to the list.
data.append(",ethan"); data += ",ethan"; // Equivalent
Write code using the string methods to remove the last name (now “ethan”)
from the list.data.erase(data.rfind(","), (data.length() - 1) - data.rfind(",") + 1); data.erase(data.rfind(","), data.length() - data.rfind(",")); // equiv data.erase(data.rfind(","), data.length()); // also equivalent
Write code using the string methods to extract the middle name.
data.substr(data.find(",") + 1, (data.rfind(",") - 1) - (data.find(",") + 1) + 1)
Write code using the string methods to replace the last name with “david”.
data.replace(data.find(",") + 1, (data.rfind(",") - 1) - (data.find(",") + 1) + 1), "david");
Write code using the string methods to get the length of the middle name.
(data.rfind(",") - 1) - (data.find(",") + 1) + 1
Expressions and variables
Add comments to the following program to show where each variable’s scope begins
and ends (either // v's scope begins
or // v's scope ends
for a variable
v
).
#include <iostream>
using namespace std;
int main() {
int a;
cout << "Hello";
int b;
{
int a;
cout << "Good bye";
int c;
cin >> c;
}
int c = 12;
cout << a << endl;
cout << (a + c) << endl;
}
Write out the values of each of these variables, after the program completes:
int a = 5;
int b = a * 3 + 1;
int c = a % (b / 2);
Explain, in English, what the result of this expression will be, in terms of
the variable a
:
a < 0 ? -a : a
What is the result of the following expression?
(1 < 2 ? 2.0 : -2.0) + (3 >= 4 && 2 < 3 ? -3.0 : 0.0)
What is the type (not value) of each of the following expressions:
1 + 2 * 3.0 // float or double
3 * 5 - 6 < 8 * 3 // bool
1 < 2 ? 3 < 4 : 6 < 7 // bool
1 + 2 * 3 / 4 % 5 // int
For each of the following statements, write out the equivalent using only the
plain =
assignment operator (note that some may expand into more than one
assignment!)
a += b;
b *= 4 - a * 4;
++a;
--c;
d %= ++a;
What does the following condition test for?
a % 5 == 0
Conditionals
I might give you a nested if
and ask you to “flatten” it by combining the
conditions; you’ll need to think about what conditions will cause each
branch to be triggered.
I might ask you to write an if-else
chain to handle some set of conditions,
possibly involving multiple variables. E.g., write an if-else chain that will
compare the two variables i
and j
and print “Less than” if i
is less than
j
, “Greater than” if i
is greater than j
, or “Equal” if they are equal.
(Question: if we had three variables, how many ways can they be arranged?)
I might give you an if-else
chain of the form
if(x == 0)
cout << "OK";
else if(x == 1 || x == 2)
cout << "Getting warm";
else if(x == 3)
cout << "Hot";
else
cout << "Extreme conditions detected";
and ask you to translate it into a switch-case
statement. Conversely, I
might ask you to take a switch-case statement and convert it to an if-else
chain. E.g.,
switch(x) {
case 0:
cout << "OK";
break;
case 1:
case 2:
cout << "Getting warm";
break;
case 3:
cout << "Hot";
break;
default:
cout << "Extreme conditions detected";
break;
}
I might give you a switch statement that lacks all (or some of) the break
s and
ask you what will happen for a given value.
Conditionals may also occur elsewhere (e.g., as part of loops, functions, etc.)
Loops
while
-loops, run until the condition is false, the condition is tested at
the beginning of the loop. Examples
Loop until the user enters 0:
int n; cin >> n; while(n != 0) { // Do whatever with n // Read the next n cin >> n; }
Note that we have to read in the first value outside the loop, to “prime the pump”. This would be clearer as a
do-while
loop.Loop as long as the user is still entering values:
int n; while(cin >> n) { // Process n }
Loop from 0 to n-1
int i = 0; while(i < n) { // Do something with i i++; }
This could even be written as
int i = 0; while(i++ < n) { // Do something with i }
Loop forever, possibly due to some conditions inside the loop:
while(true) { ... }
Any
for
loop can be rewritten into awhile
loop; you should know how to do this.
do-while
loops run until a condition is false, but always at least once.
do-while
is good for situations where we have to do some setup before testing
the condition for the first time, or where we want the loop to run at least
once.
Any kind of loop can be transformed into any other type of loop. while
loops
translate into for
loops fairly simply. Moving between while
and do-while
may require the use of break
. E.g.,
int i = 0;
while(i < n) {
// Do stuff
i++;
}
To convert this to do-while
, we have to account for the possibility that
n = 0
to start with.
int i == 0;
do {
if(!(i < n))
break;
// Do stuff
i++;
} while(i < n);
Note that now, the condition at the end is redundant. It’s going to be tested
by the if
at the beginning, so we can set the condition to true
and it
will still work correctly.
Sometimes, a loop won’t have a nice tidy condition that can be tested at the
beginning or the end. In these cases, a break
or continue
in the middle
can be useful. For example, consider finding the product of a user’s input.
We could write this as
int x, product = 1;
while(cin >> x)
product *= x;
But this ignores a potential optimization: if the product is ever 0, then we
can quit early. We can encode this using break
:
int x, product = 1;
while(cin >> x) {
product *= x;
if(product == 0)
break;
}
If we wanted to, we could optimize the situation where the element x == 1
.
In this case, the product will be unchanged. (This isn’t really an optimization,
because multiplication is easy. But we might be doing some bigger calculation
and we could detect early what the results would be, and skip it.)
int x, product = 1;
while(cin >> x) {
if(x == 1)
continue;
product *= x;
if(product == 0)
break;
}
for
loops group together the variable initialization, condition, and update
steps which many loops have. You should know the order in which these happen:
for(initialization; condition; update)
body;
becomes
initialization;
while(condition) {
body;
update;
}
You should be able to take a for
loop and translate it into a while
loop,
and vice versa (assuming a while
loop that depends on a variable). Remember
that for
loops can be about more than one variable!
for(int i = 0, j = 10; i < j; i++, j--)
cout << i << " " << j << endl;
Here, the initialization declares two variables, and the update modifies both of them. What will this print out?
The initialization, condition, or update of a for
loop can be empty. If the
condition is empty, it’s the same as if you wrote true
. You still need the
semicolons. The shortest for
loop is thus
for(;;)
// Runs forever
while is the same as
while(true)
// Runs forever
I might give you a loop and ask you what output it will produce.
Loops and strings: You should know how to use a loop to process the characters in a string:
string s;
for(int i = 0; i < s.length(); i++)
... s.at(i) ...
Note that you can combine “fancy” loops (reverse order, loop over every other element, etc.) with accumulating loops. E.g., to sum up all the powers of 2 that are less than 1000:
int sum = 0;
for(int i = 1; i < 1000; i *= 2)
sum += i;
Pay attention to the common
while(condition);
body;
error. I might ask you to find it.
Nested loops: I might give you a nested loop like
for(int i = 0; i < 5; i++)
for(int j = 0; j <= i; j++)
cout << i << " " << j << endl;
and ask what this will output. This one is a bit more tricky, because the inner loop depends on the outer loop. Note that you could write an accumulating loop over a nested loop. E.g., suppose we want to find the products of all the pairs of numbers from 0 to 10. (E.g., 0x0, 0x1, … all the way up to 10x10) and then we want to count how many are odd:
int count = 0;
for(int i = 0; i <= 10; i++)
for(int j = 0; j <= 10; j++)
if(i*j % 2 == 1)
count++;
Question: what is the difference between this loop
for(int i = 0; i < 5; i++)
for(int j = 0; j < 5; j++)
cout << i << "," << j << endl;
and this loop
for(int i = 0, j = 0; i < 5 && j < 5; i++, j++)
cout << i << "," << j << endl;
The first will print out all 25 pairs
0,0 0,1 0,2 ... 1,0 1,1, 1,2 ... 4,3 4,4
whereas the second will print out
0,0 1,1 2,2, 3,3 4,4
I.e., in the second loop, the updates happen simultaneously.