[C++ Primer Plus] Chapter 5 Loops and Relational Expressions

[for loop]

for syntax

for (initialization; test-expression; update-expression){}

  1. Variables can be declared and initialized in the initialization part of the for loop.
  2. The initialization variables and for internal variables declared in the for loop only exist in the for loop process.
  3. You can modify the step size by modifying **update-expression** (you can use "," to combine two expressions into one and change two quantities at the same time).
  4. initialization and **update-expression** can be omitted. But two semicolons ";" are required.
  5. The common way in C++ is to add a space between for and the parentheses, and omit the space between the function name and the parentheses. (as do if and while)

for loop steps:

  1. Set the initial value initialization .
  2. Before the start of each loop, execute the test-expression (bool type) to determine whether the loop body is executed. (a for loop is an entry-condition loop)
  3. Perform a loop operation.
  4. At the end of each loop, update the value update-expression used for testing .
// 使用 for 循环反转字符串

#include <iostream>
#include <cstring>

int main(void)
{
    
    
    using namespace std;

    cout << "Enter a word:";
    string word;
    cin >> word;

    char temp;
    int i, j;   //代码在循环之前声明i和j,因为不能用逗号运算符将两个声明组合起来。这是因为声明已经将逗号用于其他用途—分隔列表中的变量。
    for (j=0, i=word.size()-1; j<i; --i, ++j)   // , 列表分隔符
    {
    
    
        temp = word[i];     // temp 循环结束后被丢弃
        word[i] = word[j];
        word[j] = temp;
    }
    cout << word << "\nDone\n";

    return 0;
}

[Range-based for loop]

int prices[5] = {
    
    1, 2, 3, 4, 5};
for (int x : prices)	// x 最初表示数组的第一个元素
    cout << x << endl;	// 循环显示数组中的每个值

[Some basic knowledge in C++]

The difference between i++ and ++i

  1. i++ returns the original value, ++i returns the value after adding 1.
  2. i++ cannot be an lvalue, while ++i can.
  3. The former i++ is assigned first, and then incremented; the latter ++i is incremented first, and then assigned.
  4. int i=0; a = i++; //a=0,i=1

bool type:false and true

  1. cout converts bool values ​​to int before displaying them: 0 and 1
  2. cout.setf(ios::boolalpha);This flag function instructs cout to display true and false instead of 1 and 0.
  3. The << operator has higher precedence than operators used in expressions, so the code uses parentheses to get the correct order of operations.

Output of bool type:

//bool类型的输出

#include <iostream>

int main(void)
{
    
    
    using namespace std;

    int x;
    // <<运算符的优先级比表达式中使用的运算符高, 因此代码使用括号来获得正确的运算顺序。
    cout << " (x=100)=" << (x=100) << endl; //判定赋值表达式会带来副作用, 即修改被赋值者的值。
    cout << " (x<3)=" << (x<3) << endl;     //cout在显示bool值之前将它们转换为int
    cout << " (x>3)=" << (x>3) << endl;

    for (int i=0; i<2; i++)                 //可以在for循环的初始化部分中声明和初始化变量。i只是在for循环中存在
    {
    
    
        int a = 10;                         //在for循环中声明一个其他的变量,只是在for循环中存在
        cout << "i = " << i << endl;
        cout.setf(ios_base::boolalpha);     //该标记命令cout显示true和false,而不是1和0。
        cout << " (x<3)=" << (x<3) << endl;
        cout << " (x>3)=" << (x>3) << endl;
    }
    //cout << "i = " << i << endl;          // i 消失,只是在for循环中存在
    //cout << "a = " << a << endl;          // a 消失,只是在for循环中存在

    cout << " (x<3)=" << (x<3) << endl;     //false,不知道怎么让cout再显示回int
    cout << " (x>3)=" << (x>3) << endl;

    return 0;
}
 (x=100)=100
 (x<3)=0
 (x>3)=1
i = 0
 (x<3)=false
 (x>3)=true
i = 1
 (x<3)=false
 (x>3)=true
 (x<3)=false
 (x>3)=true

Three ways to use cout

  1. Method 1: using namespae std;//using compilation directive
  2. Method 2: using std::cout;//using statement
  3. Method 3:std::cout << "Enter a number:" << std::endl;

Calculate factorial with for loop and array:

//
// 用for循环和数组计算阶乘: n!=1×2×3×...×(n-1)×n, 0!=1
//

#include <iostream>

const int ArSize = 16;  // example of external declaration

