Chapter 3 - Objects, Types and Values

Drill

  1. This drill is to write a program that produces a simple form letter based on user input. Begin by typing the code from §3.1 prompting a user to enter his or her first name and writing “Hello, first_name” where first_name is the name entered by the user. Then modify your code as follows: change the prompt to “Enter the name of the person you want to write to” and change the output to “Dear first_name,”. Don’t forget the comma.

The following code shows the original program from §3.1.

letterformoriginal.cpp
1
2
3
4
5
6
7
8
9
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Please enter your first name (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Hello, " << first_name << "!\n";
}

Here is the modified version to satisfy the first drill:

letterform01.cpp
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Enter the name of the person you want to write to (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Dear " << first_name << ",\n";

    return 0;
}

Executing the program results in:

Enter the name of the person you want to write to (followed by 'enter'):
Pia
Dear Pia,
  1. Add an introductory line or two, like “How are you? I am fine. I miss you.” Be sure to indent the first line. Add a few more lines of your choosing — it’s your letter.
letterform02.cpp
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Enter the name of the person you want to write to (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Dear " << first_name << ",\n";

    /// 2.
    cout << "\tHow are you? I am fine. I miss you.\n";
    cout << "I hope you had a nice day and I would've loved to spend it with you.\n";
    cout << "Luckily, next weekend is not far away, and we will meet again.\n";
    cout << "I am sure we will find something fun to do, like swimming, hiking or biking,\n";
    cout << "and maybe going out into the city in the evening.\n";
    cout << "I really look forward to seeing you again.\n";

    return 0;
}

The output will be similar to this:

Enter the name of the person you want to write to (followed by 'enter'):
Pia
Dear Pia,
    How are you? I am fine. I miss you.
I hope you had a nice day and I would've loved to spend it with you.
Luckily, next weekend is not far away, and we will meet again.
I am sure we will find something fun to do, like swimming, hiking or biking,
and maybe going out into the city in the evening.
I really look forward to seeing you again.

Process finished with exit code 0
  1. Now prompt the user for the name of another friend, and store it in friend_name. Add a line to your letter: “Have you seen friend_name lately?”
letterform03.cpp
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Enter the name of the person you want to write to (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Dear " << first_name << ",\n";

    /// 2.
    cout << "\tHow are you? I am fine. I miss you.\n";
    cout << "I hope you had a nice day and I would've loved to spend it with you.\n";
    cout << "Luckily, next weekend is not far away, and we will meet again.\n";
    cout << "I am sure we will find something fun to do, like swimming, hiking or biking,\n";
    cout << "and maybe going out into the city in the evening.\n";
    cout << "I really look forward to seeing you again.\n";

    /// 3.
    cout << "Enter the name of another friend (followed by 'enter'):\n";
    string friend_name;
    cin >> friend_name;
    cout << "Have you seen " << friend_name << " lately?\n";


    return 0;

}

This results in the output similar to the following:

Enter the name of the person you want to write to (followed by 'enter'):
Pia
Dear Pia,
    How are you? I am fine. I miss you.
I hope you had a nice day and I would've loved to spend it with you.
Luckily, next weekend is not far away, and we will meet again.
I am sure we will find something fun to do, like swimming, hiking or biking,
and maybe going out into the city in the evening.
I really look forward to seeing you again.
Enter the name of another friend (followed by 'enter'):
Sebastian
Have you seen Sebastian lately?

Process finished with exit code 0
  1. Declare a char variable called friend_sex and initialize its value to 0. Prompt the user to enter an m if the friend is male and an f if the friend is female. Assign the value entered to the variable friend_sex. Then use two if-statements to write the following:
  • If the friend is male, write “If you see friend_name please ask him to call me.”
  • If the friend is female, write “If you see friend_name please ask her to call me.”
letterform04.cpp
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Enter the name of the person you want to write to (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Dear " << first_name << ",\n";

    /// 2.
    cout << "\tHow are you? I am fine. I miss you.\n";
    cout << "I hope you had a nice day and I would've loved to spend it with you.\n";
    cout << "Luckily, next weekend is not far away, and we will meet again.\n";
    cout << "I am sure we will find something fun to do, like swimming, hiking or biking,\n";
    cout << "and maybe going out into the city in the evening.\n";
    cout << "I really look forward to seeing you again.\n";

    /// 3.
    cout << "Enter the name of another friend (followed by 'enter'):\n";
    string friend_name;
    cin >> friend_name;
    cout << "Have you seen " << friend_name << " lately?\n";

    /// 4.
    char friend_sex = 0;
    cout << "Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):\n";
    cin >> friend_sex;
    if ('m' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask him to call me.\n";
    }
    else if ('f' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask her to call me.\n";
    }


    return 0;

}

Entering the following results in this output:

Enter the name of the person you want to write to (followed by 'enter'):
Pia
Dear Pia,
    How are you? I am fine. I miss you.
I hope you had a nice day and I would've loved to spend it with you.
Luckily, next weekend is not far away, and we will meet again.
I am sure we will find something fun to do, like swimming, hiking or biking,
and maybe going out into the city in the evening.
I really look forward to seeing you again.
Enter the name of another friend (followed by 'enter'):
Sebastian
Have you seen Sebastian lately?
Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):
m
If you see Sebastian please ask him to call me.
  1. Prompt the user to enter the age of the recipient and assign it to an int variable age. Have your program write “I hear you just had a birthday and you are age years old.” If age is 0 or less or 110 or more, call simple_error(“you’re kidding!”) using simple_error() from std_lib_facilities.h.
letterform05.cpp
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Enter the name of the person you want to write to (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Dear " << first_name << ",\n";

    /// 2.
    cout << "\tHow are you? I am fine. I miss you.\n";
    cout << "I hope you had a nice day and I would've loved to spend it with you.\n";
    cout << "Luckily, next weekend is not far away, and we will meet again.\n";
    cout << "I am sure we will find something fun to do, like swimming, hiking or biking,\n";
    cout << "and maybe going out into the city in the evening.\n";
    cout << "I really look forward to seeing you again.\n";

    /// 3.
    cout << "Enter the name of another friend (followed by 'enter'):\n";
    string friend_name;
    cin >> friend_name;
    cout << "Have you seen " << friend_name << " lately?\n";

    /// 4.
    char friend_sex = 0;
    cout << "Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):\n";
    cin >> friend_sex;
    if ('m' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask him to call me.\n";
    }
    else if ('f' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask her to call me.\n";
    }

    /// 5.
    cout << "Enter the age of the recipient (followed by 'enter'):\n";
    int age;
    cin >> age;
    cout << "I hear you just had a birthday and you are " << age << " years old.\n";
    if (0 >= age || 110 <= age)
    {
        simple_error("you're kidding!");
    }


    return 0;

}

