首页IT科技循环的表示方法(第5章 循环和表达式)

循环的表示方法(第5章 循环和表达式)

时间2025-05-02 09:48:46分类IT科技浏览3201
导读:说明 看《C++ Primer Plus》时整理的学习笔记,部分内容完全摘抄自《C++ Primer Plus》(第6版)中文版,Stephen Prata 著,张海龙 袁国忠译,人民邮电出版社。只做学习记录用途。...

说明

看《C++ Primer Plus》时整理的学习笔记           ,部分内容完全摘抄自《C++ Primer Plus》(第6版)中文版                  ,Stephen Prata 著      ,张海龙 袁国忠译     ,人民邮电出版社           。只做学习记录用途                  。

本章介绍循环关系表达式      。

5.1 for 循环

for循环是入口条件循环                  ,也就是在每轮循环之前            ,都将计算测试表达式的值     。

5.1.1 for 循环格式

for循环的基本格式如下:

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

initialization在循环开始时被执行     ,且整个循环过程中只被执行一次                 ,它可以使用任意表达式            ,通常在这一部分中声明并初始化变量,但这种变量只存在于for语句中                 ,当程序离开循环后                  ,这种变量将消失                  。(对于部分老式实现,initialization部分内声明的变量将被视为在循环之前声明的           ,因此在循环结束后仍可使用            。)

test-expression(测试表达式)决定循环体是否被执行                  ,它也可以使用任意表达式      ,C++ 将把结果强制转换为 bool 类型           ,若值为false                  ,将导致循环结束      ,若值为true     ,循环将继续进行                  ,这一部分通常使用关系表达式     。当省略测试表达式时            ,测试条件默认为true                 。

update-expression(更新表达式)在每轮循环结束时执行     ,它也可以使用任意表达式                 ,但通常被用来对跟踪循环轮次的变量的值进行增减            。

//以下循环将一直运行            ,除非在statements里跳出 for (;;) { statements; }

5.1.2 递增运算符(++)和递减运算符(--)

递增运算符(++)递减运算符(--)执行两种极其常见的循环操作:将循环计数加 1 或减 1。这两个运算符都有两种变体:前缀版本位于操作数前面,如++x;后缀版本位于操作数后面                 ,如x++;两个版本对操作数的影响是一样的                  ,但是影响的时间不同                 。后缀版本表示先使用操作数的值,然后再将操作数的值加 1;前缀版本表示先将操作数的值加 1           ,然后再使用操作数的值                  。

//前缀版本                  ,全部执行完毕后x=6, y=6. int x = 5; int y = ++x; //后缀版本      ,全部执行完毕后x=6, y=5. int x = 5; int y = x++;

此外           ,前缀格式与后缀格式的执行速度会有细微的差别:后缀版本首先会复制一个副本                  ,将其加 1      ,然后将复制的副本返回     ,而前缀版本不会进行额外的复制操作。对于内置类型而言                  ,这种差异微乎其微            ,但对于用户定义的类型     ,前缀版本的效率比后缀版本高           。

5.1.3 递增/递减运算符和解除引用运算符

将递增(++)/递减(--)运算符和解除引用运算符(*)同时用于指针时                 ,将依据运算符的位置以及优先级来进行运算                  。前缀递增           、前缀递减                  、解除引用运算符的优先级相同            ,都以从右到左的方式进行结合;后缀递增      、后缀递减的优先级相同,但比前缀运算符的优先级高                 ,且都以从左到右的方式进行结合      。

//执行完毕后x=32.8, pt指向arr[1], arr元素无变化 double arr[3] = {21.1, 32.8, 23.4}; double *pt = arr; double x = *++pt; //执行完毕后x=22.1, pt指向arr[0], arr元素无变化 double arr[3] = {21.1, 32.8, 23.4}; double *pt = arr; double x = ++*pt; //执行完毕后x=21.1, pt指向arr[1], arr元素无变化 double arr[3] = {21.1, 32.8, 23.4}; double *pt = arr; double x = *pt++; //执行完毕后x=21.1, pt指向arr[0], arr[0]=22.1 double arr[3] = {21.1, 32.8, 23.4}; double *pt = arr; double x = (*pt)++;

5.1.4 组合赋值运算符

每个算术运算符都有其对应的组合赋值运算符:

