第5章 循环和关系表达式

本章知识点:

 for循环

 表达式和语句

 递增运算符和递减运算符——++和–

 组合赋值运算符

 复合语句

 逗号运算符

 关系运算符——>、>=、==、<=、<、!=

 while循环

 typedef工具

 do while循环

 字符输入方法get()

 文件尾条件

 嵌套循环和二维数组

5.1 for循环

5.1.1 for循环的组成部分

声明模板:

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

例如:

int i;
for  (i = 0; i <5; i++ )
{}

for循环中语句只有一条时,可以不用{},利用缩进即可;多条时,必须使用{};for循环不加{}时只有紧接着的第一条语句位于循环中,缩进会被忽略。

int i;
for (i = 0; i <5; i++ )
cout << “hello ” << endl;
cout << “C++ knows when to stop” <<endl;
//
int i;
for (i = 0; i <5; i++ )
{
  cout << “hello1 ” << endl;
  cout << “hello 2<< endl;
}
cout << “C++ knows when to stop” <<endl;

C++程序在需要整数值的地方会把true和false分别转换为1和0,而在需要bool值的地方会把0和非0分别转换为false和true。

int i;
for (i = 4; i; i-- )
{
..
}

此处将运行至i=0。
cout在显示bool值之前会将其转换为int,可调用

cout.setf(ios::boolalpha); 

函数设置一个标记,该标记名利cout显示true和false,而不是0和1。
另外,for(int i = 0; I < 5; i++)也是允许的,只是i只存在循环体中,局部变量。

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

++x,表示使用x的当前值计算表达式,然后将x的值加1;**x++**表示先将x的值加1,然后使用新的值来计算表达式。
5.1.8 递增/递减运算符和指针
" * "(解除引用)和前缀递减/递增的优先级相同,以从右到左的方式进行结合;后缀递增/递减的优先级相同,但比前缀运算符优先级高,以从左到右的方式进行结合。
1)*++pt 2)++*pt 3)(*pt)++ 4) *pt++

# include <iostream>
int main(void)
{
  using namespace std;
  double arr[5] = {1.1, 2.1, 3.7, 4.9 . 5.8};
  double *pt = arr;
   
  cout << *pt << endl;      //1.1
  cout << *++pt << endl;    //2.1。注意,此处的++pt是全局的,会影响下一步的pt。
  cout << ++*pt << endl;    //3.1 。先增加后cout
  cout << (*pt)++ << endl;   //3.1。先cout后增加
  cout << *pt << endl;    //4.1
  cout << *pt++ << endl;   //4.1
  cout << *pt << endl;     //3.7.{1.1, 4.1, 3.7, 4.9, 5.8}
}
  1. 先执行++pt,再解除引用;
  2. 先解除引用取出内容再执行++;
  3. 先解除引用再++,此处先cout后再执行+1操作;
  4. ++优先级更高,所以先用pt,也就是先*pt(34.8),再执行+1;

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

所有运算符中,逗号运算符的优先级最低;关系运算符的优先级比算数运算符低,也就是说:x+3 > y-2 相当于是 (x+3)>(y-2)

5.1.14 C-风格字符串的比较

数组名是数组的地址,用括号括起的字符串常量也是地址,相同字符串的存储地址也不相同。所以数组和字符串都无法直接通过数组名或者字符串直接进行相等比较。
字符串通过strcmp()函数(cstring)进行比较,该函数接收两个字符串地址作为参数,也就是参数可以是指针、字符串常量或字符数组名。如果两个字符串相同,该函数将返回0;如果第一个字符串的首字母按字母顺序排在第二个字符串之前,返回一个负数值,相反则返回一个正数值。

5.1.15 比较string类字符串

string类字符串较之C-风格字符串更为简单写,可以直接使用关系运算符进行比较。因为类函数重载了运算符。
string类重载!=运算符适用于:至少有一个操作数是string对象,另一个操作数可以是string对象,也可以是C-风格字符串。

5.2 while循环

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

while (test-condition)
     body

首先判断test-condition,为true则执行循环体中的语句。执行完循环体后,程序返回test-condition重新评估,若为非零则再次执行循环体,直至test-condition为false。

# include <iostream>
Const int ArSize = 20;
int main(void){
   using namespace std;
   char name[ArSize] = 20;

   cout << ”Your first name :;
   cin >> name;

   cout << “Here is your name :<< endl;

   int i = 0;
   while(name[i] != ‘\0)      //while(name[i]),次表述更简洁;前者代码更清晰可读
{
     cout << name[i] <<:<< (int)name[i] << endl;
     i++;
}
}

5.2.1 for与while
C++中for和while本质相同,可以相互转换。
for循环→while循环

for (init-expression; test-expression; upadate-expression)
{
   statement(s)
}
//等价于
int-expression;
while (test-expression)
{
     statements(s);
     update-expression;
}

while循环→for循环

while (test-expression)
{
   statement(s)
}
//等价于
for ( ;test-expression; )
{
     statements(s);
}

for循环需要3个表达式,表达式都可以为空,但两个分号是必需项。如果测试表达式也为空,测试结果将为true,循环将一直运行下去:

