C++语句


空语句

  空语句是最简单的语句,只含有一个单独的分号。如果在程序的某个地方,语法上需要一条语句但是逻辑上不需要,此时应该使用空语句。一种常见的情况是,当循环的全部工作在条件部分就可以完成时,我们通常会用到空语句,比如:

// 重复读入数据直至到达文件末尾或某次输入的值等于sought
while(cin>>s && s!=sought)
  ;   //空语句

  注意: 使用空语句是应该加上注释,从而令读这段代码的人知道该语句是有意省略的。

悬垂else

  当程序中有多个else分支,如何知道某个给定的else是和哪个if匹配,这个问题通常就称为悬垂else ,比如:

// 错误:实际的执行过程并非像缩进格式显示的那样;else分支匹配的是内层if语句
if(grade % 10>=3)
   if(grade % 10>7)
      lettergrade +='+';       //末尾是8或者9的成绩加上一个加号
else
  lettergrade +='-';            //末尾是3、4、5、6或者7的成绩添加一个减号

switch内部的变量定义

  switch的执行流程有可能会跨过某些case标签,如果程序跳转到了某个特定的case,则switch结构中该case标签之前的部分会被忽略掉。这种忽略掉一部分代码的行为引出了一个有趣的问题:如果被略过的代码中含有变量的定义该怎么办?
  答案是:如果在某处一个带有初始值的变量位于作用域之外 ,在另一处该变量位于作用域之内 ,则从前一处跳转到后一处的行为是非法行为。

case true:
 // 因为程序的执行流程可能绕开下面的初始化语句,所以该switch语句不合法
 string file_name;   // 错误:控制流绕过一个隐式初始化的变量
 int ival=0;         // 错误:控制流绕过一个显示初始化的变量
 int jval;           // 正确:因为jval没有初始化
 break;
case false:
  // 正确:jval虽然在作用域内,但是它没有被初始化
 jval = next_num();          // 正确:给jval赋一个值
 if(file_name.empty())       // file_name在作用域内,但是没有被初始化
   //....

  假设上述代码合法,则一旦控制流直接跳转到false分支,也就同时略过了变量file_name和ival的初始化过程。此时这两个变量位于作用域之内 ,跟在false之后的代码试图在尚未初始化的情况下使用它们,这显然是行不通的。因此C++语言规定: 不允许通过变量的初始化语句直接跳转到该变量作用域内 的另一个位置。
  如果需要为某个case分支定义并初始化一个变量,我们应该把变量定义在块内,从而确保后面的所有case标签都在变量的作用域之外

case true:
  {
    // 正确:声明语句位于语句块内部
    string file_name = get_file_name();
    //....
  }
  break;
case false:
	if(file_name.empty())       // 错误:file_name不在作用域之内
      //....

范围for语句

  C++11新标准引入了一种更简单的for语句,这种语句可以遍历容器或其他序列的所有元素,比如:

vector<int> v={0,1,2,3,4};
// 范围变量必须是引用类型,这样才能对元素执行写操作
for(auto &r : v)
  r *=2;

  范围for语句的定义来源于与之等价的传统for语句:

for(auto beg = v.begin(), end = v.end(); beg!=end; ++beg){
  auto &r=*beg;    // r必须是引用类型,这样才能对元素执行写操作
  r *=2;
}

  在范围for语句中,预存了end()的值。一旦在序列中添加(删除)元素,end函数的值可能就变得无效了!

原文地址:https://www.cnblogs.com/xipuhu/p/7456675.html