The output when the age is inbetween 0 and 110:

Enter the name of the person you want to write to (followed by 'enter'):
Pia
Dear Pia,
    How are you? I am fine. I miss you.
I hope you had a nice day and I would've loved to spend it with you.
Luckily, next weekend is not far away, and we will meet again.
I am sure we will find something fun to do, like swimming, hiking or biking,
and maybe going out into the city in the evening.
I really look forward to seeing you again.
Enter the name of another friend (followed by 'enter'):
Sebastian
Have you seen Sebastian lately?
Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):
m
If you see Sebastian please ask him to call me.
Enter the age of the recipient (followed by 'enter'):
29
I hear you just had a birthday and you are 29 years old.

Erroneous input results in:

Enter the name of the person you want to write to (followed by 'enter'):
Pia
Dear Pia,
    How are you? I am fine. I miss you.
I hope you had a nice day and I would've loved to spend it with you.
Luckily, next weekend is not far away, and we will meet again.
I am sure we will find something fun to do, like swimming, hiking or biking,
and maybe going out into the city in the evening.
I really look forward to seeing you again.
Enter the name of another friend (followed by 'enter'):
Sebastian
Have you seen Sebastian lately?
Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):
m
If you see Sebastian please ask him to call me.
Enter the age of the recipient (followed by 'enter'):
0
I hear you just had a birthday and you are 0 years old.
Please enter a character to exit
error: you're kidding!
^D

Process finished with exit code 1
  1. Add this to your letter:
  • If your friend is under 12, write “Next year you will be age+1.”

  • If your friend is 17, write “Next year you will be able to vote.”

  • If your friend is over 70, write “I hope you are enjoying retirement.”

    Check your program to make sure it responds appropriately to each kind of value.

letterform06.cpp
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Enter the name of the person you want to write to (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Dear " << first_name << ",\n";

    /// 2.
    cout << "\tHow are you? I am fine. I miss you.\n";
    cout << "I hope you had a nice day and I would've loved to spend it with you.\n";
    cout << "Luckily, next weekend is not far away, and we will meet again.\n";
    cout << "I am sure we will find something fun to do, like swimming, hiking or biking,\n";
    cout << "and maybe going out into the city in the evening.\n";
    cout << "I really look forward to seeing you again.\n";

    /// 3.
    cout << "Enter the name of another friend (followed by 'enter'):\n";
    string friend_name;
    cin >> friend_name;
    cout << "Have you seen " << friend_name << " lately?\n";

    /// 4.
    char friend_sex = 0;
    cout << "Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):\n";
    cin >> friend_sex;
    if ('m' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask him to call me.\n";
    }
    else if ('f' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask her to call me.\n";
    }

    /// 5.
    cout << "Enter the age of the recipient (followed by 'enter'):\n";
    int age;
    cin >> age;
    cout << "I hear you just had a birthday and you are " << age << " years old.\n";
    if (0 >= age || 110 <= age)
    {
        simple_error("you're kidding!");
    }

    /// 6.
    if (12 > age)
    {
        cout << "Next year you will be " << age+1 << ".\n";
    }
    if (17 == age)
    {
        cout << "Next year you will be able to vote.\n";
    }
    if (70 < age)
    {
        cout << "I hope you are enjoying retirement.\n";
    }


    return 0;

}

Here is the output if the friend is under 12:

Enter the age of the recipient (followed by 'enter'):
1
I hear you just had a birthday and you are 1 years old.
Next year you will be 2.

Here is the output if the friend is 17:

Enter the age of the recipient (followed by 'enter'):
17
I hear you just had a birthday and you are 17 years old.
Next year you will be able to vote.

Here is the output if the friend is over 70:

Enter the age of the recipient (followed by 'enter'):
71
I hear you just had a birthday and you are 17 years old.
I hope you are enjoying retirement.
  1. Add “Yours sincerely,” followed by two blank lines for a signature, followed by your name.
letterform07.cpp
// read and write a first name
#include "std_lib_facilities.h"

int main() {
    cout << "Enter the name of the person you want to write to (followed by 'enter'):\n";
    string first_name; // first_name is a variable of type string
    cin >> first_name; // read characters into first_name
    cout << "Dear " << first_name << ",\n";

    /// 2.
    cout << "\tHow are you? I am fine. I miss you.\n";
    cout << "I hope you had a nice day and I would've loved to spend it with you.\n";
    cout << "Luckily, next weekend is not far away, and we will meet again.\n";
    cout << "I am sure we will find something fun to do, like swimming, hiking or biking,\n";
    cout << "and maybe going out into the city in the evening.\n";
    cout << "I really look forward to seeing you again.\n";

    /// 3.
    cout << "Enter the name of another friend (followed by 'enter'):\n";
    string friend_name;
    cin >> friend_name;
    cout << "Have you seen " << friend_name << " lately?\n";

    /// 4.
    char friend_sex = 0;
    cout << "Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):\n";
    cin >> friend_sex;
    if ('m' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask him to call me.\n";
    }
    else if ('f' == friend_sex)
    {
        cout << "If you see " << friend_name << " please ask her to call me.\n";
    }

    /// 5.
    cout << "Enter the age of the recipient (followed by 'enter'):\n";
    int age;
    cin >> age;
    cout << "I hear you just had a birthday and you are " << age << " years old.\n";
    if (0 >= age || 110 <= age)
    {
        simple_error("you're kidding!");
    }

    /// 6.
    if (12 > age)
    {
        cout << "Next year you will be " << age+1 << ".\n";
    }
    if (17 == age)
    {
        cout << "Next year you will be able to vote.\n";
    }
    if (70 < age)
    {
        cout << "I hope you are enjoying retirement.\n";
    }

    /// 7.
    cout << "Yours sincerely,\n\n\n";
    cout << "Franz\n";


    return 0;

}

This code produces:

Enter the name of the person you want to write to (followed by 'enter'):
Pia
Dear Pia,
    How are you? I am fine. I miss you.
I hope you had a nice day and I would've loved to spend it with you.
Luckily, next weekend is not far away, and we will meet again.
I am sure we will find something fun to do, like swimming, hiking or biking,
and maybe going out into the city in the evening.
I really look forward to seeing you again.
Enter the name of another friend (followed by 'enter'):
Sebastian
Have you seen Sebastian lately?
Enter an 'm' if the friend is male and and 'f' if the friend is female (followed by 'enter'):
m
If you see Sebastian please ask him to call me.
Enter the age of the recipient (followed by 'enter'):
29
I hear you just had a birthday and you are 29 years old.
Yours sincerely,


Franz

Process finished with exit code 0