int main()
{
    
    
    long long factorials[ArSize];
    factorials[1] = factorials[0] = 1LL;    //连续赋值,从右到左
    for (int i = 2; i < ArSize; i++)
        factorials[i] = i * factorials[i-1];
    for (int i = 0; i < ArSize; i++)
        std::cout << i << "! = " << factorials[i] << std::endl;
    return 0;
}

//下面是我自己写的,哈哈哈太low了,而且很多地方没有考虑到位
//#include <iostream>
//
//int main(void)
//{
    
    
//    using namespace std;
//
//    int jiecheng=1;   //阶乘增加很快,int数值范围太小
//    int n;
//
//    cout << "Enter a number:";
//    cin  >> n;
//
//    if (n!=0)
//        for(int i=1; i<(n+1); i++)
//        {
    
    
//            jiecheng = i * jiecheng;
//        }
//    cout << n << "!=" << jiecheng << endl;
//
//    return 0;
//}

full expression

What is a complete expression? It is an expression that is not a subexpression of another larger expression.
Examples of complete expressions: expression parts in expression statements and expressions used as test conditions in while loops.

int guests = 9;
while (guests++ < 10)
    cout << guests << endl;	//output 10,while循环中检测条件是一个完整表达式,所以和10比较之后自加一存储

Example of an incomplete expression: not being a complete expression y = (4 + x++) + (6 + x++);in does not guarantee that the value of x will be incremented by 1 immediately after evaluating the subexpression 4 + x++.4 + x++

prefix suffix

  1. C++ allows you to define these operators against classes
  2. Prefix function ++i: add 1 to the value and return the result;
  3. Suffix i++: First make a copy, increment it by 1, then return the copied copy.
  4. Therefore, for classes, the prefix version is more efficient than the suffix version.

increment decrement operator and pointers

Using the increment/decrement operators on pointers will increment/decrement the value of the pointer by the number of bytes occupied by the data type it points to.

//
// Created by chaikeya on 2022/8/21.
//递增递减运算符和指针, 前缀和后缀
//
#include <iostream>

int main(void)
{
    
    
    using namespace std;

    double arr[5] = {
    
    21.1, 32.8, 23.4, 45.2, 37.4};
    double *pt = arr;   // 该语句执行完: pt = &arr[0], *pt = arr[0] = 21.1
    ++pt;               // 该语句执行完: pt = &arr[1], *pt = arr[1] = 32.8
    double x = *++pt;   // 该语句执行完: pt = &arr[2], *pt = arr[2] = 23.4, x =  arr[2] = 23.4

    ++*pt;              // 该语句执行完: pt = &arr[2], *pt = arr[2] = 23.4 + 1 = 24.4
    (*pt)++;            // 该语句执行完: pt = &arr[2], *pt = arr[2] = 24.4 + 1 = 25.4

    x = *pt++;          // 该语句执行完: pt = &arr[3], *pt = arr[3] = 25.4, x =  arr[2] = 25.4
    //后缀运算符意味着将对原来的地址(&arr[2]) 而不是递增后的新地址解除引用, 因此*pt++的值为arr[2],即25.4.

    return 0;
}

compound statement (statement block)

  1. A code block consists of a pair of curly braces and the statement they enclose, and is considered a single statement.
  2. If you define a new variable in a statement block, the variable exists only while the program executes the statements in that statement block. After the statement block is executed, the variable will be freed. This indicates that the variable is only available within that block.
  3. What if you declare a variable in a statement block and there is a variable with that name in an outer statement block? From the point of declaration to the end of the inner block, the new variable hides the old variable; then the variable is visible again.
//
// Created by chaikeya on 2022/8/21.
// 复合语句(语句块)
//
#include <iostream>

int main(void)
{
    
    
    using namespace std;

    int x = 20;             // original x

    {
    
       // block starts
        cout << x << endl;  // use original x

        int y;              // y 只存在于语句块中
        y = x++;            // 后缀运算符,y = 20, x = 21

        int x = 100;        // new x = 100
        x += 1;             // 组合赋值运算符,左=左+右
        cout << x << endl;  // use new x = 101
    }   // block ends

    cout << x << endl;      // use original x = 20
    //cout << y << endl;    // y 不存在

    return 0;
}

operator

Combining assignment operators:
The += operator adds two operands and assigns the result to the left operand. This means that the operand on the left must be assignable, such as a variable, array element, structure member, or data identified by dereferencing a pointer.

comma operator:

  1. int cats = 17, 240;// cats=17, 240 doesn't work
  2. int cats = (17, 240);// cats=240, the value of the comma expression is the value of the second part.

