C++PrimerPlus 第五章 循环和关系表达式

for循环

for循环的组成部分

for循环完成以下步骤:

  1. 设置初始值

  2. 执行测试,看看循环是否应当继续进行

  3. 执行循环操作

  4. 更新用于测试的值

for(initialization; test-expression; update-expression)
    body

C++语法将整个for看作一条语句(包含多条语句时,需要使用复合语句或代码块)

  • test-expression(测试表达式):决定循环体是否被执行,C++强制转换此语句为bool类型,得到的结果是true或false

  • for循环是入口条件(entry-condition)循环,即每轮循环进行前计算测试表达式的值,当表达式结果为false时,将不会执行循环体。

  • update-expression(更新表达式):在每轮循环结束时执行,此时循环体已经执行完毕,更新表达式可以是任意的C++表达式,还可以是其他控制表达式

表达式和语句

首先明确一点,C++中,任何值或任何有效的值和运算符的组合都是表达式。例:10是值为10的表达式,X =20是一个表达式

表达式的副作用:当判定表达式的操作改变了内存中数据的值时,我们说表达式有副作用(side effect)例:(X =100)此表达式作为判定表达式将X 的值赋为100 改变了X 的值

语句:只要加上分号,所有的表达式都可以成为语句,但不一定编程意义 例:rodents + 6; 没有意义

非表达式和语句

对任何表达式加上分号都可以成为语句,但是反过来不成立。即从语句中删除分号并不一定能使它成为一个表达式 例:返回语句、声明语句、for语句都不满足

由此可以判断:int load; 是一条语句,但int load并不是表达式,因为它没有值,因此eggs = int load * 100;非法 ;同样 ,不能把for循环赋给变量

修改规则

C++相对于C语言添加的特性,允许for结构的初始化部分直接声明,即:for(int i = 0; i < 5; i++)是允许的。

for ( for-init-statement condition; expression) 其中for-init-statement被视为一条语句,有自己的分号,因而总共两个分号没有少

使用这种初始化的一个好处:这个变量只存在于for循环中

递增运算符和递减运算符

可以分为前缀形式和后缀形式 即:++X 和 X++,分别表示将X的值加一,进行计算 和 使用当前值进行计算表达式,再将X 的值加一

避免一条语句中重复出现多个递增或递减运算符

副作用和顺序点

副作用(side effect)指的是在计算表达式时对某些东西进行了修改(如储存在变量中的值);顺序点(sequence point)是程序执行过程中的一个点,在这里,进入下一步前将确保对所有的副作用进行了评估。C++中,语句的分号是一个顺序点,另外,任何完整的表达式末尾都是一个顺序点。

何为完整表达式?不是另一个更大的表达式的子表达式。例:表达式语句中的表达式部分以及用作while循环中检测条件的表达式

前缀格式和后缀格式

对于类而言,使用前缀形式比后缀形式运行更快,内置形式没有区别

递增递减运算符和指针

前缀递增,前缀递减和解除引用运算符的优先级相同,从右往左结合。后缀递增和后缀递减优先级相同,但比前缀运算符优先级高,从左往右结合。

注意指针位置是否发生改变。例:++*p 前缀递增和解引用运算符优先级相同,从右往左结合,所以先计算解引用,再计算前缀递增,即:先取得p的值,再把这个值加1;在这种情况下,指针仍指向原位置

复合语句(语句块)

代码块由一对花括号和它们包含的语句组成,被视为一条语句,从而满足句法的要求。因而对于for循环而言,若不使用花括号,那只有for括号后紧跟的一条语句在循环中。

复合语句中定义的变量只有在代码块中存在,代码块执行完后,变量被释放。

其他语法技巧——逗号运算符

逗号运算符允许将两个表达式放到C++语法只允许放一个表达式的位置。例: ++j, --i;

逗号并不总是逗号运算符,也有可能只是将变量列表中相邻的名称分开: int i, j;

逗号运算符是一个顺序点(确保先计算第一个表达式,然后计算第二个表达式)。在所有的运算符中,逗号运算符的优先级是最低的。

字符串的比较

C++将C-风格字符串视为地址,因而不能用关系运算符来比较。

使用C-风格字符串库中的strcmp()函数来比较。

存储在不同数组长度的不同数组中的字符串可能相同,因为C-风格字符串是通过结尾处的空值字符定义的。

string类字符串的比较