Review

  1. What is meant by the term prompt?

A line of code that writes out a message to the screen (terminal, console, …) which encourages or prompts the user to take action.

int main()
{
  cout << "Please enter your first name (followed by 'enter'):\n"; // Prompt the user to take action
  string first_name; // first_name is a variable of type
  string cin >> first_name; // read characters into first_name
  cout << "Hello, " << first_name << "!\n";
}
  1. Which operator do you use to read into a variable?

The operator to read from an input (such as the keyboard) into a variable is called the right shift operator >>:

string first_name; // first_name is a variable of type string
cin >> first_name; // read characters into first_name
  1. If you want the user to input an integer value into your program for a variable named number, what are two lines of code you could write to ask the user to do it and to input the value into your program?
cout << "Please input an integer value (followed by 'enter'):\n"; // Prompt the user to take action
int number;  // It could also be assumed that the variable number was declared before, which would make this line obsolet.
cin >> number; // Read the value from the user input into the variable named number.
  1. What is \n called and what purpose does it serve?

This is a special whitespace character and is another name for newline (“end of line”) in an output output:

cout << "This scentence is written over\n two lines.\n";
  1. What terminates input into a string?

A so called whitespace character. By convention, reading of strings is terminated by what is called whitespace, that is, space, newline, and tab characters. Otherwise, whitespace by default is ignored by >>. For example, you can add as many spaces as you like before a number to be read; >> will just skip past them and read the number.

  1. What terminates input into an integer?

A whitespace character or an input that is not an integer.

  1. How would you write
cout << "Hello, ";
cout << first_name;
cout << "!\n";

as a single line of code?

  1. What is an object?

An object is a region of memory that holds a value of a given type that specifies what kind of information can be placed in it.

  1. What is a literal?

Literals represent values of various types. For example, the literal 12 represents the integer value “twelve”, “Morning” represents the character string value Morning, and true represents the Boolean value true.

  1. What kinds of literals are there?

Integer literals come in three varieties:

  • Decimal: a series of decimal digits Decimal digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9
  • Octal: a series of octal digits starting with 0 Octal digits: 0, 1, 2, 3, 4, 5, 6, and 7
  • Hexadecimal: a series of hexadecimal digits starting with 0x or 0X Hexadecimal digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, A, B, C, D, E, and F
  • Binary: a series of binary digits starting with 0b or 0B (C++14) Binary digits: 0, 1

A suffix u or U makes an integer literal unsigned (§25.5.3), and a suffix l or L makes it long, for example, 10u and 123456UL.

A floating-point-literal contains a decimal point (.), an exponent (e.g., e3), or a floating-point suffix (d or f). For example:

123 // int (no decimal point, suffix, or exponent)
123. // double: 123.0
123.0 // double
123   // double
0.123 // double: 0.123
1.23e3 // double: 1230.0
1.23e–3 // double: 0.00123
1.23e+3 // double 1230.0

Floating-point-literals have type double unless a suffix indicates otherwise. For example:

1.23 // double
1.23f // float
1.23L // long double

The literals of type bool are true and false. The integer value of true is 1 and the integer value of false is 0.

A character literal is a character enclosed in single quotes, for example, ‘a’ and ‘@’. In addition, there are some “special characters”:

Name ASCII name C++ name
newline NL n
horizontal tab HT t
vertical tab VT v
backspace BS b
carriage return CR r
form feed FF f
alert BEL a
backslash
question mark ? ?
single quote
double quote
octal number ooo ooo
hexadecimal number hhh xhhh

A special character is represented as its “C++ name” enclosed in single quotes, for example, '\n' (newline) and '\t' (tab).

The character set includes the following visible characters:

abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
!@#$%^&*()_+|~`{ } [ ] :";'< > ?,./

The value of a character, such as 'a' for a, is implementation dependent (but easily discovered, for example, cout << int('a')).

A string literal is a series of characters enclosed in double quotes, for example, “Knuth” and “King Canute”. A newline cannot be part of a string; instead use the special character \n to represent newline in a string:

"King
Canute " // error: newline in string literal
"King\nCanute" // OK: correct way to get a newline into a string literal

There is only one pointer literal: the null pointer, nullptr. For compatibility, any constant expression that evaluates to 0 can also be used as the null pointer.

For example:

t* p1 = 0; // OK: null pointer
int* p2 = 2–2; // OK: null pointer
int* p3 = 1; // error: 1 is an int, not a pointer
int z = 0;
int* p4 = z; // error: z is not a constant although it is set to zero initially

The value 0 is implicitly converted to the null pointer.

  1. What is a variable?

A named object is called a variable. For example, character strings are put into string variables and integers are put into int variables.

  1. What are typical sizes for a char, an int, and a double?

Every int is of the same size; that is, the compiler sets aside the same fixed amount of memory for each int. On a typical desktop computer, that amount is 4 bytes (32 bits). Similarly, bools, chars, and doubles are fixed size. You’ll typically find that a desktop computer uses a byte (8 bits) for a bool or a char and 8 bytes for a double. Note that different types of objects take up different amounts of space. In particular, a char takes up less space than an int, and string differs from double, int, and char in that different strings can take up different amounts of space.

  1. What measures do we use for the size of small entities in memory, such as ints and strings?

For ints we use usually 4 bytes which are 32 bits. A string is of variable size with its length stored and made up of single characters that require each 1 byte of memory.

  1. What is the difference between = and ==?

= is the assignment operator which assigns a value to variable and is also used to initialize a variable.

== is the equality operator which yields a bool (true or false, 1 or 0) by comparing two objects.

  1. What is a definition?

A definition is a declaration that sets aside memory for an object.

  1. What is an initialization and how does it differ from an assignment?

The assignment operator, represented as = gives a variable a new value. For example:

int a = 3; // a starts out with the value 3
a = 4;     // a gets the value 4 (“becomes 4”)
int b = a; // b starts out with a copy of a’s value (that is, 4)
b = a+5;   // b gets the value a+5 (that is, 9)
a = a+7;   // a gets the value a+7 (that is, 11)

Above, we use “starts out with” and “gets” to distinguish two similar, but logically distinct, operations:

  • Initialization (giving a variable its initial value)
  • Assignment (giving a variable a new value)

These operations are so similar that C++ allows us to use the same notation (the =) for both:

int y = 8;     // initialize y with 8
x = 9;         // assign 9 to x

string t = "howdy!";  // initialize t with “howdy!”
s = "G'day";          // assign “G’day” to s

However, logically assignment and initialization are different. You can tell the two apart by the type specification (like int or string) that always starts an initialization; an assignment does not have that. In principle, an initialization always finds the variable empty. On the other hand, an assignment (in principle) must clear out the old value from the variable before putting in the new value.

  1. What is string concatenation and how do you make it work in C++?

