C++ Primer Plus 学习——第五章

循环与关系表达式

5.1 for循环

代码5-1

// forloop.cpp -- introducing the for loop
#include <iostream>
using namespace std;

int main()
{
    int i;

    for (i = 0; i < 5; i++)
    {
        cout << "I have " << i << " apple(s)." << endl;
    }
    cout << "GG Bond konws when to end the loop" << endl;

    return 0;
}

for循环组成部分
代码5-2

// num_test.cpp -- use numeric test in for loop
#include <iostream>
using namespace std;

int main()
{
    cout << "Enter the starting countdown value: ";
    int count;

    cin >> count;

    int i;

    for (i = count; i ; i--)
    {
        cout << "i = " << i << endl;
    }
    cout << "Done when i = " << i << endl;

    return 0;
}

对以上两部分代码,注意++和–运算符的使用

表达式
代码5-3

// express.cpp -- values of expressions4
#include <iostream>
using namespace std;

int main()
{
    int x;

    cout << "The expression x = 100 has the value ";
    cout << (x=100) << endl;
    cout << "Now x = " << x << endl;
    cout << "The expression x < 3 has the value ";
    cout << (x<3) << endl;
    cout << "The expression x > 3 has the value ";
    cout << (x>3) << endl;
    cout.setf(ios_base::boolalpha);// 设置bool不自动转换为int值输出
    cout << "\n\n";
    cout << "The expression x < 3 has the value ";
    cout << (x<3) << endl;
    cout << "The expression x > 3 has the value ";
    cout << (x>3) << endl;

    return 0;

}

对于在for循环中声明的变量,较老的C++在循环结束后仍可以使用变量,但较新的C++不允许,循环结束后即释放

循环阶乘示例
代码5-4

// formore.cpp -- more looping with for
#include <iostream>
using namespace std;

const int ArSize = 16;

int main()
{
    long long factorials[ArSize];

    factorials[1] = factorials[0] = 1LL;
    for (int i = 2; i < ArSize; i++)
    {
        factorials[i] = factorials[i-1] * i;
    }
    for (int i = 0; i < ArSize; i++)
    {
        cout << i << "! = " << factorials[i] << endl;
    }

    return 0;
}

修改步长
代码5-5

// bigstep.cpp -- count as directed
#include <iostream>
using namespace std;

int main()
{
    cout << "Enter an integer: ";
    int by;

    cin >> by;
    cout << "Counting by: " << by << "s:\n" << endl;
    for (int i = 0; i < 100; i+=by)
    {
        cout << i << endl;
    }

    return 0;
}

for循环与字符串
代码5-6

// forstr1.cpp -- using for with a string
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << "Enter a word: ";
    string word;

    // cin >> word;
    getline(cin, word);// 测试数据 GG Bond
    for (int i = word.size()-1; i>=0; i--)
    {
        cout << word[i] << " ";
    }
    cout << "\nBye.\n";

    return 0;
}

递增与递减运算符
代码5-7

// plus_one.cpp -- the increment operator
#include <iostream>
using namespace std;

int main()
{
    int a = 20;
    int b = 20;

    cout << "a = " << a << "\t\tb = " << b << endl;
    cout << "a++ = " << a++ << "\t++b = " << ++b << endl;
    cout << "a = " << a << "\t\tb = " << b << endl;

    return 0;
}

留意前缀和后缀使用的区别

需要注意
任何完整表达式【最小子表达式】的末尾都是一个顺序点,如下:

#include <iostream>
using namespace std;

int main()
{
    int a = 20;

    while (a++ < 30)// a++ < 30 是一个完整表达式,所以a并非直接使用20进入cout进行输出,
    				// 而是完整实现 a++ 以及使用 20 < 30 判断后使用21进入cout进行输出
    {
        cout<< "a = " << a << endl;
    }
    
    return 0;
}
int y = (4 + a++) + (6 + a++);
cout << y << endl;

