Variables, Branching, and Loops in C++

1. Variables and their types

The variables must be declared in the code before they are used. In addition, you must specify what kind of data will be stored in each variable.

In the following code, the variable x can store an integer value. The variable dogName can store a text (text is of type std::string in C++).

#include<iostream>
int main(){
   int x;
   std::string dogName;
   x=27;
   dogName="Darcy";
   std::cout<<"x is an integer. Its content is "<<x<<"\n";
   std::cout<<"dogName is a text. Its content is "<<dogName<<"\n";
   return 0;
}

These are the most common types of variables.

  • int is used to store integers. Integers are sometimes called whole numbers and can be positive, negative, or 0.
  • long is also used to store integers. The range for long is larger than the range for int. At the time when this document was written (the year was 2022), most of the C++ compilers on 64-bit operating system will offer the range \(\left[-2^{31}, 2^{31}-1\right]\) for int and the range \(\left[-2^{63}, 2^{63}-1\right]\) for long. There are notable exceptions. One of them is 32-bit version of Raspbian operating system. On such operating system, both int and long have the same range: \(\left[-2^{31}, 2^{31}-1\right]\).
  • float is used to store decimal numbers like 2.17, -337.11.
  • double is also used to store decimal numbers. However, double offers bigger precision. Bigger precision means more decimal places and bigger range. The details are covered in the text floating point representation of decimal numbers. In the year 2022, when this document was written, on most 64-bit operating systems, the type float is stored using 32 bits, while the type float is stored using 64 bits.
  • std::string is used to store texts.
Problem 1.

In the following code the variable integerFromUser is not properly declared. Write the command that needs to be put instead of the text // ??? // in order to obtain a valid C++ source file.

#include<iostream>
int main(){
   // ??? //
   std::cin>>integerFromUser;
   long squareOfTheNumber=integerFromUser*integerFromUser;
   std::string message;
   message="The square of the inserted number is";
   std::cout<<message<<" "<<squareOfTheNumber<<"\n";
   return 0;
}

Problem 2.

In the following code the variable message was not properly declared. Write the command that needs to be put instead of the text // ??? // in order to obtain a valid C++ source.

#include<iostream>
int main(){
   long integerFromUser;
   std::cin>>integerFromUser;
   long squareOfTheNumber=integerFromUser*integerFromUser;
   // ??? //
   message="The square of the inserted number is";
   std::cout<<message<<" "<<squareOfTheNumber<<"\n";
   return 0;
}

2. Branching

Our next task is to write programs with branching. We will introduce if statement. We will explain how to use it by looking at one simple example. Assume that the user is asked to provide an integer x through the standard input. The program will check whether x is bigger than 100. If it is, then the program will print

Congratulations! You know about big numbers!

If x is not bigger than 100, then the program will print

Good enough. Try with a bigger number next time.

This is the code:

#include<iostream>
int main(){
   int x;
   std::cout<<"Insert an integer x. ";
   std::cin>>x;
   if(x>100){
      std::cout<<"Congratulations! You know about big numbers!\n";
   }
   else{
      std::cout<<"Good enough. Try with a bigger number next time.\n";
    }
    return 0;
}

Problem 3.

Write a code that calculates max{a,b} and stores the result in the variable m. Note: You are not allowed to use the function std::max.

You should only write the code that replaces the text // ??? //.

#include<iostream>
int main(){
   long a,b,m;
   std::cin>>a>>b;
   // ??? //
   std::cout<<m<<"\n";
   return 0;
}

3. Comparison operator ==

The following code checks whether the value x is equal to 17 and prints seventeen if it is.

if(x==17){
   std::cout<<"seventeen"<<"\n";
}

Warning: If you accidentally write if(x=17) with one symbol = instead of two symbols ==, then the program will compile. The command x=17 is not a bug by itself. It is an assignment operator. The variable x receives the value 17. In addition, the operation x=17 will succeed and the code will evaluate to true. Consider the following program

#include<iostream>
int main(){
   int x;
   std::cin>>x;
   if(x=17){
      std::cout<<"seventeen\n";
   }
   else{
      std::cout<<"not seventeen\n";
   }
   std::cout<<"The variable x is "<<x<<"\n";
   return 0;
}