For strings + means concatenation; that is, when s1 and s2 are strings, s1+s2 is a string where the characters from s1 are followed by the characters from s2. For example, if s1 has the value "Hello" and s2 the value "World", then s1+s2 will have the value "HelloWorld".

  1. Which of the following are legal names in C++? If a name is not legal, why not?
This_little_pig latest thing MiniMineMine
This_1_is fine the_$12_method number
2_For_1_special _this_is_ok correct?

In a C++ program, a name starts with a letter and contains only letters, digits, and underscores.

For example:

x
number_of_elements
Fourier_transform
z2
Polygon

Therefore the following are not names:

the_$12_method  // $ is not a letter, digit, or underscore
2_For_1_special // a name must start with a letter
correct?        // ? is not a letter, digit, or underscore

The _this_is_ok is also a legal name, however, variables beginning with an underscore are reserved for implementation and system entities and should therefore not be used in production code. If you read system code or machine-generated code, you might see names starting with underscores, such as _foo. Never write those yourself; such names are reserved for implementation and system entities. By avoiding leading underscores, you will never find your names clashing with some name that the implementation generated.

  1. Give five examples of legal names that you shouldn’t use because they are likely to cause confusion.

Names are case sensitive; that is, uppercase and lowercase letters are distinct, so x and X are different names. However, it is not a good idea to use the following names because a programmer can get confused with names from the standard library:

int String = 2; // Similar to string
double Int = 1.2; // Similar to int
double Double = 1.2; // Similar to doulbe

You can use names of facilities in the standard library, such as string, but you shouldn’t. Reuse of such a common name will cause trouble if you should ever want to use the standard library:

int string = 7; // Possible but will lead to trouble when using std::string

The C++ language reserves many (about 85) names as “keywords.” Using variable names that are similar to those can also be confusing:

int Static = 42;

Avoid names that are easy to mistype, misread, or confuse. For example:

Name names nameS foo f00 fl
f1 fI fi

The characters 0 (zero), o (lowercase O), O (uppercase o), 1 (one), I (uppercase i), and l (lowercase L) are particularly prone to cause trouble.

  1. What are some good rules for choosing names?

When you choose names for your variables, functions, types, etc., choose meaningful names; that is, choose names that will help people understand your program. Don’t use variables with “easy to type” names like x1, x2, s3, and p7. Abbreviations and acronyms can confuse people, so use them sparingly.

Short names, such as x and i, are meaningful when used conventionally; that is, x should be a local variable or a parameter (see §4.5 and §8.4) and i should be a loop index (see §4.4.2.3).

Don’t use overly long names; they are hard to type, make lines so long that they don’t fit on a screen, and are hard to read quickly.

C++ implementations use underscores to separate words in an identifier, such as element_count, rather than alternatives, such as elementCount and ElementCount. C++ never uses names with all capital letters, such as ALL_CAPITAL_LETTERS, because that’s conventionally reserved for macros (§27.8 and §A.17.2).

We should use an initial capital letter for types we define, such as Square and Graph or following the MISRA C style: c prefix for classes and s prefix for structs. The C++ language and standard library don’t use the initial-capital-letter style, so it’s int rather than Int and string rather than String. Thus, our convention helps to minimize confusion between our types and the standard ones.

  1. What is type safety and why is it important?

Every object is given a type when it is defined. A program — or a part of a program — is type-safe when objects are used only according to the rules for their type. Unfortunately, there are ways of doing operations that are not type-safe. For example, using a variable before it has been initialized is not considered type-safe

int main()
{
    double x; // we “forgot” to initialize:
              // the value of x is undefined
    double y = x; // the value of y is undefined
    double z = 2.0+x; // the meaning of + and the value of z are undefined
}

An implementation is even allowed to give a hardware error when the uninitialized x is used. Always initialize your variables! There are a few — very few — exceptions to this rule, such as a variable we immediately use as the target of an input operation.

  1. Why can conversion from double to int be a bad thing?

On a typical desktop computer architecture double has a fixed memory amount of 8 bytes (64 bits). An int on the other hand the compiler sets aside the same fixed amount of memory, which is 4 bytes (32 bits) on most architectures. To convert a double to an int a narrowing conversion is required where information can get lost, which describes an unsafe conversion. A conversion is said to be safe if the destination type can hold the value of the source type without loosing information.

#include <iostream>

int main()
{
    double d = 100;
    int i = d;     // implicit safe conversion
    double dd = i;
    if (d == dd)
        cout << "No loss of information\n";
}
#include <iostream>
#include <iomanip>

int main()
{
    double d = 4294967296/2-1; // 2^32 = 4294967296, 2^32/2 = 2^31 = 2147483648
    //double d = 2147483648-1; // 2^32 = 4294967296, 2^32/2 = 2^31 = 2147483648

    int i = d;     // implicit safe conversion
    double dd = i;

    if (d == dd)
        std::cout << "Safe conversion: d == dd, with d == " << std::fixed << d << "; i == " << i << "\n";
    else
        std::cout << "Unsafe conversion: d == " << std::fixed << d << "; dd == " << std::fixed << dd << "; i == " << i << "\n";
}

This gives the output:

Safe conversion: d == dd, with d == 2147483647

Without std::fixed from the iomanip header, the output of d would be rounded:

Safe conversion: d == dd, with d == 2.14748e+09; i == 2147483647

One case where information gets lost with these types, is when the value of the double variable is too large to fit into the int.

The following example shows an unsafe conversion from double to int. Notice that int ranges from -2^31 to 2^31-1.

#include <iostream>
#include <iomanip>

int main()
{
    double d = 4294967296/2; // 2^32 = 4294967296, 2^32/2 = 2^31 = 2147483648
    //double d = 2147483648-1; // 2^32 = 4294967296, 2^32/2 = 2^31 = 2147483648

    int i = d;     // implicit unsafe conversion
    double dd = i;

    if (d == dd)
        std::cout << "Safe conversion: d == dd, with d == " << std::fixed << d << "; i == " << i << "\n";
    else
        std::cout << "Unsafe conversion: d == " << std::fixed << d << "; dd == " << std::fixed << dd << "; i == " << i << "\n";
}

The output is:

Unsafe conversion: d == 2147483648.000000; dd == -2147483648.000000; i == -2147483648

They are unsafe in the sense that the value stored might differ from the value assigned.

Another case where an unsafe conversion happens, is when the double variable stores a floating-point value and is converted to an int.

double x = 2.7; // lots of code
int y = x; // y becomes 2