操作数 作用(L为左操作数                  ,R为右操作数) += 将L+R赋给L -= 将L-R赋给L *= 将L*R赋给L /= 将L/R赋给L %= 将L%R赋给L

5.1.5 逗号运算符

用两个花括号可以构造一条复合语句(代码块),代码块被视为一条语句           ,这种做法允许把两条或更多语句放到按 C++ 语法只能放一条语句的地方           。逗号运算符对表达式完成同样的任务                  ,可以将两个或多个表达式合并为一个      ,但在声明语句中           ,逗号只做为分隔符                  ,而不是运算符                  。逗号运算符是一个顺序点      ,它确保先计算第一个表达式     ,再计算第二个表达式                  ,C++ 规定            ,逗号表达式的值是第二部分的值     ,在所有运算符中                 ,逗号运算符的优先级是最低的      。

//声明语句中            ,逗号用做分隔符 int i = 0, j = 0; //逗号用做运算符 i = 0, j = 0; //逗号运算符的优先级最低,此时i=1 i = 1,2,3,4,5,6; //逗号表达式的值                 ,此时i=6 i = (1,2,3,4,5,6);

5.1.6 关系表达式

C++ 提供了 6 种关系运算符来对数字进行比较                  ,由于字符用其 ASCII 码表示,因此也可将这些运算符用于字符     。不能将它们用于 C-风格字符串           ,但可用于 string类对象                  。对所有关系表达式                  ,若比较结果为真      ,则其值为true           ,否则为false            。关系运算符的优先级比算术运算符低     。

操作符 含义 < 小于 <= 小于或等于 == 等于 > 大于 >= 大于或等于 != 不等于

5.1.7 字符串的比较

C-风格字符串应使用strcmp()函数来比较                  ,该函数接受两个字符串地址作为参数      ,参数可以是指针     、字符串常量或字符数组名                 。如果两个字符串相同     ,该函数将返回零;如果第一个字符串按字母顺序排在第二个字符串之前                  ,该函数将返回一个负值;如果第一个字符串按字母顺序排在第二个字符串之后            ,该函数将返回一个正值            。

//比较C-风格字符串是否相等 strcmp(str1,str2) == 0 //比较C-风格字符串是否不等 strcmp(str1,str2) != 0 strcmp(str1,str2) //比较C-风格字符串str1是否在str2前面 strcmp(str1,str2) < 0 //比较C-风格字符串str1是否在str2后面 strcmp(str1,str2) > 0

string类函数重载了关系运算符     ,因此其对象可直接使用关系运算符进行比较。

5.2 while 循环

while循环也是入口条件循环                 ,也就是在每轮循环之前            ,都将计算测试表达式的值                 。

5.2.1 while 循环格式

while循环的基本格式如下:

while (test-expression) { statements; }

它可以转换为for循环:

for (;test-expression;) { statements; }

同样地,for循环基本格式也可以转换为while循环:

initialization; while (test-expression) { statements; update-expression; }

通常                 ,使用for循环来为循环计数                  ,在无法事先知道循环将执行的次数时,一般使用while循环                  。设计循环时           ,有以下几条指导原则:

指定循环终止条件。 在首次测试之前初始化条件           。 在条件被再次测试之前更新条件                  。

5.2.2 编写延时循环

头文件ctime定义了一个符号常量CLOCKS_PER_SEC                  ,该常量等于每秒钟包含的系统时间单位数      ,将系统时间除以这个值           ,可以得到秒数      。或者将秒数乘以CLOCKS_PER_SEC                  ,可以得到以系统时间单位为单位的时间           。以下程序使用了头文件ctime来创建延时 5 秒的循环:

#include <ctime> int main() { //接下来的4行总耗时约5秒 float secs = 5; clock_t delay = secs * CLOCKS_PER_SEC; clock_t start = clock(); while (clock() - start < delay); return 0; }

5.2.3 类型别名

C++ 为类型建立别名的方式有两种                  。一种是使用预处理器:

//使用预处理器创建别名(通用格式) #define aliasName typeName //使用预处理器创建别名(例子) #define BYTE char #define FLOAT_POINTER float *

第二种方法是使用关键字typedef来创建别名:

//使用关键字typedef来创建别名(通用格式) typedef typeName aliasName; //使用关键字typedef来创建别名(例子) typedef char BYTE; typedef float * FLOAT_POINTER;