for ( ; ; )
{
     statements(s);
}

在无法预知循环执行次数的时候常使用while循环。
循环设计指导原则:
 指定循环终止的条件
 在首次测试之前初始化条件
 在条件被再次测试之前更新条件
while循环和for循环一样都由括号括起的表达式和后面的循环体(仅包含一条语句)组成。建议不管循环体语句只有一条还是多条都用括号括起来。

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

应用场景:程序在屏幕上显示一条消息,但还没来得阅读之前,又出现了其他内容。通过单纯计算机计数或因为机器性能过高时计数过快而无法控制,此时便需要通过系统时钟来完成此种工作。
函数clock(),返回程序开始执行后所用的系统时间。其返回单位不一定是秒,且返回类型在某些系统上可能是long或者unsigned long。
头文件ctimne可解决这些问题,它定义了一个符号常量——CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数。因此将系统时间/ CLOCKS_PER_SEC即可得到秒数;或将秒数* CLOCKS_PER_SEC即可得到以系统时间单位为单位的时间。
clock()返回类型为clock_t,可将变量声明为clock_t类型,编译器将把它转换为long、unsigned int或其他适合系统的其他类型。

# include <iostream>
# include <ctime>
int main(void)
{
   using namespace std;
   cout << “Enter the delay time ,in seconds”;

   float secs;
   cin >> secs;
   clock_t delay = secs * CLOCK_PER_SEC;
   
   clock_t start = clock();
  
   while(clock() – start) < delay)
;

cout << “done!\n”;
  
   return 0;
}

此程序以系统时间单位为单位(而非秒为单位)计算延迟时间,避免了在每轮循环中将系统时间转换为秒。
类型别名
1、预处理器

#define BYTE char

用char替换所有的BYTE,BYTE成为char的别名。
2、关键字typedef

typedef typeName aliasName

指针也适用:

typedef char * byte_pointer   //让byte_pointter成为char指针的别名

#define不适用与声明一系列变量的情况。

#define FLOAT_POINTER float * 
FLOAT_POINTER pa, pb
//预处理置换转换后:
float *pa, pb   //pa为指针,而pb为float

相应的typedef:

typedef float * FLOAT_POINTER
FLOAT_POINTER pa, pb
预处理置换转换后:
float *pa, pb   //pa、pb皆为指针

统一用typedef作为定义变量别名的方法。
类型别名可提高代码阅读性,参考上页代码中的int的别名clock_t,一目了然。

5.3 do while循环

语法:

do
     body
while(test-expression);

出口条件循环,首先执行循环体,再判定测试表达式,决定是否继续执行循环。
do while循环常用于用户输入。

cin >> n ;
while(n != 7)
{
    cin >> n;
}
//可用do while更为简洁:
do 
{
   Cin >> n;
}while(n != 7)

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

double prices[5] = {1, 2, 3, 4, 5};
for(double x : prices)
   cout << x << endl;   //输出prices中的所有值

同样也可使用 for (int x : {3, 5, 6, 7})

5.5 循环和文本输入

5.5.1 使用原始的cin进行输入

程序使用循环读取来自键盘的文本输入,在遇到某个特定字符(哨兵字符)时停止读取输入。

cin >> ch

cin会忽略空格和换行符,因此输入中的空格不会被回显,且不会被计数。

5.5.2 使用cin.get(char)进行补救

cin.get(char)可对上述问题进行补救,可以对下一个字符即使是空格并赋值给ch。

cin.get(ch)

5.5.4 文件尾条件

使用诸如#等符号作为输入结束偶尔不太适用,因为该符号可能也是合法输入的组成部分。
可使用检测文件尾EOF技术。UNIX可在行首按下Ctrl+D实现;WIN命令提示符模式下,可以在任意位置按Ctrl+Z和Enter。具体情况或有各异。

5.6 嵌套循环和二维数组

C++没有提供二维数组类型,但用户可以创建每个元素本身都是数组的数组。
int temperature[4][5]
temperature是一个包含4个元素的数组,其中每个元素都是一个由5个整数组成的数组,4行5列。
for循环打印:

for (int row =0; row < 4; row ++)
{
   For (int col = 0; col < 5; ++ col)
        {
               Cout << temperature[row][col] << “\n”;
        }
    cout << endl; 
}

char指针数组中每个元素都是一个char指针,可被初始化为一个字符串的地址,例如:

const char * cities[5] = 
{
      “Gribble City”,
      “Grubbletown”,
      “New Gribble”,
}

这个例子也可以使用char数组的数组,如下:

char cities[3][25] = 
{
      “Gribble City”,
      “Grubbletown”,
      “New Gribble”,
}

char指针和char数组的数组,从存储空间角度,使用指针数组更为经济;但如果要修改其中的字符串,则使用二维数组更为方便。
此外,还可以使用string对象数组:

string cities[3][25] = 
{
      “Gribble City”,
      “Grubbletown”,
      “New Gribble”,
}

在字符串可修改的情况下,string类自动调整大小的特性使这种方法比使用二维数组更为方便

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我宿孤栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值