a double-to-int conversion truncates (always rounds down, toward zero) rather than using the conventional 4/5 rounding. What happens is perfectly predictable, but there is nothing in the int y = x; to remind us that information (the .7) is thrown away.

  1. Define a rule to help decide if a conversion from one type to another is safe or unsafe.

A conversion is unsafe if the amount of memory reserved for the destination type is less than the memory reserved for the source type or if a floating-point type is converted to a fixed-point type (with a scaling factor of 1 for the fixed-point number). Such conversion lead to a loss of information where the value is narrowed. A value can be implicitly turned into a value of another type that does not equal the original value.

Safe conversions happen when the source type reserves less memory than the destination type. Safe conversions are:

bool to char
bool to int
bool to double
char to int
char to double
int to double

All of the following conversions are unsafe although they are accepted by the compiler:

double to int
double to char
double to bool
int to char

They are unsafe in the sense that the value stored might differ from the value assigned.

Terms

assignment

An assignment is an operator, denoted by the = sign. This operator assings a new value to a variable. For example:

int a = 3; // a starts out with the value 3
a = 4; // a gets the value 4 (“becomes 4”)
int b = a; // b starts out with a copy of a’s value (that is, 4)
b = a+5; // b gets the value a+5 (that is, 9) a:
a = a+7; // a gets the value a+7 (that is, 11)

That last assignment deserves notice. First of all it clearly shows that = does not mean equals — clearly, a doesn’t equal a+7. It means assignment, that is, to place a new value in a variable. What is done for a=a+7 is the following:

  1. First, get the value of a; that’s the integer 4.
  2. Next, add 7 to that 4, yielding the integer 11.
  3. Finally, put that 11 into a.

cin

The name cin refers to the standard input stream (pronounced “see-in,” for “character input”) defined in the standard library. It is used to read characters from input (keyboard) into a variable:

string first_name;
cin >> first_name; // read characters into variable first_name

It is used in combination with the right shift operator >> where the second operand specifies where the (keyboard) input goes.

concatenation

For strings + means concatenation; that is, when s1 and s2 are strings, s1+s2 is a string where the characters from s1 are followed by the characters from s2. For example, if s1 has the value "Hello" and s2 the value "World", then s1+s2 will have the value "HelloWorld".

conversion

Conversion means to convert one type to another where a possible loss of information is possible. Because of this, conversions can be categorized to be safe and unsafe.

Safe conversion means that a type which requires less memory than another one, can be converted to that type and back without loss of information. For example, a char, which usually requires one byte of of memory, can be converted to an int, which is usually made up of four bytes and back again. The twice converted value will be the same as the original one.

char c = 'x';
int i1 = c;
int i2 = 'x';

// i1 == i2

Here both i1 and i2 the the same value 120. The following are safe conversions for standard types:

bool to char
bool to int
bool to double
char to int
char to double
int to double

A useful conversion is int to double because it allows us to mix ints and doubles in expressions.

(Implicit) unsafe conversion on the other hand can lose information. Unsafe means, that a value can be implicitly turned into a value of another type that does not equal the original value.

int a = 20000;
char c = a;     // try to squeeze a large int into a small char
int b = c;

// a != b

declaration

A declaration is a statement that gives a name to an object.

decrement

C++ provides a special syntax for decrementing (that is, subtracting 1 from it) a variable:

int a = 10;
a--; // post decrement
--a; // pre decrement

Both decrement operators result in a = a - 1;. Post and pre decrement are useful, for example, when indexing arrays.

definition

A definition is a declaration that sets aside memory for an object.

increment

Incrementing a variable (that is, adding 1 to it) is so common in programs that C++ provides a special syntax for it. For example:

++counter

means

counter = counter + 1

There are many other common ways of changing the value of a variable based on its current value. For example, we might like to add 7 to it, to subtract 9, or to multiply it by 2. Such operations are also supported directly by C++. For example:

a += 7; // means a = a+7
b –= 9; // means b = b–9
c *= 2; // means c = c*2

In general, for any binary operator oper, a oper= b means a = a oper b. For starters, that rule gives us operators +=, –=, *=, /=, and %=. This provides a pleasantly compact notation that directly reflects our ideas. For example, in many application domains *= and /= are referred to as “scaling.”

initialization

An initialization gives a variable its initial value. Assignments are similar to initialization which is illustrated in the following example:

string a = "alpha"; // a starts out with the value “alpha” a: alpha
a = "beta"; // a gets the value “beta” (becomes “beta”) a: beta
string b = a; // b starts out with a copy of a’s value (that is, “beta”)
b = a+"gamma"; // b gets the value a+“gamma” (that is, “betagamma”)
a = a+"delta"; // a gets the value a+“delta” (that is, “betadelta”)

Above, we use “starts out with” and “gets” to distinguish two similar, but logically distinct, operations:

  • Initialization (giving a variable its initial value)
  • Assignment (giving a variable a new value)

These operations are so similar that C++ allows us to use the same notation (the =) for both:

int y = 8; // initialize y with 8
x = 9;  // assign 9 to x
string t = "howdy!"; // initialize t with “howdy!”
s = "G'day";  // assign “G’day” to s

However, logically assignment and initialization are different. You can tell the two apart by the type specification (like int or string) that always starts an initialization; an assignment does not have that. In principle, an initialization always finds the variable empty. On the other hand, an assignment (in principle) must clear out the old value from the variable before putting in the new value.

name

We name our variables so that we can remember them and refer to them from other parts of a program. In a C++ program, a name starts with a letter and contains only letters, digits, and underscores.

x
number_of_elements
Fourier_transform
z2
Polygon

The following are not names:

2x              // a name must start with a letter
time$to$market  // $ is not a letter, digit, or underscore
Start menu      // space is not a letter, digit, or underscore

When we say “not names,” we mean that a C++ compiler will not accept them as names. If you read system code or machine-generated code, you might see names starting with underscores, such as _foo. Never write those yourself; such names are reserved for implementation and system entities. By avoiding leading underscores, you will never find your names clashing with some name that the implementation generated. Names are case sensitive; that is, uppercase and lowercase letters are distinct, so x and X are different names.

narrowing

Unsafe conversions are also called “narrowing” conversions, because they put a value into an object that may be too small (“narrow”) to hold it.

object

An object is some memory that holds a value of a given type.

operation

The type of a variable determines what operations we can apply to it and what they mean. For example:

int count; // >> reads an integer into count
cin >> count;
string name;
cin >> name; // >> reads a string into name
int c2 = count+2; // + adds integers
string s2 = name + " Jr. "; // + appends characters
int c3 = count–2; // – subtracts integers
string s3 = name – " Jr. "; // error: – isn’t defined for strings