No matter what user enters for x, the code will print

seventeen
The variable x is 17

Many compilers will actually give you warnings if you try to use single equality sign when a logical operation == is expected. However, the code will compile, and the binary will end up with a nasty bug.

4. Logical operations

The condition inside the if statement can be more complex. We can combine multiple conditions using logical operations and, or, and negation.

Negation is denoted by !. The following code will print Not seventeen.

int x=18;
if(!(x==17)){
   std::cout<<"Not seventeen\n";
}
else{
   std::cout<<"x is seventeen\n";
}

The operation and is also denoted by &&. The operation or is also denoted by ||.

In this website the symbols &&, ||, and ! will be preferred over and, or, and not.

Problem 4.

Write a code that checks whether the real number x belongs to the union of the open intervals \((5,15)\cup(95,202)\). If it does, the program should print yes. If it does not, the program should print no.

You should only write the code that replaces the text // ??? //.

#include<iostream>
int main(){
   double x;
   std::cin>>x;
   // ??? //
   return 0;
}

5. Loops

Loops are used to simplify the writing of repetitive code. Imagine that you have to print all integers in the closed interval \([3,7]\). Those who do not know how to use loops can succeed. They will write the following program:

#include<iostream>
int main(){
   std::cout<<3<<"\n";
   std::cout<<4<<"\n";
   std::cout<<5<<"\n";
   std::cout<<6<<"\n";
   std::cout<<7<<"\n";
   return 0;
}

This code is repetitive, and most of the lines look exactly the same, except for one item. That item can be handled by a variable. We will introduce the variable called counter that will initially take the value 3. Then we will have only one command std::cout<<counter<<"\n"; instead of five almost identical commands. The variable counter will then increase by 1 and the command std::cout<<counter<<"\n"; can be executed again. Although the command looks the same, it will accomplish a different outcome. Thus, the block of code

{
   std::cout<<counter<<"\n";
   counter=counter+1;
}

has to be executed several times. The block will repeat for as long as counter<8. We use the command
while (counter<8)

before the block of the code to tell the computer to keep the loop going. The loop will repeat for as long as the condition counter<8 is satisfied.

If you are transferring to C++ from some other computer language, you may be asking

Question: Can I omit the brackets and write while counter<8 instead of while (counter<8)?

The answer is No, you can not. You must write while (counter<8) and you must never write while counter<8 in C++.

The code that prints all integers from [3,7] is:

#include<iostream>
int main(){
   int counter=3;
   while (counter<8){
      std::cout<<counter<<"\n";
      counter=counter+1;
   }
   return 0;
}

Problem 5.

Create a program that reads real numbers of type double from the user input until it reads a negative number or zero. The negative number (or zero) means that the input is over. You are allowed to assume that the input from the user will contain at least one positive element. The program should calculate the maximum of the numbers provided by the user. You are not allowed to use the standard functions max and min. Your code should replace the text // ??? //

#include<iostream>
int main(){
   double x; double largestNumber;
   std::cin>>x; largestNumber=x; 
   std::cin>>x;
   while(x>0.0){
      // ??? //
      std::cin>>x;
   }
   std::cout<<largestNumber<<std::endl;
   return 0;
}

6. Scopes of variables

Once variable is declared, it can be used in the code. The variable cannot be used before it is declared. In addition, the variable cannot be used outside of the block of code in which it is declared. The block of code is the set of all commands that are between the brackets { and }. For example, the following main function has two sub-blocks. The variable x is declared in the first sub-block. It is not declared in the second, hence it cannot be used in the second block. If you try to use x in the second block, then the compiler will return an error. The compiler will refuse to make a binary.

#include<iostream>
int main(){
   {
      int x; x=27;
      std::cout<<"The content of the variable is "<<x<<"\n";
   }
   {
      int y; y=37;
      std::cout<<"The content of the variable is "<<y<<"\n";
   }
   return 0;
}

On the other hand, you could declare the variable variable x in different blocks. In those blocks, the variable x could be of different types.