typedef不会创建新类型      ,只是为已有类型建立一个新名称     ,相比于使用#define                  ,它能处理更复杂的类型别名            ,因此     ,使用typedef是一种更佳的选择      。

5.3 do while 循环

do while循环是出口条件循环                 ,这意味着这种循环将首先执行循环体            ,然后再判定测试表达式,决定是否应继续执行循环     。这样的循环通常至少执行一次                  。do while循环的基本格式如下(注意最后的分号):

do { statements; } while (test-expression);

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

C++11 新增了一种循环:基于范围的for循环                 ,这简化了一种常见的循环任务:对数组或容器类的每个元素执行相同的操作:

//循环遍历数组的值 double prices[5] = {4.99, 10.99, 6.87, 7.99, 8.49}; for (double x : prices) { std::cout << x << std::endl; } //循环遍历并修改数组的值(引用变量) double prices[5] = {4.99, 10.99, 6.87, 7.99, 8.49}; for (double &x : prices) { x = x * 0.80; } //基于范围的for循环和初始化列表 for (double x : {3, 5, 2, 8, 6}) { std::cout << x << std::endl; }

这种循环多用于模板容器类            。

5.5 嵌套循环和二维数组

5.5.1 初始化二维数组

C++ 没有提供二维数组的类型                  ,但用户可以创建每个元素本身都是数组的数组,二维数组在概念上是二维的           ,但在内存中是连续存放的                  ,在 C++ 中      ,二维数组是按行存储的           ,也就是先存放a[0]行                  ,再存放a[1]行      ,接着存放a[2]行     ,以此类推直到元素放完                  ,每行中元素也是依次存放     。二维数组的初始化与一维数组类似:

//初始化方式一:全元素初始化 int a[4][5] = { {96, 100, 87, 101, 105}, {96, 98, 91, 107, 104}, {96, 101, 93, 108, 107}, {96, 103, 95, 109, 108} }; //初始化方式二:全元素初始化时            ,可省略内部括号 int a[4][5] = { 96, 100, 87, 101, 105, 96, 98, 91, 107, 104, 96, 101, 93, 108, 107, 96, 103, 95, 109, 108 }; //初始化方式三:全元素初始化时     ,第一维大小可省略 int a[][5] = { 96, 100, 87, 101, 105, 96, 98, 91, 107, 104, 96, 101, 93, 108, 107, 96, 103, 95, 109, 108 }; //初始化方式四:全元素初始化为0 int a[4][5] = {0}; //初始化方式五:初始化部分元素                 ,剩余元素默认为0 int a[4][5] = { {96}, {96, 98, 91}, {96, 101}, {96, 103, 95, 109} }; //初始化方式六:省略第一维大小且只初始化部分元素 int a[][5] = { {}, {96, 98, 91}, {96, 101}, {96, 103, 95, 109} };

5.5.2 使用 new 创建动态二维数组

动态二维数组的创建以及释放如下所示:

//分配动态二维数组内存的通用格式 typeName ** pointer_name = new typeName *[rowSize]; for (int i = 0; i < rowSize; i++) { pointer_name[i] = new typeName[columnSize]; } //释放动态二维数组内存 for (int i = 0; i < rowSize; i++) delete[] pointer_name[i]; delete[] pointer_name;

在 C++11 中            ,使用 new 创建动态二维数组的同时还可对其进行初始化,采用动态一维数组的初始化方法                 ,在for循环中对动态二维数组的每行进行初始化即可                 。

5.5.3 嵌套循环

嵌套循环是循环中的循环                  ,外层循环以及内层循环可以是for                  、while            、do while中的任意一种            。由于 CPU 使用了分支预测技术,将大循环做为内层循环           ,小循环做为外层循环可以提升嵌套循环的运行效率                  ,因此嵌套循环一般将循环次数最多循环的放在最内层。由于二维数组是按行存储的      ,使用嵌套循环遍历二维数组时           ,按行遍历可提升运行效率                  ,因此当嵌套循环用于遍历二维数组时      ,一般将列循环放在内层[测试例]                 。

声明:本站所有文章     ,如无特殊说明或标注                  ,均为本站原创发布                  。任何个人或组织            ,在未征得本站同意时     ,禁止复制     、盗用                 、采集            、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益                 ,可联系我们进行处理           。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
jspc标签(JSP中的JSTL 标签库) win7旗舰版如何查看本机的mac地址信息表(Win7旗舰版如何查看本机的Mac地址?)