同时,对于上述 y 的表达式,C++不保证输出结果一定正确,因为不能保证 4 + a++ 【并非完整表达式】中 a 的值使用后立刻增加1

指针与递增/递减运算符

++*p;// 对地址中的值进行递增,指针指向不变
(*p)++;// // 对地址中的值进行递增,指针指向不变
*p++;// 递增运算符优先级更高,意味着先指针的指向递增,再解引用

组合赋值运算符
在这里插入图片描述
代码5-8

// block.cpp -- use a block statement
#include <iostream>
using namespace std;

int main()
{
    cout << "The Amazing Accounto will sum and average five numbers for you." << endl;
    cout << "Please enter five numbers: " << endl;
    double number;
    double sum = 0.0;

    for (int i = 1; i <= 5; i++)
    {
        cout << "Value: " << i << " : ";
        cin >> number;
        sum += number;
    }
    cout << "Five exquisite choices indeed! " << endl;
    cout << "They sum to: " << sum << endl;
    cout << "They average: " << sum / 5 << endl;

    return 0;

}

注意:一个 {} 即代表着一个代码块,代码块中定义的变量,只能在自身的代码块中调用

int y = 0;
{
	int x = 0;
	cout << y << endl;// 正常输出
}
cout << x << endl;// 无法正常输出

语法技巧
逗号运算符 ,
代码5-9

// forstr2.cpp -- reversing an array
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << "Enter a word: ";
    string word;

    // cin >> word;
    getline(cin, word);
    char temp;// 如果将temp写在for循环里面,将重复分配和释放,费时更多
    int i, j;
    
    for (j = 0, i = word.size()-1; j < i; --i, ++j)// 逗号技巧
    {
        temp = word[i];
        word[i] = word[j];
        word[j] = temp;
    }

    cout << word << "\nDone!" << endl;

    return 0;
}
i=20, j=2*i;//正常运行
cats = 17,240;//编译器解释为(cata=17),240
cats = (17,240);// 可以使用括号的优先级最高特性,cats值被设置为240

关系表达式
代码5-10

// equal.cpp -- quality vs assainment
#include <iostream>
using namespace std;

int main()
{
    int quizscores[10] = {20, 20, 20, 20, 20, 19, 20, 18, 20, 20};

    cout << "Doing it right: " << endl;
    int i;

    for (i = 0; quizscores[i]==20; i++)
    {
        cout << "quiz " << i << " is a 20" << endl;
    }
    // cout << "Doing it dangerously wrong: " << endl;
    // for (i = 0; quizscores[i]=20; i++)// 数组末尾不停止,可能导致其他程序崩溃
    // {
    //     cout << "quiz " << i << " is a 20" << endl;
    // }

    return 0;
}

C风格字符串比较
假设word中储存了mate字符串

word == "mate";// 此句实际为判断它们是否存储在相同地址上

需要判断两个字符串是否相同,可使用

strcmp();// 接受两个字符串地址做参数,相同返回0,如果第一个字符串在第二个之前,返回负数,否则返回正数

代码5-11

// compstr1.cpp -- Comparing strings using arrays
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char word[5] = "?ate";

    for (char ch = 'a'; strcmp(word, "mate"); ch++)
    {
        cout << word << endl;
        word[0] = ch;
    }
    cout << "After loop endds, words is : " << word << endl;

    return 0;
}

使用string类字符串
代码5-12

// compstr2.cpp -- Comparing strings using arrays
#include <iostream>
#include <string>
using namespace std;

int main()
{
    string word = "?ate";

    for (char ch = 'a'; word!="mate"; ch++)
    {
        cout << word << endl;
        word[0] = ch;
    }
    cout << "After loop endds, words is : " << word << endl;

    return 0;
}

5.2 while循环

代码5-13

// while.cpp -- introducing the while loop
#include <iostream>
using namespace std;

const int ArSize = 20;

