语句【C++】
- 简单语句
- 空语句
- 复合语句
- 条件语句
- if 语句
- switch 语句
- 迭代语句
- while语句
- 传统 for 语句
- 范围 for 语句(C++11)
- do while 语句
- 跳转语句
- break 语句
- continue 语句
- goto 语句
简单语句
大多数语句以分号结束。
ival + 5; //没有实际用处的表达式
cout<<ival; //有用的表达式
空语句
只包含一个单独的分号:
;
用处:
循环的全部工作在条件部分完成。
while (cin >> s && s != sought)
; //空语句
注意:使用空语句是应该加上注释,令读这段代码的人知道该语句是有意省略的。
可以在任何允许使用语句的地方使用空语句。
ival = v1 + v2;; //正确:第二个分号表示一条多余的空语句
多余的空语句并非总是无害的。
while (iter != svec.end()); //while 循环体是那条空语句
{
++iter; //递增运算不属于循环的一部分
}
复合语句
花括号括起来的语句和声明的序列,也被称作 块 。
{
//块
}
程序语法上需要一条语句,逻辑上需要多条语句时,使用复合语句。
代码演示:while循环计算 0 到 10 的和。
#include <iostream>
using namespace std;
int main()
{
int val = 0;
int sum = 0;
while (val <= 10)
{
sum += val;
++val;
}
cout << "sum: " << sum << endl;
return 0;
}
运行结果:
代码演示:for循环计算 0 到 10 的和。
#include <iostream>
using namespace std;
int main()
{
int sum = 0;
for (int val = 0; val <= 10; ++val)
{
sum += val;
}
cout << "sum: " << sum << endl;
return 0;
}
运行结果:
块不以分号作为结束。
{//块开始
//块内部
}//块结束,无 ;
空块:内部没有任何语句的一对 { }
,等价于空语句。
{}
条件语句
if 语句
if 语句:
if (condition) //condition为真 执行statement
statement
if else 语句:
if (condition)//condition为真 执行statement
statement
else //condition为假 执行statement2
statement
condition
必须能够转换为 bool
。
注意使用花括号:作为块执行的语句没有添加花括号。
代码演示:作为块执行的语句没有添加花括号。
#include <iostream>
using namespace std;
int main()
{
bool b = false;
if (b)
cout << "yes" << endl;
else
cout << "no" << endl;
cout << "error" << endl;
return 0;
}
运行结果:
本质上我们希望 b
为 false
的时候 打印 no
和 error
,但是上面程序无论 b
的值为 false
或 true
, error
都会打印。
上面的错误非常难发现,因为没有任何语法错误。
修改:在while、for、 if 和 else 之后必须写上花括号,避免代码混乱不清。
代码演示:作为块执行的语句没有添加花括号。
#include <iostream>
using namespace std;
int main()
{
bool b = true;
if (b)
{
cout << "yes" << endl;
}
else
{
cout << "no" << endl;
cout << "error" << endl;
}
return 0;
}
运行结果:
悬垂else问题: if
嵌套语句中,if
分支多余 else
。
C++解决: else
和最近尚未匹配的 if
匹配。
代码演示:C++解决悬垂else问题。
#include <iostream>
using namespace std;
int main()
{
bool b1 = true;
bool b2 = true;
bool b3 = true;
if (b1)
if (b2)
if (b3)
cout << "true" << endl;
else//和 if (b3) 匹配
cout << "false" << endl;
return 0;
}
如果想让 else
或者 if (b2)
或者 if (b2)
匹配,则可以在内层 if
语句两端加上 { }
使其成为一个 块
。
代码演示:else 和非最近未匹配的 if 匹配。
#include <iostream>
using namespace std;
int main()
{
bool b1 = true;
bool b2 = true;
bool b3 = true;
if (b1)
{
if (b2)
{
if (b3)
{
cout << "true" << endl;
}
}
else//和 if (b2) 匹配
{
cout << "false" << endl;
}
}
return 0;
}
运行结果:
switch 语句
#include <iostream>
using namespace std;
int main()
{
int switch_on = 3;
switch (switch_on) //switch_on 表达式必须能够转换成整数,然后与所有 case匹配。
{
case 1: //标签后面必须跟一条语句或者另一个 case标签。
break;
case 2: //switch_on 和某一个 case 匹配成功,从该case下一行开始顺序执行所有case分支,直到swith结尾或遇到break。
break;
case 3: //下一个 case 标签之前应该有一条 break 语句。
break; //break:中断当前控制流,转移控制权到 switch 语句外。
case 4:
break; //任何两个 case 标签不能相同。
case 5: //case 选项数量固定
break;
default: //和所有 case 不匹配,执行 default 标签。default 标签后面必须跟上一条空语句或空块。
break; //一般不要省略最后一个case分支的break语句。如果没有写请注释说明。
}
return 0;
}
代码演示:case标签执行完成后加break影响效果。
#include <iostream>
using namespace std;
int main()
{
int switch_on = 3;
switch (switch_on)
{
case 1:
cout << "case 1" << endl;
break;
case 2:
cout << "case 2" << endl;
break;
case 3: //匹配
cout << "case 3" << endl; //执行
break; //退出 switch语句
case 4:
cout << "case 4" << endl;
break;
case 5:
cout << "case 5" << endl;
break;
default:
cout << "default" << endl;
break;
}
return 0;
}
运行结果:
代码演示:case标签执行完成后不加break影响效果。
#include <iostream>
using namespace std;
int main()
{
int switch_on = 3;
switch (switch_on)
{
case 1:
cout << "case 1" << endl;
case 2:
cout << "case 2" << endl;
case 3: //匹配
cout << "case 3" << endl; //执行
case 4:
cout << "case 4" << endl; //执行
case 5:
cout << "case 5" << endl; //执行
default:
cout << "default" << endl; //执行
}
return 0;
}
运行结果:
switch 内部的定义变量:
switch 跳转到某个特定 case,该 case 标签之前的部分会被忽略。
疑问:如果被忽略的部分还有变量定义怎么办?
解答:初始化变量(包括显示和隐式)和使用变量跳跃 case 属于非法行为,未初始化的变量则不影响。
代码演示:初始化变量和使用变量跳跃 case属于非法行为。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int switch_on = 2;
switch (switch_on)
{
case 1: //程序跳过 case1 执行 case2,绕开初始化语句。
cout << "case 1" << endl;
int num1 = 10; //num 显式初始化为10
string str; //str 隐式初始化为空字符串
break;
case 2: //编译器报错位置,带有初值的变量跳跃标签 case2
cout << "case 2" << endl;
cout << num1 << endl; //不允许跨过初始化语句直接跳转到另外的位置。
cout << str << endl; //不允许跨过初始化语句直接跳转到另外的位置。
break;
default:
cout << "default" << endl;
break;
}
return 0;
}
编译器报错:
代码演示:未初始化变量和使用变量跳跃 case 赋值和使用则不影响。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int switch_on = 2;
switch (switch_on)
{
case 1:
cout << "case 1" << endl;
int num1;
break;
case 2:
cout << "case 2" << endl;
num1 = 10;
cout << num1 << endl;
break;
default:
cout << "default" << endl;
break;
}
return 0;
}
运行结果:
如果某个 case 定义并初始化变量,应该把变量定义在块内,确保后面所有 case 都在变量的作用域之外。
代码演示:把变量定义在块内,确保后面所有 case 都在变量的作用域之外。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int switch_on = 1;
switch (switch_on)
{
case 1:
{
cout << "case 1" << endl;
int num1 = 10;
string str;
cout << num1 << endl;
cout << str << endl;
break;
} //出块,num1 和 str无法被访问到。
case 2:
cout << "case 2" << endl;
break;
default:
cout << "default" << endl;
break;
}
return 0;
}
运行结果:
迭代语句
迭代及循环,重复执行操作直到满足某个条件才停下来。
- while 语句:执行循环体前先检查条件。
- for 语句:执行循环体前先检查条件。
- do while 语句:先检查条件再执行循环体。
while语句
语法:
while(condition)
statement
执行过程:while语句
通常由条件本身或循环体改变condition
的值,否则可能循环无法终止。
定义在condition
和statement
的变量每次迭代都经历从创建到销毁。
#include <iostream>
#include <string>
using namespace std;
int main()
{
while (int i = 1)//创建i
{
int j = 2;//创建j
}//销毁 i , j
return 0;
}
当不确定到底要迭代多少次时,使用 while 循环更合适。
代码演示:当不确定到底要迭代多少次时,使用 while 循环更合适。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num = 10;
while (cin >> num)
{
if (20 == num)
{
cout << num << endl;
}
}
return 0;
}
运行结果:
传统 for 语句
for(init-statemen;condition;expression)
statement
执行过程:传统 for 语句
init-statemen
必须是三种格式之一:
- 声明语句。
- 表达式语句。
- 空语句。
for 语句头中定义的对象只在for循环体中可见。
init-statemen
可以用多个对象,但是只能有一条声明语句,所有变量的基础类型相同。
代码演示:
#include <iostream>
#include <string>
using namespace std;
int main()
{
for (int i = 0, j = 5,k = 10; i < 3; ++i)
{
cout << "i: " << i << " ,j: " << j << " ,k: " << k << endl;
}
return 0;
}
运行结果:
省略 for 语句头的某些部分或全部,但是分号必须保留。
- 省略
init-statemen
:无需初始化时使用。 - 省略
condition
:等价于条件部分永远是true
。statement 中必须要有语句负责退出循环,否则就会死循环。 - 省略
expression
:循环体或者条件部分必须改变迭代变量的值。
范围 for 语句(C++11)
遍历所有容器或其他序列。
for (declaration:expression)
statement
expression
必须是一个序列:初始值列表、数组、vector、string等拥有能返回迭代器成员 begin
和 end
成员。
declaration
定义一个变量,序列中每个元素都能转换成该变量的类型,最简单的方法是使用 auto
自动推导。
需要需要对序列元素执行写操作,循环变量必须声明成引用类型。
每次迭代重新定义循环控制变量,并将其初始化成序列中的下一个值,之后执行 statement。
statement 可以是一条单独的语句,也可以是语句块。
代码演示:把 vector 对象中的每个元素翻倍。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<int> vi = { 0,1,2,3,4,5};
for (auto& r : vi)
{
cout << r << " ";
}
cout << endl;
for (auto& r : vi)
{
r *= 2;
cout << r << " ";
}
return 0;
}
运行结果:
范围 for 语句的定义来源于与之等价的传统 for 语句。
代码演示:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<int> vi1 = { 0,1,2,3,4,5};
for (auto& r : vi1)
{
cout << r << " ";
}
cout << endl;
for (auto& r : vi1)
{
r *= 2;
cout << r << " ";
}
cout << endl;
vector<int> vi2 = { 0,1,2,3,4,5 };
for (auto beg = vi2.begin(), end = vi2.end(); beg != end; ++beg)
{
auto& r = *beg;
cout << r << " ";
}
cout << endl;
for (auto beg = vi2.begin(), end = vi2.end(); beg != end; ++beg)
{
auto& r = *beg;
r *= 2;
cout << r << " ";
}
return 0;
}
for (auto beg = vi2.begin(), end = vi2.end(); beg != end; ++beg)
等价于
for (auto& r : vi1)
运行结果:
强调:不能通过范围 for
语句增加 vector
对象(其他容器)的元素,因为在范围 for
语句中,预存了 end()
的值。一旦序列中添加或删除元素,end
函数的值可能变得无效。
do while 语句
do while语句先执行循环体后检查条件。
不管条件值如何,至少执行一次循环。
do
statement
while(condition);
while(condition)
后面用 ;
表示语句结束。
condition
不能为空。
condition
使用的变量必须定义在循环体之外。
不允许在条件中定义变量:
说明:对于 do while 语句来说先执行语句或块,后判断条件,如果允许在条件部分定义变量,则变量使用出现在了定义之前是不合理的。
执行过程:do while 语句
跳转语句
中断当前执行过程。
4种:break
,continue
,goto
,return
。
break 语句
终止离它 最近的 while,do while,for,switch 语句,并从这些语句之后第一条语句开始执行。
只能出现在 循环语句 或者 switch语句 内部(包括嵌套在此类循环里面的语句或块的内部)。
代码演示:for语句,while语句,do while 语句,switch语句中的 break
#include <iostream>
#include <string>
using namespace std;
int main()
{
for (int num = 10; num <= 10; ++num)
{
if ( num < 0)
{
break; //#1离开 for 循环
}
while (num > 100)
{
if (num % 3)
{
break; //#2离开 while 循环
}
do
{
if (++num)
{
break; //#3离开 do while 循环
}
switch (num--)
{
case 10:
cout << "num" << endl;
break; //#4离开 switch 语句
case 20:
break;
default:
break;
}//#4将控制权转移到这里
} while (num*=2);//#3将控制权转移到这里
}//#2将控制权转移到这里
}//#1将控制权转移到这里
return 0;
}
说明:上述代码仅用来说明 break 语句的转移权跳转,无实际功能意义。
continue 语句
终止最近的循环中的当前迭代,并立即开始执行下一次迭代。
只能出现在 for
、while
、do while
循环的内部或嵌套在此类循环里的语句或块的内部。
代码演示:
#include <iostream>
#include <string>
using namespace std;
int main()
{
for (int num = 10; num <= 10; ++num)
{
if ( num < 0)
{
continue; //终止当前迭代,进入下一次 for 循环迭代
}
while (num > 100)
{
if (num % 3)
{
continue; //终止当前迭代,进入下一次 while 循环迭代
}
do
{
if (++num)
{
continue; //终止当前迭代,进入下一次 do while 循环迭代
}
} while (num*=2);
}
}
return 0;
}
只有 switch 语句嵌套在循环语句内部时,才能在switch 中使用 continue。
goto 语句
不要在程序中使用 goto 语句,因为它会使程序难以理解和修改。