Relational operators: >, <, >=, <=, !=, ==,
the comparison result is a bool value, int x = (3>5);at this time x=0, and the bool value is promoted to int.
Arithmetic operators: +, -, *, /,
priority: (executed from high to low) arithmetic operators > relational operators > comma operator
x + 3 > y -2is equivalent to(x + 3) > (y -2)

C-style string comparison strcmp()

  1. strcmp() This function accepts two string addresses as parameters (the array name is an address, and the string is also an address)
  2. strcmp() The function will return zero if the two strings are the same
  3. strcmp() returns a negative (positive) number if the first string comes alphabetically before (after) the second string
// C-风格字符串的比较 strcmp()
// 该程序显示一个单词,修改其首字母,然后再次显示这个单词,这样循环往复,直到strcmp( )确定该单词与字符串“mate”相同为止。
// strcmp()该函数接受两个字符串地址作为参数(数组名是一个地址,字符串也是一个地址)
// strcmp()如果两个字符串相同,该函数将返回零
// strcmp()如果第一个字符串按字母顺序排在第二个字符串之前(后)返回一个负(正)数

#include <iostream>
#include <cstring>	// strcmp()函数的头文件

int main(void)
{
    
    
    using namespace std;

    char word[5] = "?ate";     // strcmp()该函数接受两个字符串地址作为参数(数组名是一个地址,字符串也是一个地址)
    for (char ch = 'a'; strcmp(word, "mate"); ch++) // strcmp()如果字符串不相等,则它的值为非零(true);
                                                    // strcmp()如果字符串相等,则它的值为零(false)。
    {
    
    
        cout << word << endl;
        word[0] = ch;
    }
    cout << "After loop ends, word is " << word << endl;

    cout << strcmp("abc", "ABC") << endl;   // return 1 (正数),ASCII表中A在a前

    return 0;
}

comparison of string-like strings: relational operator

// string 类字符串的比较
// 类设计让您能够使用关系运算符进行比较
#include <iostream>
#include <string>   // string class

int main(void)
{
    
    
    using namespace std;

    string word = "?ate";
    for (char ch  = 'a'; word != "mate"; ch++)  // 可以将关系运算符用于string对象
    {
    
    
        cout << word << endl;
        word[0] = ch;
    }
    cout << "After loop ends, word is " << word << endl;

    return 0;
}

type alias

  1. Preprocessor: #define A Breplace B with A
  2. Keyword typedef: typedef A B;replace A with B

【while loop】

A while loop is a for loop without an initialization and update section, it only has a test condition and a loop body: (entry-condition loop)

header file ctime:

  1. First, a symbolic constant, CLOCKS_PER_SEC, is defined, which is equal to the number of system time units per second.
  2. So, divide the system time by this value to get the number of seconds. Or multiply the number of seconds by CLOCK_PER_SEC to get the time in system time units.
  3. Second, ctime uses clock_t as an alias for the return type of clock(), which means that a variable can be declared as type clock_t, and the compiler will convert it to long, unsigned int, or other types suitable for the system.

Write a delay loop using while and clock:

// 如何使用clock()和头文件ctime来创建延迟循环。

#include <iostream>
#include <ctime>    // clock_t 的头文件

int main(void)
{
    
    
    using namespace std;

    cout << "Enter the delay time, in seconds:";
    float secs;
    cin  >> secs;
    clock_t delay = secs * CLOCKS_PER_SEC;  // 以系统时间单位为单位(而不是以秒为单位) 计算延迟时间

    cout << "starting\a\n";
    clock_t start = clock();
    while (clock() - start < delay);    // while 循环体为空语句
    cout << "done!\a\n";

    return 0;
}

【do while loop】

  1. The exit condition loop.
  2. The body of the loop is executed first, and then the test expression is evaluated to determine whether the loop should continue.
  3. If the condition is false, the loop terminates; otherwise, it enters a new round of execution and testing.
  4. Such a loop usually executes at least once because its program flow must pass through the loop body before reaching the test condition.

Usage: When user input is requested, the program must first obtain the input and then test it.

【Loop and text input】

The cin object supports 3 different modes of single-character input

  1. cin
  2. cin.get(char);
    C language: To modify the value of a variable, the address of the variable must be passed to the function. C++: The header file iostream declares the parameter of cin.get(ch) as a reference type, so this function can modify the value of its parameter.
    Function overloading allows the creation of multiple functions with the same name, provided they have different parameter lists.
    The array name is the address of its first element, so the character array name is of type char*
    Detect end-of-file (EOF)
    while (cin.fail() == false){...} Simulates an end-of-file condition via the keyboard.
    In Unix, you can press Ctrl+D at the beginning of the line; in Windows command prompt mode, you can press Ctrl+Z and Enter at any position.
  3. cin.get()