By “error” we mean that the compiler will reject a program trying to subtract strings. The compiler knows exactly which operations can be applied to each variable and can therefore prevent many mistakes.

operator

An operator is a function that has one ore two operands of the same or possibly different type, which yields a result.

https://en.cppreference.com/w/cpp/language/operators

type

An object is described by a type which specifies what kind of information can be placed into that object. Put another way, a type specifies how a region of memory, describing that object, should be interpreted.

Consider the following named object (variable):

int a = 42;

The type of the variable a is int which is suitable to describe the integer value 42.

It is not possible to put values of the wrong type into a variable:

string name2 = 39; // error: 39 isn’t a string
int number_of_steps = "Annemarie"; // error: “Annemarie” is not an int

Here are the five most important types:

int number_of_steps = 39;  // int for integers
double flying_time = 3.5;  // double for floating-point numbers
char decimal_point = '.';  // char for individual characters
string name = "Annemarie"; // string for character strings
bool tap_on = true;        // bool for logical variables

Note that each of these types has its own characteristic style of literals.

In addition to specifying what values can be stored in a variable, the type of a variable determines what operations we can apply to it and what they mean. Check the example of the term operation.

typesafety

Every object is given a type when it is defined. A program — or a part of a program — is type-safe when objects are used only according to the rules for their type. Unfortunately, there are ways of doing operations that are not type-safe. For example, using a variable before it has been initialized is not considered type-safe:

int main() {
  double x; // we “forgot” to initialize:
            // the value of x is undefined
  double y = x; // the value of y is undefined
  double z = 2.0+x; // the meaning of + and the value of z are undefined
}

value

A value is a set of bits in memory interpreted according to a type.

variable

A variable is a named object.

Try This

Name and Age

Get the “name and age” example to run. Then, modify it to write out the age in months: read the input in years and multiply (using the * operator) by 12. Read the age into a double to allow for children who can be very proud of being five and a half years old rather than just five.

.

Operators

Get this little program to run. Then, modify it to read an int rather than a double. Note that sqrt() is not defined for an int so assign n to a double and take sqrt() of that. Also, “exercise” some other operations. Note that for ints / is integer division and % is remainder (modulo), so that 5/2 is 2 (and not 2.5 or 3) and 5%2 is 1. The definitions of integer *, /, and % guarantee that for two positive ints a and b we have a/b * b + a%b == a.

.

Repeated Words

Execute this program yourself using a piece of paper. Use the input The cat cat jumped. Even experienced programmers use this technique to visualize the actions of small sections of code that somehow don’t seem completely obvious.

Line previous current current == equal
6 ” “ “The” false
10 “The” “The” false
6 “The” “cat” false
10 “cat” “cat” false
6 “cat” “cat” true
10 “cat” “cat” true
6 “cat” “jumped” false
10 “jumped” “jumped” false
6 “jumped” eof

Get the “repeated word detection program” to run. Test it with the sentence

She she laughed He He He because what he did did not look very very good good.

How many repeated words were there? Why? What is the definition of word used here? What is the definition of repeated word? (For example, is She she a repetition?)

The output of the program is:

repeated word: He
repeated word: He
repeated word: did
repeated word: very
^D

Process finished with exit code 0

which means that there were four repeated words according to this program. She and she are not equal here because the capitalization do not match. The program also did not get good and good. as equal because of the period at the end of the sentence. Here a word is defined to be sequence of characters that is sparated by a white-space character. A repeated word is defined to be a word that matches its previous word exactly regarding case sensitivity and its containing characters.

Exercises

Exercise 02

Write a program in C++ that converts from miles to kilometers. Your program should have a reasonable prompt for the user to enter a number of miles. Hint: There are 1.609 kilometers to the mile.

miles2kilometers.cpp
#include "std_lib_facilities.h"


int main()
{
    cout << "Enter a number of miles (followed by 'Enter'):\n";
    double miles;
    cin >> miles;
    const double kilometersToMile = 1.609;
    if (1.0 == miles)
    {
        cout << miles << " mile is equal to " << miles * kilometersToMile << " kilometers.\n";
    }
    else {
        double kilometers = miles * kilometersToMile;
        if (1.0 == kilometers) {
            cout << miles << " miles are equal to " << kilometers << " kilometer.\n";
        }
        else {
            cout << miles << " miles are equal to " << kilometers << " kilometers.\n";
        }
    }

    return 0;
}

c

Exercise 03

Write a program that doesn’t do anything, but declares a number of variables with legal and illegal names (such as int double = 0;), so that you can see how the compiler reacts.

variablenames.cpp
#include "std_lib_facilities.h"


int main()
{
    //int double = 0;
    // main.cpp:6:9: error: cannot combine with previous 'int' declaration specifier
    // main.cpp:6:16: error: expected unqualified-id

    //double int = 0;
    // main.cpp:10:12: error: cannot combine with previous 'double' declaration specifier
    // main.cpp:10:16: error: expected unqualified-id

    //double string = 0; // ok but dangerous


    //double std::string = 0;
    // main.cpp:17:17: error: definition or redeclaration of 'string' not allowed inside a function


    //int _is_this_int_ok = 1; // ok but underscore is usually reserved implementation and system entities

    //double 2x = 4;  // a name must start with a letter
    // main.cpp:23:12: error: expected unqualified-id

    //int time$to$market = 5; // gives no error although $ is not a letter, digit or underscore.
    // no error with clan but could give errors on other compilers

    //int start menu = 2; // space is not a letter, digit, or underscore
    // main.cpp:29:14: error: expected ';' at end of declaration

    //char correct? = 'c'; // ? is not a letter, digit, or underscore
    // main.cpp:32:17: error: expected ';' at end of declaration

    // The following are all legal names, which start
    // with a letter and contains only letters, digits, and underscores.
    double x;

    int number_of_elements;

    double Fourier_transform;

    double z2;

    char Polygon;

    return 0;
}

c

Exercise 04

Write a program that prompts the user to enter two integer values. Store these values in int variables named val1 and val2. Write your program to determine the smaller, larger, sum, difference, product, and ratio of these values and report them to the user.

val1val2.cpp
#include "std_lib_facilities.h"


int main()
{
    cout << "Enter two integer values (followed by 'Enter')\n";
    int val1, val2;
    cin >> val1 >> val2;

    int smaller, larger;
    bool same = false;
    if (val1 < val2)
    {
        smaller = val1;
        larger = val2;
    } else {
        //if (val1 == val2)
        //{
        //    same = true;
        //}
        smaller = val2;
        larger = val1;
    }

    int sum = val1 + val2;
    int difference = val1 - val2;
    int product = val1 * val2;
    int ratio = val1/val2;

    cout << "smaller = " << smaller << "\n"
        << "larger = " << larger  << "\n"
        << "sum = " << sum << "\n"
        << "difference = " << difference << "\n"
        << "product = " << product << "\n"
        << "ratio = " << ratio << "\n";

    return 0;
}