类设计使其可以使用关系运算符进行比较。因为类函数重载了运算符。

while循环

while循环是没有初始化和更新部分的for循环,它只有测试条件和循环体:

while (test-condition) bodywhile循环也是入口条件循环,因此,若条件一开始是false则程序不会执行循环体。

for和while

在C++中,for和while循环本质上是相同的,两者之间可以相互转换

for循环需要三个表达式,但是表达式可以为空,只有分号是不可省略的。例如下面的循环将会一直执行下去:for( ; ; ) body

for循环和while循环的差别:

  • for循环省略测试条件时,将认定条件为true

  • for循环可以用初始化语句声明一个局部变量,但在while循环中不被允许

  • 如果循环体中有continue语句,情况不同

等待一段时间:编写延时循环

clock()函数使用系统时钟。包含在头文件ctime中。

ctime定义了一个符号常量:CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数。因此,将系统时间除以这个值,可以得到秒数。其次,ctime将clock_t作为clock()返回类型的别名,这意味着可以将变量声明为clock_t类型,编译器自动将其转换为long、unsigned int或适合系统的其他类型。

clock()是现在系统时间。

do while 循环

不同于 while和for循环,是出口条件循环(exit condition),即循环至少执行一次。

基于范围的for 循环(C++ 11)

基于范围的for循环简化了一种常见的循环任务:对数组(或容器类,如vector和array)的每个元素执行相同的操作,例:

double prices[5] = {4.66 ,5.66 ,1.55 ,8.36 };
for (double x:prices)
    cout<< x<<std::endl;

要修改数组中的元素,要使用不同的循环变量语法:

for(double &x :prices)
    x = x * 0.5;

符号&表明x 是一个引用变量,只有使用引用变量才能改变数组内容,而第一种方式不能。

基于范围的for循环和初始化列表:

for (int x : {3 ,5 ,2 ,8 ,6})
    cout<< x <<"  ";
cout<<'\n';

循环和文本输入

cin支持3种不同的单字符输入,用户接口各不相同。

使用原始的cin进行输入

cin忽略空格和换行符

使用cin.get(char)

cin.get(ch)读取输入中的下一个字符,并将其赋给ch(包括空格)

解释:C语言中,要修改变量的值,必须将变量的地址传给函数,但C++中将参数声明为引用类型即可(声明在头文件iostream)中

不同的getchar()

C++中的函数重载允许同名函数存在不同的参数列表

cin.getchar(char * ,ArSize)第一个参数是数组名(字符串char * 类型的地址)第二个参数是int 类型的整数

cin.get(ch),不接受任何参数 返回iostream中定义的对象

cin.get(),同样不接受任何参数

cin.get(char)只接受一个参数

文件尾条件(EOF)

文件尾的信息在操作系统中被定义,不同操作系统对文件尾的定义可能不同

操作系统的重定向支持从文件输入,输出到文件等一系列操作

很多操作系统支持模拟文件尾条件,在Windows命令提示符下,任意位置按下 Ctrl + Z 和 Enter

检测到文件尾后,cin将两位(eofbit 和 failbit ,这两个标记都是cin对象的属性)都设置为1 。 可以使用函数eof()和 fail()判断是否到达文件尾 注意:两个函数都是事后报告,因而应该将他们放在读取后。

EOF在iostream中被定义为值-1

嵌套循环和二维数组

初始化二维数组

int maxtemps[4][5] = 
{
    {9,2,2,3,3},
    {7,8,9,63,1},
    {2,3,66,55,1},
    {4,5,66,6,3}
};

二维数组的使用

特殊的,对于char类型的二维数组,提供另一种指针数组,相比定长的char二维数组,更加实用经济(事实上,使用string数组更加方便)

const int Cites=5;
//字符串指针数组
const char * cities[Cites]={
    "Gribble City",
    "Gribbletown",
    "New Gribble",
    "San Gribble",
    "Gribble Vista"
};
​
//char类型二维数组 在此处规定定长不超过24个字符
char cities[Cities][25]={
    "Gribble City",
    "Gribbletown",
    "New Gribble",
    "San Gribble",
    "Gribble Vista"
};
​
//string类型数组 自动调整大小  比二维数组更常用
const string cities[Cities]={
    "Gribble City",
    "Gribbletown",
    "New Gribble",
    "San Gribble",
    "Gribble Vista"
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值