while (cin.get(ch));The three guidelines (determine the end condition, initialize the condition, and update the condition) are all placed in the loop test condition.

  1. cin.get(ch) To determine the condition of the loop test, the program must call cin.get(ch) first. If successful, put the value into ch.
  2. Then, the program gets the return value of the function call, which is cin.
  3. Next, the program converts cin to bool. If the input is successful, the result is true, otherwise it is false.

while ((ch = cin.get()) != EOF)

  1. The program must first call the cin.get( ) function, and then assign the return value of this function to ch.
  2. Since the value of the assignment statement is the value of the left operand, the entire subexpression becomes the value of ch.
  3. If this value is EOF, the loop will end, otherwise continue.
  4. All parentheses in this test condition are essential. (Because the != operator has higher precedence than =)

input Output

// 方法一:
int ch; 			// for compatibility with EOF value
ch = cin.get();
while (ch != EOF)
{
    
    
    cout.put(ch); 	// cout.put(char(ch)) for some implementations
    ch = cin.get();
}

// 方法二:
char ch;
cin.get(ch);	// cin.get(ch)返回一个对象, 而不是读取的字符
while (cin.fail() == false) 	// test for EOF
{
    
    
    cout << ch;
    cin.get(ch);
}

[Nested loops and two-dimensional arrays]

Two-dimensional arrayint maxtemps[4][5];

Assuming you want to print all the contents of an array, you can use a for loop to change the rows and another nested for loop to change the columns:

for (int row = 0; row < 4; row++)
{
    
    
    for (int col = 0; col < 5; ++col)
        cout << maxtemps[row][col] << "\t";
        cout << endl;
}

Initialize an array of pointers to a set of string constants:

That is, declare cities as an array of char pointers. This makes each element (such as cities[0]) a char pointer that can be initialized to the address of a string. The program initializes cities[0] to be the address of the string "Gribble City".

array of pointers = array of char arrays = array of string objects

  1. Array of pointers: char * cities[5]
  2. Array of char arrays: char cities[5][25]
  3. Array of string objects: char string cities[5]
// 初始化了一个二维数组, 并使用了一个嵌套循环

// 将一个指针数组初始化为一组字符串常量。
// 也就是说,将cities声明为一个char指针数组。这使得每个元素(如cities[0])都是一个char指针,可被初始化为一个字符串的地址。
// 程序将cities [0]初始化为字符串“Gribble City”的地址

#include <iostream>
const int Cities = 5;
const int Years = 4;
int main()
{
    
    
    using namespace std;
                                    // 可以试用使用char数组的数组 char cities[Cities][25]
                                    // 还可以使用string对象数组 string cities[Cities]
    const char * cities[Cities] =   // 将cities声明为一个char指针数组
            {
    
     // to 5 strings
                    "Gribble City", // cities[0]初始化为字符串“Gribble City”的地址
                    "Gribbletown",
                    "New Gribble",
                    "San Gribble",
                    "Gribble Vista"
            };
    int maxtemps[Years][Cities] = // 2-D array 初始化
            {
    
    
                    {
    
    96, 100, 87, 101, 105}, // values for maxtemps[0]
                    {
    
    96, 98, 91, 107, 104}, // values for maxtemps[1]
                    {
    
    97, 101, 93, 108, 107}, // values for maxtemps[2]
                    {
    
    98, 103, 95, 109, 108} // values for maxtemps[3]
            };
    cout << "Maximum temperatures for 2008 - 2011\n\n";
    for (int city = 0; city < Cities; ++city)
    {
    
    
        cout << cities[city] << ":\t";
        for (int year = 0; year < Years; ++year)
            cout << maxtemps[year][city] << "\t";
        cout << endl;
    }
// cin.get();
    return 0;
}