#include<iostream>
int main(){
   {
      int x; x=27;
      std::cout<<"The content of the variable is "<<x<<"\n";
   }
   {
      std::string x; x="<<some funny text>>";
      std::cout<<"The content of the variable is "<<x<<"\n";
   }
   return 0;
}

If one block of code is fully within another block, then in this inner block you are allowed to use the variables declared in the outer block. You are also allowed to declare variables in the inner block with the same name. However, if you do this, then the inner block will loose the access to the variable from the outer block. Here is example:

#include<iostream>
int main(){
   int x=55;
   std::cout<<"This is the most outer block of the main function.\n";
   std::cout<<"The value of x is "<<x<<"\n";
   {
      std::cout<<"The inner block. The current value of x is "<<x<<"\n";
      std::cout<<"We will re-declare x now. \n";
      std::string x;
      x="Darcy";
      std::cout<<"The value of x is "<<x<<"\n";
   }
   std::cout<<"We are now back to the outer block.\n";
   std::cout<<"The value of x is "<<x<<"\n";
   return 0;
}

The variants of the code from above are very written quite often. They are always written by mistake. They are common cause for bugs in the programs. Nobody should write such code intentionally.

7. Practice

Problem 6.

Create a program that reads \(5\) real numbers \(a\), \(b\), \(c\), \(d\), and \(e\) from the standard input and calculates the value \[\max\{a,b\}+\min\{c,d,e\}+\max\{b,e\}.\] Your code should replace the text // ??? //

#include<iostream>
int main(){
   double a,b,c,d,e;
   double result; 
   std::cin>>a>>b>>c>>d>>e;
   // ??? //
   std::cout<<result<<"\n";
   return 0;
}

Problem 7.

Create the program that reads six real numbers \(a_{11}\), \(a_{12}\), \(a_{21}\), \(a_{22}\), \(b_1\), and \(b_2\) from the standard input and finds two real numbers \(x\) and \(y\) that are the solutions to the system \begin{eqnarray*} a_{11}x+a_{12}y&=&b_1\\ a_{21}x+a_{22}y&=&b_2. \end{eqnarray*} You are allowed to assume that the user will provide such input values that would guarantee that the system has unique solution.

Your code should replace the text // ??? // below

#include<iostream>
int main(){
    double a11, a12, a21, a22, b1, b2, x, y; 
    std::cin>>a11>>a12>>a21>>a22>>b1>>b2;
    // ??? //
    std::cout<< x<<" "<<y<<std::endl;      
    return 0;
}

Problem 8.

The user input consists of four positive integers \(m\), \(a\), \(b\), and \(c\). Determine the smallest non-negative integer \(x\) such that \[ax+b\] gives the remainder \(c\) when divided by \(m\). If such an integer \(x\) does not exist, display the message There is no such x.

Your code should replace the text // ??? // below

#include<iostream>
int main(){
    int m,a,b,c; 
    std::cin>>m>>a>>b>>c;
    // ??? //
    return 0;
}
\begin{eqnarray*} \begin{array}{|c|l|l|}\hline \mbox{Test case}&\mbox{Input}&\mbox{Output}\\ \hline 1& 17 \quad5\quad 3\quad 2 & 10 \\ \hline 2& 18 \quad2\quad 8\quad 1 &\mbox{There is no such x}\\ \hline \end{array} \end{eqnarray*}

Problem 9.

The user input consists of six positive integers \(m\), \(n\), \(a\), \(b\), \(c\), and \(d\). Determine the smallest non-negative integer \(x\) such that \[ax+b\] gives the remainder \(c\) when divided by \(m\) while for this same \(x\) the number \(ax+b\) gives the remainder \(d\) when divided by \(n\). If such an integer \(x\) does not exist, display the message There is no such x.

Your code should replace the text // ??? // below

#include<iostream>
int main(){
    int m,n,a,b,c,d; 
    std::cin >> m >> n >> a >> b >> c >> d;
    // ??? //
    return 0;
}
\begin{eqnarray*} \begin{array}{|c|l|l|}\hline \mbox{Test case}&\mbox{Input}&\mbox{Output}\\ \hline 1& 17 \quad 19 \quad 5 \quad 3 \quad 2 \quad 6 & 316 \\ \hline 2& 18 \quad 19 \quad 2 \quad 8 \quad 1 \quad 5 &\mbox{There is no such x}\\ \hline \end{array} \end{eqnarray*}

