zoukankan      html  css  js  c++  java
  • c++中的陷阱(二)

    导言###

    程序设计语言中充满陷阱,一不小心就会掉入其中万劫不复,之所以有陷阱,是因为语言的设计细节不符合程序员的直觉
    所以你会发现,语言越高级越注重顺从程序员的直觉。
    c++也有许多陷阱,所谓山不过来,我就过去,因此将c++中易错点、难点集合于此,会不定期更新。
    参考:c++中的陷阱(一)


    控制语句###

    1. 在swtich语句中存在一个普遍的误解,以为程序只会执行匹配的case标号相关联的语句,实际上,程序从该点开始执行,并跨越case边界继续执行其他语句,直到swtich结束或遇到break

    2. 对于switch结构,只能在它的最后一个case标号或default标号后面定义变量,这是为了避免出现代码跳过变量的定义和初始化的情况。如果需要为某个特殊的case定义变量,则可以引入块语句,在该块语句中定义变量,从而保证这个变量在使用前被定义和初始化。

    char c = 'b';
    switch(c){
    case 'b':
      {
        int i = 0;           //right  i定义在语句块中
        cout<<"b"<<endl; 
      }
    case 'c':
      cout<<"c"<<endl;
    default:
      ;
    }
    
    char c = 'b';
    switch(c){
    case 'b':
      int i = 0;           //error
      cout<<"b"<<endl; 
    case 'c':
      cout<<"c"<<endl;
    default:
      ;
    }
    
    1. do-while语句中,任何在循环条件中引用的变量都必须在do语句之前就已经存在
    string input;
    do{
      cout<<input<<endl;
      cin >> input;
    }while(input != "bye");   //right
    
    do{
      string input;
      cout<<input<<endl;
      cin >> input;
    }while(input != "bye");   //error 变量input只存在于花括号的块作用域中
    
    while(bool status = true){   //right
      cout<<"hello"<<endl;
    }
    
    do{
      cout<<"hello"<<endl;
    }while(bool status = true);   //error 变量status必须在do语句之前就已经存在
    

    函数###

    1. 返回值为void的函数,return后一般不能接表达式,但有一个例外,即返回另一个返回类型同样是void的函数的调用结果
    void func1(){}
    void func2(){return func1();}  //right
    int main(){
      func2();
      return 0;
    }
    
    1. 函数的返回值是引用类型时,谨记不能返回局部对象的引用。因为在函数执行完毕时,将释放分配给局部对象的存储空间,此时,对局部对象的引用就会指向不确定的内存

    2. 函数的返回值是指针时,谨记不能返回局部对象的指针,理由同上

    3. 返回引用的函数返回一个左值,因此可以给返回的引用赋值

    int &func(int &i){return i;}
    int main(){
      int ival = 0;
      cout<<ival<<endl;   // 0
      func(ival) = 1;     //func返回引用,因此返回的是一个左值
      cout<<ival<<endl;   // 1
      return 0;
    }
    
    1. const对象、指向const对象的指针或引用只能用于调用其const成员函数,如果尝试用他们调用非const成员函数,则是错误的

    2. 区分重载与非重载
      非重载

    int func(const int i);
    int func(int i);
    int func(int *const i);
    int func(int *i);
    
    typedef int integer;
    int func(int i);
    int func(integer i);
    
    void fun(int i=0);
    void fun(string s="");
    

    重载

    int func(const int &i);
    int func(int &i);
    
    int func(const int *i);
    int func(int *i);
    
    1. 重载函数的实参类型转换
    int func(int i){ cout<<"int func"<<endl;}
    int func(unsigned char){ cout<<"unsigned char func"<<endl;}
    int main(){
      char c = 'a';
      func(c);	 //打印 int func
    }
    /*
    char类型到int型是类型提升,char类型到unsigned char类型是类型转换,在实参匹配时类型提升优于类型转换
    实参类型的转换等级:1.精确匹配 2.通过类型提升 3.通过标准转换 4.通过类类型转换
    */
    
    int func(int i, int ii){ cout<<"int func"<<endl;}
    int func(double d, double dd){ cout<<"double func"<<endl;}
    int main(){
      int i=0;
      double d=0.0;
      func(i,d);		//error 二义性
    }
    /*
    在调用重载函数时,编译器会试图寻找最佳匹配,若无法确定唯一的最佳匹配,则报错
    */
    
    enum ABC {a, b, c};
    int func(ABC val){}
    int main(){
      ABC v = a;
      func(v);      //right
      func(1);	//error 不能直接将整数值作为枚举类型的实参
    }
    
  • 相关阅读:
    C语言实验报告(二)
    C语言实验报告(一)
    Modbus通信
    clip_region_rel&clip_region
    字符分割时对粘连字符的处理方法
    Labview读取二维码
    LabVIEW访问Access数据库教程
    利用Halcon寻找出边缘突出的部分
    利用Halcon提取出器件的中心部分
    Halcon中对于Tuple数据类型的操作
  • 原文地址:https://www.cnblogs.com/moonlight-chao/p/3642744.html
Copyright © 2011-2022 走看看