【Summarize】

  1. C++ provides 3 kinds of loops: for loop, while loop and do while loop. If the loop test condition is true or non-zero, the loop will repeatedly execute a set of instructions; if the test condition is false or 0, the loop ends. Both for loop and while loop are entry conditional loops, which means that the program will check the test condition before executing the statements in the loop body. The do while loop is an exit conditional loop, which means it will check the condition after executing the statements in the loop body.
  2. The syntax of each loop requires that the body of the loop consist of a single statement. However, this statement can be a compound statement or a statement block (multiple statements enclosed in curly braces).
  3. Relational expressions compare two values ​​and are often used as loop test conditions. Relational expressions are formed by using one of six relational operators: <, <=, ==, >=, >, or !=. The result of the relational expression is bool type, and the value is true or false.
  4. Many programs read text input or text files byte by byte, and the istream class provides a variety of methods to do this.
  5. If ch is a char variable, the following statement reads the next character in the input into ch: cin >> ch; it ignores spaces, newlines, and tabs.
  6. The following member function call reads the next character in the input (whatever that character is) and stores it into ch: The cin.get(ch);member function call returns cin.get( )the next input character—including spaces, newlines, and tabs, so, It can be used like this:ch = cin.get();
  7. cin.get(char)A member function call indicates that EOF has been reached by returning a bool value converted to false, while a cin.get( )member function call indicates that EOF has been reached by returning a value of EOF, which is defined in the file iostream.
  8. Nested loops are loops within loops and are suitable for working with two-dimensional arrays.

【Programming Exercise】

// 5.9.2
// 使用array对象(而不是数组)和long double(而不是long long)重新编写程序清单5.4,并计算100!的值。

#include <iostream>
#include <array>

using namespace std;

const int ArSize = 100;  // example of external declaration

int main()
{
    
    
    array<long double, ArSize> factorials;
    factorials[1] = factorials[0] = 1LL;    //连续赋值,从右到左

    for (int i = 2; i < ArSize; i++)
        factorials[i] = i * factorials[i-1];

    cout << ArSize << "! = " << factorials[99] << endl;

    return 0;
}


// 5.9.4
// Daphne   利息 = 0.10×原始存款
// Cleo     利息 = 0.05×当前存款
// 计算多少年后, Cleo的投资价值才能超过Daphne的投资价值, 并显示此时两个人的投资价值。

#include <iostream>

int main(void)
{
    
    
    using namespace std;

    double Daphne_account=100;
    double Cleo_account=100;
    int years=0;
    while (Daphne_account >= Cleo_account)
    {
    
    
        years++;
        Daphne_account+=10;
        Cleo_account=Cleo_account*1.05;
    }
    cout << "After " << years << " years " << "Cleo is richer than Daphne " << endl;
    cout << "Cleo_account = " << Cleo_account << endl;
    cout << "Daphne_account = " << Daphne_account << endl;

    return 0;
}


// 5.9.7
// 设计一个名为car的结构, 用它存储下述有关汽车的信息: 生产商(存储在字符数组或string对象中的字符串) 、 生产年份(整数) 。
// 编写一个程序,向用户询问有多少辆汽车。随后,程序使用new来创建一个由相应数量的car结构组成的动态数组。
// 接下来, 程序提示用户输入每辆车的生产商(可能由多个单词组成) 和年份信息。
// 请注意, 这需要特别小心, 因为它将交替读取数值和字符串(参见第4章) 。
// 最后,程序将显示每个结构的内容。

#include <iostream>
#include <cstring>

using namespace std;
struct car
{
    
    
    std::string make;
    int year;
};

int main(void)
{
    
    
    int n;
    cout << "How many:";
    cin >> n;
    car *pt = new car[n];

    for (int i=0; i < n; ++i)
    {
    
    
        cout << "Car #" << i+1 << ":" << endl;
        cout << "Place enter the make:";
        cin >> pt[i].make;
        cout <<"please enter the year make: ";
        cin>>pt[i].year;
    }
    cout<<" Here is your collection: "<<endl;
    for (int i = 0; i < n; i++)
    {
    
    
        cout << pt[i].make<<"   "<<pt[i].year<<endl;
    }

    delete [] pt;
}


// 5.9.8
// 编写一个程序, 它使用一个char数组和循环来每次读取一个单词,直到用户输入done为止。
// 随后,该程序指出用户输入了多少个单词(不包括done在内) 。
// 用string类的方法实现

#include <iostream>
#include <cstring>

int main(void)
{
    
    
    using namespace std;

    int num_word=0;
    char letter[128];   //string letter;
    cout<<"Enter words (type done to stop)"<<endl;
    while (cin >> letter)
    {
    
    
        if (!(strcmp(letter, "done")))  //if (letter == "done")
        {
    
    
            break;
        }
        num_word++;
    }
    cout<<"You enter a total of "<<num_word<<" words."<<endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_39751352/article/details/126530764