int main()
{
    char name[ArSize];

    cout << "Enter your name: ";
    cin.getline(name, ArSize);
    cout << "Here is your name, verticalized and ASCIIized: " << endl;
    int i = 0;

    while (name[i] != '\0')// 判断结尾空字符
    {
        cout << name[i] << " : " << int(name[i]) << endl;
        i++;
    }

    return 0;

}

延时循环
代码5-14

// waiting.cpp -- using clock() in time delay loop
#include <iostream>
#include <ctime>
using namespace std;

int main()
{
    cout << "Enter the time delay, in seconds: ";
    float seconds;

    cin >> seconds;
    clock_t delay = seconds * CLOCKS_PER_SEC;// CLOCKS_PER_SEC值为1000,delay计算结果单位为毫秒,即计算机系统单位时间
    cout << "Starting time delay\a\n";
    clock_t start = clock();// clock_t组为clock()返回类型,是类型别名
                            //【因为clock()在不同系统的返回类型不一定相同,可能为long 、unsigned long等】
                            // start是记录进入循环的时间
    while (clock() - start < delay);// 一直判断当前时间与记录时间的差值与所需延迟的时间相比,满足进入空循环

    cout << "Done!\n";
    return 0;
}

C++为类型建立别名:

  1. 使用预处理器
#define BYTE char
#define f_pointer float*
f_pointer a, b;// 会被编译器解释为 float* a, float b【typedef无此问题】
  1. 使用关键字typedef
typedef char byte;
typedef char* bytePointer;// 将char指针命别名
bytePointer a, b;// 会被编译器解释为 char* a, char* b

5.3 do while循环

// dowhile.cpp -- exit-condition-loop
#include <iostream>
using namespace std;

int main()
{
    int n;

    cout << "Enter numbers in the range 1-10 to find ";
    cout << "my favorite number. " << endl;
    do
    {
        cin >> n;
    } while (n!=7);
    cout << "Yes, 7 is my favorite number. " << endl;

    return 0;
    
}

编译器正确,却不建议的写法:

int I = 0;
    for (;;)
    {
        I++;
        if (I >= 30) break;
    }
    
    for (;;I++)
    {
        if (I >= 30) break;
    }
    // 以下为正常写法
    do
    {
        I++;
    } while (30 > I);
    
    while(I < 30)
    {
        I++;
    }

5.4 基于范围的for循环

C++11新增,对数组、容器类(vector,array)等可迭代对象中每个元素执行相同的操作
代码示例

#include <iostream>
using namespace std;

int main()
{
    double prices[4] = {1.00, 2.00, 3.00, 4.00};
    
    cout << "original data: " << endl;
    for (double x : {1.00, 2.00, 3.00, 4.00})
    {
        cout << x << " ";
    }
    
    for (double &x : prices)// &: 引用符,即取地址【*: 解引用符】
    // 可将&去除观察区别
    {
        x = x * 10;// 对每个元素进行修改
    }
    cout << "\nAfter being fixed: " << endl;
    for (double x : prices)
    {
        cout << x << " ";
    }
    return 0;
}

5.5 循环和文本输入

通过循环完成逐字符读取文件或键盘文本
即使C与C++中的while看起来一样,但C++的I/O工具不同
cin 对象支持3种不同模式单字符输入
对字符停止标志称为:哨兵字符
代码5-16
使用cin

// textin1.cpp -- reading chars with a while loop
#include <iostream>
using namespace std;

int main()
{
    char ch;
    int count = 0;

    cout << "Enter characters: enter # to quit" << endl;
    cin >> ch;// input : GG Bond#
    // 一次性将多个字符插入到输入流中,将#看作结束符
    // 由于cin自动忽略空格符和换行符,所以不会将其计数
    while (ch != '#')// 由于在输入流中,刚才的数据有序排列着,循环读取
    {
        cout << ch;
        ++count;
        cin >> ch;// 输入#用于结束
    }
    cout << endl << count << " characters entered" << endl;

    return 0;
}