Problem 10.

Note: This problem is graded by auto-grader. The execution must produce the correct results on secret test-cases in order to receive credit. You are only allowed to use the header iostream.

The user input consists of two positive integers \(p\) and \(M\) such that \(p > 3\) and \(M > 3\). Create a program that determines the number of integers \(x\) from \(\{0\), \(1\), \(\dots\), \(M-1\}\) that satisfy \[x^5\; \% \; p = p-1.\]

Problem 11.

The user input consists of a positive integer from the interval \((0,2^{63})\). Create a program that prints the sum of digits of the number that the user provided.

Note: You are not allowed to use strings and arrays. In this problem, the auto-grader will reject your code if it contains the word string or the symbols [ and ].

Problem 12.

The user input consists of a list of integers each of which is either \(0\) or \(1\). Once the user provides the number \(2\) the input is over. You are allowed to assume that the user will provide at least two terms before typing number \(2\). The following sequence of operations is performed with the list from the input. Each operation consists of identifying the two leftmost terms that are equal. If they are both \(0\), then they are replaced with the single term equal to \(1\). If they are both equal to \(1\), then they are replaced with the single term equal to \(0\). Create the program that determines the final sequence that is obtained after repeatedly performing the described operations.

Example: Input: 1 0 1 1 0 0 1 2.

Output: 1 0 1.

Explanation: The first operation replaces the two leftmost terms \(1\) and \(1\) with \(0\). The resulting sequence is 1 0 0 0 0 1. The next operation transforms the sequence into 1 1 0 0 1 . Next the sequence becomes 0 0 0 1 . The final sequence is 1 0 1 .

Problem 13.

The user input consists of a sequence of numbers from the set \(\{1,2,3\}\) followed by the number \(-1\) that signifies the end of the input. Make the program that repeatedly performs the following operation on the entire sequence until the sequence gets transformed into one that has all terms equal:

In each step, starting from the left we identify the first two terms of the sequence that are different from each other. Then we remove these two terms and replace them by one single term that is equal to neither of the two original terms. For example \((1 2)\) is replaced by \(3\); \((2 1)\) is replaced by \(3\); \((3 2)\) is replaced by \(1\).

Example:

Input: 
1 1 1 2 3 3 1 2 2 1 3 3 -1 
Output: 
3 3 3

Explanation: The terms of the sequence are \(x_0=1\), \(x_1=1\), \(x_2=1\), \(x_3=2\), \(x_4=3\), \(x_5=3\), \(x_6=1\), \(x_7=2\), \(x_8=2\), \(x_9=1\), \(x_{10}=3\), \(x_{11}=3\). In the first step, we identify the terms \(x_2\) and \(x_3\) that are different from each other and replace them by a single term \(2\). We obtain the sequence \(1\; 1\; 3\; 3 \; 3\; 1\; 2\; 2\; 1\; 3\; 3\). This can be summarized in the following way \begin{eqnarray*} &&1\; 1\; \underbrace{1\; 2}_3\; 3\; 3 \;1\; 2\; 2\; 1\; 3\; 3 \\ &&1\; \underbrace{1\; 3}_2\; 3\; 3 \;1\; 2\; 2\; 1\; 3\; 3 \\ &&\underbrace{1\; 2}_3\; 3\; 3 \;1\; 2\; 2\; 1\; 3\; 3 \\ &&3\; 3\; \underbrace{3 \;1}_2\; 2\; 2\; 1\; 3\; 3 \\ &&3\;\underbrace{3\; 2}_1\; 2\; 2\; 1\; 3\; 3 \\ &&\underbrace{3\;1}_2\; 2\; 2\; 1\; 3\; 3 \\ &&2\; 2\;\underbrace{2\; 1}_3\; 3\; 3 \\ &&2\; \underbrace{2\;3}_1\; 3\; 3 \\ &&\underbrace{2\; 1}_3\; 3\; 3 \\ &&3\; 3\; 3 \end{eqnarray*}