The output of this program is:

Enter two integer values (followed by 'Enter')
2 3
smaller = 2
larger = 3
sum = 5
difference = -1
product = 6
ratio = 0

Note that the ratio is zero because the values after the decimal point are truncated when using int.

Enter two integer values (followed by 'Enter')
3 2
smaller = 2
larger = 3
sum = 5
difference = 1
product = 6
ratio = 1
Enter two integer values (followed by 'Enter')
3 3
smaller = 3
larger = 3
sum = 6
difference = 0
product = 9
ratio = 1

Exercise 05

Modify the program from exercise 04 to ask the user to enter floating-point values and store them in double variables. Compare the outputs of the two programs for some inputs of your choice. Are the results the same? Should they be? What’s the difference?

val1val2float.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "Enter two double values (followed by 'Enter')\n";
    double val1, val2;
    cin >> val1 >> val2;

    double smaller, larger;
    bool same = false;
    if (val1 < val2)
    {
        smaller = val1;
        larger = val2;
    } else {
        //if (val1 == val2)
        //{
        //    same = true;
        //}
        smaller = val2;
        larger = val1;
    }

    double sum = val1 + val2;
    double difference = val1 - val2;
    double product = val1 * val2;
    double ratio = val1/val2;

    cout << "smaller = " << smaller << "\n"
        << "larger = " << larger  << "\n"
        << "sum = " << sum << "\n"
        << "difference = " << difference << "\n"
        << "product = " << product << "\n"
        << "ratio = " << ratio << "\n";

    return 0;
}

This program outpus the following:

Enter two double values (followed by 'Enter')
2 3
smaller = 2
larger = 3
sum = 5
difference = -1
product = 6
ratio = 0.666667

The ratio is different between this and the program of exercise 04, because floating-point values are not truncated when using double instead of int.

Enter two double values (followed by 'Enter')
3 2
smaller = 2
larger = 3
sum = 5
difference = 1
product = 6
ratio = 1.5
Enter two double values (followed by 'Enter')
3 3
smaller = 3
larger = 3
sum = 6
difference = 0
product = 9
ratio = 1

Exercise 06

Write a program that prompts the user to enter three integer values, and then outputs the values in numerical sequence separated by commas. So, if the user enters the values 10 4 6, the output should be 4, 6, 10. If two values are the same, they should just be ordered together. So, the input 4 5 4 should give 4, 4, 5.

sort.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "Enter three integer values (followed by 'Enter')\n";
    int val1, val2, val3;
    cin >> val1 >> val2 >> val3;

    int smallest, middle, largest;

    if (val1 < val2)
    {
        smallest = val1;
        largest = val2;
    } else {
        smallest = val2;
        largest = val1;
    }
    
    // Put val3 in the correct place
    if (val3 <= smallest)
    {
        middle = smallest;
        smallest = val3;
    }
    else if (smallest < val3 && val3 < largest)
    {
        middle = val3;
    }
    else if (largest <= val3)
    {
        middle = largest;
        largest = val3;
    }

    cout << smallest << ", " << middle << ", " << largest << "\n";

    return 0;
}

Here are some outputs of the program:

Enter three integer values (followed by 'Enter')
10 4 6
4, 6, 10
Enter three integer values (followed by 'Enter')
3 2 1
1, 2, 3
Enter three integer values (followed by 'Enter')
1 2 1
1, 1, 2
Enter three integer values (followed by 'Enter')
4 5 4
4, 4, 5

Exercise 07

Do exercise 6, but with three string values. So, if the user enters the values Steinbeck, Hemingway, Fitzgerald, the output should be Fitzgerald, Hemingway, Steinbeck.

sortstrings.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "Enter three strings (followed by 'Enter')\n";
    string str1, str2, str3;
    cin >> str1 >> str2 >> str3;

    string smallest, middle, largest;

    if (str1 < str2)
    {
        smallest = str1;
        largest = str2;
    } else {
        smallest = str2;
        largest = str1;
    }
    
    // Put str3 in the correct place
    if (str3 <= smallest)
    {
        middle = smallest;
        smallest = str3;
    }
    else if (smallest < str3 && str3 < largest)
    {
        middle = str3;
    }
    else if (largest <= str3)
    {
        middle = largest;
        largest = str3;
    }

    cout << smallest << ", " << middle << ", " << largest << "\n";

    return 0;
}

The output results in:

Enter three strings (followed by 'Enter')
Steinbeck Hemingway Fitzgerald
Fitzgerald, Hemingway, Steinbeck

Exercise 08

Write a program to test an integer value to determine if it is odd or even. As always, make sure your output is clear and complete. In other words, don’t just output yes or no. Your output should stand alone, like The value 4 is an even number. Hint: See the remainder (modulo) operator in §3.4.

oddeven.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "Enter an integer value (followed by 'Enter')\n";
    int val;
    cin >> val;

    if (0 == val % 2)
    {
        cout << "The value " << val << " is even.\n";
    }
    else
    {
        cout << "The value " << val << " is odd.\n";
    }

    return 0;
}

The output using 2 as input is:

Enter an integer value (followed by 'Enter')
2
The value 2 is even.
Enter an integer value (followed by 'Enter')
3
The value 3 is odd.

0 results in:

Enter an integer value (followed by 'Enter')
0
The value 0 is even.

Negativ values result in:

Enter an integer value (followed by 'Enter')
-1
The value -1 is odd.
Enter an integer value (followed by 'Enter')
-2
The value -2 is even.
Enter an integer value (followed by 'Enter')
-3
The value -3 is odd.

Exercise 09

Write a program that converts spelled-out numbers such as “zero” and “two” into digits, such as 0 and 2. When the user inputs a number, the program should print out the corresponding digit. Do it for the values 0, 1, 2, 3, and 4 and write out not a number I know if the user enters something that doesn’t correspond, such as stupid computer!.

spelledoutnumbers.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "Enter a number from 0 to 4 as a string, e.g. 'zero' (followed by 'Enter')\n";
    string val;
    cin >> val;

    int digit = -1;
    if ("zero" == val)
    {
        digit = 0;
    }
    else if ("one" == val)
    {
        digit = 1;
    }
    else if ("two" == val)
    {
        digit = 2;
    }
    else if ("three" == val)
    {
        digit = 3;
    }
    else if ("four" == val)
    {
        digit = 4;
    }

    if (-1 != digit)
    {
        cout << "The spelled-out number " << val << " corresponds to " << digit << ".\n";
    }
    else
    {
        cout << "not a number I know\n";
    }
        
    return 0;
}