使用cin.get()
代码5-17

// textin2.cpp -- using cin.get(char)
#include <iostream>
using namespace std;

int main()
{
    char ch;
    int count = 0;

    cout << "Enter characters: enter # to quit" << endl;
    cin.get(ch);// input : GG  Bond# B ond #
    // 一次性将多个字符插入到输入流中,将#看作结束符
    // cin.get(ch);会记录空格
    while (ch != '#')// 由于在输入流中,刚才的数据有序排列着,循环读取
    {
        cout << ch;
        ++count;
        cin.get(ch);// 输入#用于结束
    }
    cout << endl << count << " characters entered" << endl;

    return 0;
}

若输入来自文件,可以使用检查文件尾(EOF),来判断结束信息
检测到EOF后,cin将eofbit、failbit都设置为1,使用成员函数eof()、fail()查看状态

代码5-18

// textin3.cpp -- reading chars to end of file
#include <iostream>
using namespace std;

int main()
{
    char ch;
    int count = 0;

    cout << "Enter characters: " << endl;
    cin.get(ch);
    // The green bird sings in the winter.<ENTER>
    // Yes,but the crow flies in the dawn.<ENTER>
    // <CTRL>+<Z><ENTER>// 模拟EOF条件
    while (cin.fail() == false)
    {
        cout << ch;
        ++count;
        cin.get(ch);
    }
    cout << endl << count << " characters entered" << endl;

    return 0;
}

可以使用cin.clear()来清除EOF标记

C语言中的I/O函数
头文件:<cstdio>

ch = cin.get();// 不接受任何参数,返回输入中的下一个字符
// 与getchar()相似,将字符编码作为int值返回
cin.get(ch);// 返回一个cin对象,并非字符
cout.put(ch);// 显示字符
// 与putchar()相似,参数类型为char
// put()最初只有一个原型,可传递int,将被强制转换为char,
// 后续对于传递的参数通过三个原型:char,signed char,unsigned char【将无法自动将int转换】

当读取文件函数到达EOF时,将无可返回字符,但cin.get()将返回一个特殊值【在iostream中被定义为-1(-1在ASCII码并无定义)】来代表这种状态
由于未定义,所以无法与char字符兼容
如果使用cin.get()【无参数】测试EOF,必须使用int类型来接收返回值

代码5-19

// textin4.cpp -- reading chars with cin.get()
#include <iostream>
using namespace std;

int main()
{
    int ch;// 必须为int类型
    int count = 0;

    // The green bird sings in the winter.<ENTER>
    // Yes,but the crow flies in the dawn.<ENTER>
    // <CTRL>+<Z><ENTER>// 模拟EOF条件
    while ((ch = cin.get()) != EOF)
    {
        cout.put(char(ch));// 强制转换,对应ASCII码
        ++count;
    }
    cout << endl << count << " characters entered" << endl;

    return 0;
}

!= 优先级高于 =
所以不能如下所示,省略括号

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

区别表
在这里插入图片描述

5.6 嵌套循环和二维数组

二维数组:每个元素本身都是数组的数组

int maxtemps[4][5];// 4行5列数组

代码5-20

// nested.cpp -- nested loops and 2-D arrays
#include <iostream>
using namespace std;

const int Cities = 5;
const int Years = 4;

int main()
{
    const char* cities[Cities] = // 指针数组初始化为常量,C++常用操作
    // 注意区别指针常量和常量指针
    {
        "Gribble City",
        "GribbleTown",
        "New York City",
        "San Francisco",
        "Vista City"
    };

    int maxtemps[Years][Cities] = 
    {
        {96, 100, 87, 101, 105},
        {96, 98, 91, 107, 104},
        {97, 101, 93, 108, 107},
        {98, 103, 95, 109, 108}
    };

    cout << "Maximun temperatures for 2008-2011\n\n" << endl;
    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;
    }
    return 0;
}
  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值