C/C++中未定义行为

来源:互联网 发布:淘宝远程付款靠谱吗 编辑:程序博客网 时间:2024/06/04 19:34
C/C++中未定义行为


下列 C 代码中,不属于未定义行为的有:______。
  • A:int i=0;i=(i++);
  • B:char *p=”hello”;p[1]=’E’
  • C:char *p=”hello”;char ch=*p++
  • D:int i=0;printf(“%d%d\n”,i++ i--)
  • E:都是未定义行为
  • F:都不是未定义行为
    查看正确选项
    正确答案:C
    A:变量即是左边结果,又是右边的操作数,如a+=a++,a %= b ^= a ^= b ^= a属于未定义行为。
    B:对于B就一种解释,常量字符串不允许修改,因为放在常量区,一修改就错,属于未定义行为。

    D:D 答案有点问题,应为,  int i=0;printf(“%d%d\n”,i++ , i--)


    一句话,未定义行为就是运行结果不确定

    在C语言中,出现未定义,简单来说有以下几种原因:
    1、变量类型没有指定。
    2、指定类型的方式与C++混淆了,特别是在.c文件中容易出现这种错误。
    3、变量指定了类型,但是与使用的变量名不符合,使用的变量名会提示为未定义。


    在C++中常见的未定义行为
    C++ 标准中有大量的未定义行为,如果在标准中查找 undefined behavior,将会看到几十条相关内容。如此众多的未定义行为,无疑给我们带来了许多麻烦,下面我们将列出一些常见的未定义行为,写程序时应该尽量避免。
    指针相关的常见未定义行为有如下内容:
    解引用 nullptr 指针;
    解引用一个未初始化的指针;
    解引用 new 操作失败返回的指针;
    指针访问越界(解引用一个超出数组边界的指针);
    解引用一个指向已销毁对象的指针;
    解引用一个指向已销毁对象的指针,有时候很容易就会犯这个错误,例如在函数中返回局部指针地址。 一些简单的错误代码如下:
    #include <iostream>


    int * get(int tmp){
        return &tmp;
    }
    int main()
    {
        int *foo = get(10);
        std::cout << *foo << std::endl; // Undefined Behavior;


        int arr[] = {1,2,3,4};
        std::cout << *(arr+4) << std::endl; // Undefined Behavior;


        int *bar=0;
        *bar = 2;                       // Undefined Behavior;
        std::cout << *bar << std::endl;
        return 0;
    }


    #include <iostream>
     
    int * get(int tmp){
        return &tmp;
    }
    int main()
    {
        int *foo = get(10);
        std::cout << *foo << std::endl; // Undefined Behavior;
     
        int arr[] = {1,2,3,4};
        std::cout << *(arr+4) << std::endl; // Undefined Behavior;
     
        int *bar=0;
        *bar = 2;                       // Undefined Behavior;
        std::cout << *bar << std::endl;
        return 0;
    }
    其他常见未定义行为如下:


    有符号整数溢出(文章开头的例子);
    整数做左移操作时,移动的位数为负数;
    整数做移位操作时,移动的位数超出整型占的位数。(int64_t i = 1; i <<= 72);
    尝试修改字符串字面值或者常量的内容;
    对自动初始化且没有赋初值的变量进行操作;(int i; i++; cout << i;)
    在有返回值的函数结束时不返回内容;
    原创粉丝点击