Here are some example input and outputs:

Enter a number from 0 to 4 as a string, e.g. 'zero' (followed by 'Enter')
one
The spelled-out number one corresponds to 1.
Enter a number from 0 to 4 as a string, e.g. 'zero' (followed by 'Enter')
five
not a number I know

Exercise 10

Write a program that takes an operation followed by two operands and outputs the result. For example:

+ 100 3.14
* 4 5

Read the operation into a string called operation and use an if-statement to figure out which operation the user wants, for example, if (operation=="+"). Read the operands into variables of type double. Implement this for operations called +, –, *, /, plus, minus, mul, and div with their obvious meanings.

polishnotationcalculator.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "Enter an operation ('+','-','*','/','plus','minus','mul','div') followed by two operands (followed by 'Enter')\n";
    string operation;
    double op1, op2;
    cin >> operation >> op1 >> op2;
    
    double result = 0;
    if (operation == "+" || operation == "plus")
    {
        result = op1 + op2;
    }
    else if (operation == "-" || operation == "minus")
    {
        result = op1 - op2;
    }
    else if (operation == "*" || operation == "mul")
    {
        result = op1 * op2;
    }
    else if (operation == "/" || operation == "div")
    {
        result = op1 / op2;
    }
    
    cout << "The result of " << op1 << " " << operation << " " << op2 << " is " << result << "\n";
        
    return 0;
}

Here are some example inputs and the results:

Enter an operation ('+','-','*','/','plus','minus','mul','div') followed by two operands (followed by 'Enter')
+ 5.5 2
The result of 5.5 + 2 is 7.5
Enter an operation ('+','-','*','/','plus','minus','mul','div') followed by two operands (followed by 'Enter')
mul 5 2.1
The result of 5 mul 2.1 is 10.5

Exercise 11

Write a program that prompts the user to enter some number of pennies (1-cent coins), nickels (5-cent coins), dimes (10-cent coins), quarters (25-cent coins), half dollars (50-cent coins), and one-dollar coins (100-cent coins). Query the user separately for the number of each size coin, e.g., “How many pennies do you have?” Then your program should print out something like this:

You have 23 pennies.
You have 17 nickels.
You have 14 dimes.
You have 7 quarters.
You have 3 half dollars.
The value of all of your coins is 573 cents.

I assume that the output for dollars is missing in the task above which is why I added it in my solution:

pennies.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "How many pennies do you have? (followed by 'Enter'):\n";
    int pennies;
    cin >> pennies;

    cout << "How many nickels do you have? (followed by 'Enter'):\n";
    int nickels;
    cin >> nickels;

    cout << "How many dimes do you have? (followed by 'Enter'):\n";
    int dimes;
    cin >> dimes;

    cout << "How many quarters do you have? (followed by 'Enter'):\n";
    int quarters;
    cin >> quarters;

    cout << "How many half dollars do you have? (followed by 'Enter'):\n";
    int half_dollars;
    cin >> half_dollars;

    cout << "How many dollars do you have? (followed by 'Enter'):\n";
    int dollars;
    cin >> dollars;


    int cents = pennies + nickels * 5 + dimes * 10 + quarters * 25 + half_dollars * 50 + dollars * 100;


    cout
        << "You have " << pennies << " pennies.\n"
        << "You have " << nickels << " nickels.\n"
        << "You have " << dimes << " dimes.\n"
        << "You have " << quarters << " quarters.\n"
        << "You have " << half_dollars << " half dollars.\n"
        << "You have " << dollars << " dollars.\n"
        << "The value of all of your coins is " <<  cents << " cents.\n";

    return 0;
}

The output of the above program is:

How many pennies do you have? (followed by 'Enter'):
23
How many nickels do you have? (followed by 'Enter'):
17
How many dimes do you have? (followed by 'Enter'):
14
How many quarters do you have? (followed by 'Enter'):
7
How many half dollars do you have? (followed by 'Enter'):
3
How many dollars do you have? (followed by 'Enter'):
0
You have 23 pennies.
You have 17 nickels.
You have 14 dimes.
You have 7 quarters.
You have 3 half dollars.
You have 0 dollars.
The value of all of your coins is 573 cents.

Make some improvements: if only one of a coin is reported, make the output grammatically correct, e.g., 14 dimes and 1 dime (not 1 dimes). Also, report the sum in dollars and cents, i.e., $5.73 instead of 573 cents.

penniesimproved.cpp
#include "std_lib_facilities.h"

int main()
{
    cout << "How many pennies do you have? (followed by 'Enter'):\n";
    int pennies;
    cin >> pennies;

    cout << "How many nickels do you have? (followed by 'Enter'):\n";
    int nickels;
    cin >> nickels;

    cout << "How many dimes do you have? (followed by 'Enter'):\n";
    int dimes;
    cin >> dimes;

    cout << "How many quarters do you have? (followed by 'Enter'):\n";
    int quarters;
    cin >> quarters;

    cout << "How many half dollars do you have? (followed by 'Enter'):\n";
    int half_dollars;
    cin >> half_dollars;

    cout << "How many dollars do you have? (followed by 'Enter'):\n";
    int dollars;
    cin >> dollars;


    int cents = pennies + nickels * 5 + dimes * 10 + quarters * 25 + half_dollars * 50 + dollars * 100;


    cout
        << "You have " <<  pennies;
        if (1 == pennies)
            cout << " penny.\n";
        else
            cout << " pennies.\n";

        cout << "You have " <<  nickels;
        if (1 == nickels)
            cout << " nickel.\n";
        else
            cout << " nickels.\n";

        cout << "You have " <<  dimes;
        if (1 == dimes)
            cout << " dime.\n";
        else
            cout << " dimes.\n";

        cout << "You have " <<  quarters;
        if (1 == quarters)
           cout << " quarter.\n";
        else
            cout << " quarters.\n";

        cout << "You have " <<  half_dollars;
        if (1 == half_dollars)
            cout << " half dollar.\n";
        else
            cout << " half dollars.\n";

        cout << "The value of all of your coins is $" <<  cents/100.0;

    return 0;
}

This improved program version gives the output:

How many pennies do you have? (followed by 'Enter'):
1
How many nickels do you have? (followed by 'Enter'):
1
How many dimes do you have? (followed by 'Enter'):
1
How many quarters do you have? (followed by 'Enter'):
1
How many half dollars do you have? (followed by 'Enter'):
1
How many dollars do you have? (followed by 'Enter'):
1
You have 1 penny.
You have 1 nickel.
You have 1 dime.
You have 1 quarter.
You have 1 half dollar.
The value of all of your coins is $1.91 cents.