精华内容
下载资源
问答
  • 对于未定义行为C++标准没有明确规定编译器们应该怎么做,那么执行的结果就是不可预料的。下面我们来详细探讨下
  • C/C++未定义行为

    2017-03-29 09:50:15
    下列 C 代码中,不属于未定义行为的有:______。 int i=0;i=(i++); char *p=”hello”;p[1]=’E’ char *p=”hello”;char ch=*p++ int i=0;printf(“%d%d\n”,i++ i--) 都是未定义行为 都不是...
    下列 C 代码中,不属于未定义行为的有:______。 
    
    • int i=0;i=(i++);
    • char *p=”hello”;p[1]=’E’
    • char *p=”hello”;char ch=*p++
    • int i=0;printf(“%d%d\n”,i++ i--)
    • 都是未定义行为
    • 都不是未定义行为
    首先我应该是能选出答案的,但是因为优先级没有弄清楚,看到C选项。

    出自:http://www.jb51.net/article/37282.htm
    *和++同处于第二级优先级,但是这个结合方向比较特殊,是从右到左。
    所以是先++,后*,所以得到的是p[1],并没有改变字符串的字符。
    关于未定义行为:

    未定义行为(Undefined Behavior)是指C语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。一句话,未定义行为就是运行结果不确定
    1.变量即是左边结果,又是右边的操作数,如a+=a++,a %= b ^= a ^= b ^= a
    2.使用越界数组也是C的一个“未定义行为”
    3.允许一个随便指的指针的读写。
    4.使用未初始化的变量
    等等
    参考 http://blog.jobbole.com/53211/
    题目链接:https://www.nowcoder.com/questionTerminal/8e273aeb2b4147fea72ff08814fc78e6

    展开全文
  • a[n]里面能装n个数,可这是从0开始装的,当我们从1开始装的时候,最大的数组下标是n-1,可上面那段代码我们却让它给数组下标为n的数组赋值,因此发生了数组越界,也就是未定义问题。 改成如下代码即可: #include ...

    我们先来看看下面的代码:

    #include <iostream>
    using namespace std;
    const int N = 100010;
    int a[N];
    int main()
    {
    	for (int i = 1;i<=N;i++) a[i] = 2;
    	return 0;
    }
    

    当我们写这段代码的时候,编译器就会发生这样的问题。

    在这里插入图片描述
    这是为什么呢???

    其实是发生了数组越界

    a[n]里面能装n个数,可这是从0开始装的,当我们从1开始装的时候,最大的数组下标是n-1,可上面那段代码我们却让它给数组下标为n的数组赋值,因此发生了数组越界,也就是未定义问题。

    改成如下代码即可:

    #include <iostream>
    using namespace std;
    const int N = 100010;
    int a[N];
    int main()
    {
    	for (int i = 1;i<=N-1;i++) a[i] = 2;
    	return 0;
    }
    

    注意:

    #include <iostream>
    using namespace std;
    const int N = 100010;
    int a[N];
    int main()
    {
    	for (int i = 0;i<=N;i++) a[i] = 2;
    	return 0;
    }
    

    这样也是越界,只要我们给数组下标为n赋值,就是越界。

    展开全文
  • 在一些程序语言中,在某些情况下存在着一些未定义行为,其中以C和C++最为著名,在C++中,规定某些操作的行为是未定义的。这些未定义行为往往会导致一些程序的错误问题的出现,作为一名合格的程序员,应该极力避免...

    前言

    在一些程序语言中,在某些情况下存在着一些未定义行为,其中以C和C++最为著名,在C++中,规定某些操作的行为是未定义的。这些未定义行为往往会导致一些程序的错误问题的出现,作为一名合格的程序员,应该极力避免这些未定义行为的出现,让程序的运行结果不会说出现不确定的情况。

    总结

    在C++中的常见的未定义行为主要有以下几种:

    数组越界问题

    在C++中,数组越界问题是一个重灾区,也是很多人容易疏忽的点。比如以下的程序

    const int ARR_SIZE = 10;
    int arr[ARR_SIZE];
    bool func(int i)
    {
        cout<<arr[i]<<endl;
        return true;
    }
    
    

    不对函数的入参进行校验,以判断其下标是否越界,就容易出现数组的越界问题,导致程序在某些情况下可能访问了非法内存进而导致程序崩溃。正确的做法,应该严格校验下标参数,防止出现数组越界问题。如下:

    const int ARR_SIZE = 10;
    int arr[ARR_SIZE];
    bool func(int i)
    {
        if(i >= 0 && i < ARR_SIZE)
        {
            cout<<arr[i]<<endl;
            return true;
        }
        return false;
    }
    
    

    非法多次释放同一块内存空间

    在C++中,提供了我们new跟delete的操作符来进行内存管理,这就是使得程序员有了很大的便利性,但是,对这两个操作符倘若使用不够恰当就可能会导致内存泄漏或者未定义行为。比如以下代码:

    bool func()
    {
        int *p = new int;
        delete p;
       	
        delete p;
    }
    

    在这里,由于程序员的疏忽,导致p指针指向的内存空间被释放了两次,这种非法操作也会导致程序未定义行为,导致程序出现不确定的运行结果。

    不恰当使用容器的erase操作

    在C++中,容器的出现确实给程序员带来了很多便利,但是如果操作不当便可能导致一些未定义行为,比如erase操作

    成员函数erase是从容器中指定位置删除元素。这无疑是个非常便利以及常用的成员函数,但是如果使用不恰当,便很容易出现程序出现错误的情况,一些粗心的程序员可能会写出下面的程序:

    bool func()
    {
        vector<int> vec = {1, 3, 4,5,9,5,6,7,5};
       	vector<int>::iterator it = vec.begin();
        for(; it != vec.end(); ++it)
        {
            if(*it == 5)
            {
                vec.erase(it);
            }
        }
        return true;
    }
    

    这里的原因便是erase函数在删除完元素,迭代器会失效,成为一个无效值,这样,再次执行 ++it 操作时便会导致未定义行为,因此,为了避免删除完元素的迭代器失效,导致程序崩溃,程序应该修改成这样:

    bool func()
    {
        vector<int> vec = {1, 3, 4, 5, 9, 5, 6, 7, 5};
       	vector<int>::iterator it = vec.begin();
        for(; it != vec.end();)
        {
            if(*it == 5)
            {
                vec.erase(it++);  //在C++11中,也可以这样写: it = vec.erase(it);
            }
            else
            {
                ++it;
            }
        }
        return true;
    }
    

    其他

    除了这些之外,在C++中还有很多其他未定义行为,比如说:

    • 除以0
    int res = 10 / 0;
    

    使用指针进行非法操作,如下:

    const int i = 10;
    int *p = (int*)&i;
    *p = 2;
    

    此时i被程序被声明为const的,即不能修改的,直接通过赋值对i进行修改并不能通过编译,但是通过指针,则能通过编译,i的值也由编译器决定。

    展开全文
  • C++未定义行为

    2015-06-30 15:53:00
    今天算是长见识了。引用自《C语言undefined ...同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功...

      今天算是长见识了。引用自《C语言undefined behaviour未定义行为》http://www.itoldme.net/archives/904

    C语言中的未定义行为(Undefined Behavior)是指C语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。

      所以,避免未定义行为,是个明智的决定。本文将介绍几种未定义行为,同时欢迎读者纠错和补充。

    1.同一运算符中多个操作数的计算顺序(&&、||、?和,运算符除外)

      例如:x = f()+g(); //错误

      f()和g()谁先计算由编译器决定,如果函数f或g改变了另一个函数所使用变量的值,那么x的结果可能依赖于这两个函数的计算顺序。

    参考: 《C程序设计语言(第2版)》 P43

    2.函数各参数的求值顺序

      例如: printf("%d,%d\n",++n,power(2,n)); //错误

      在不同的编译器可能产生不同的结果,这取决于n的自增运算和power调用谁在前谁在后。

    需要注意的是,不要和逗号表达式弄混,都好表达式可以参考这篇文章:c语言中逗号运算符和逗号表达式

    参考: 《C程序设计语言(第2版)》 P43

    3.通过指针直接修改 const 常量的值

      直接通过赋值修改const变量的值,编译器会报错,但通过指针修改则不会,例如: 

    int main()
    {
        const int a = 1;
        int *b = (int*)&a;
        *b = 21;
     
        printf("%d, %d", a, *b);
        return 0;
    } 

    a输出值也由编译器决定。

    转载于:https://www.cnblogs.com/nobbyoucanyouup/p/4610768.html

    展开全文
  • 【C++】C++未定义行为

    2018-10-18 20:28:00
    未定义行为:语言标准没有规定,编译器自行决定的行为,在不同的编译器上有时会有不同的结果。 1: int i=0; i=i++; 我们知道i++会返回i之后再自增,那么程序运行完i为多少? 解释一:i=i;i++;先赋值再自增。 解释...
  • C/C++未定义行为

    2017-08-29 10:20:25
    C/C++未定义行为
  • c / c++ 编程当中会遇到一些未定义行为 这些行为多数和c/c++标准当中的定义不明确有关系 第一种,操作数的执行顺序 标准当中,只有四个操作数有过明确的执行顺序: 逻辑运算符&&和|| 从左到右,...
  • 有关C/C++未定义行为

    2018-01-10 16:25:40
    未定义行为(undefined behavior)在计算机程序设计中,未定义行为(英语:undefined behavior)是指行为不可预测的计算机代码。
  • 今天写代码时,遇到了一个小问题,然后用程序验证了下,事实证明不是所有的事情都跟自己想...所以说C/C++语言中有好多未定义行为,等号这种编译器并不一定先计算右边,然后赋值给左边,这些都是由编译器决定的。
  • C/C++中的未定义行为

    千次阅读 2019-06-28 21:20:18
    文章目录未定义行为(Undefined Behavior)C和C++未定义行为的一些例子尝试修改字符串字面量会产生未定义行为除以零会导致未定义行为某些指针操作可能导致未定义行为到达返回数值的函数(除main函数以外)的结尾,...
  • C++中的未定义行为

    2021-01-20 03:35:01
    现在我们需要一个程序从控制台读入一个 INT 型整数(输入确保是INT),然后输出...好了,欢迎走进未定义行为 (Undefined Behavior) 的世界。  什么是未定义行为  文章一开始的程序中用到了 abs 求值函数,当n为
  • c++中的未定义行为

    2019-01-09 18:07:13
    概念:C语言中的未定义行为(Undefined Behavior)是指C语言标准未做规定的行为; 1.同一运算符中多个操作数的计算顺序(&amp;&amp;、||、?和,运算符除外) 例如:x = f()+g(); //错误 f()和g()谁先计算...
  • 当前的C与C++编译器将利用未定义行为来生成高效代码(大量的例子在这里及这里),但不一致或者不好。是时候让我们严肃对待这个问题了。在本文,我将证明利用未定义行为可以显著提升代码速度,同时100%符合
  • 什么是未定义行为 简单地说,未定义行为是指C语言标准未做规定的行为。编译器可能不会报错,但是这些行为编译器会自行处理,所以不同的编译器会出现不同的结果,什么都有可能发生,这是一个极大的隐患,所以我们应该...
  • 如果对象是带符号的,那么位运算如何处理符号位依赖于机器,而且此时左移可能改变符号位,一次是一种未定义行为。 //强烈建议位运算用于处理无符号位   指针比较: 任意的毫无关联的两个指针进行比较是毫无...
  • 摘 要:自增自减运算符是C语言的一个特色,本文通过表达式中对一个变量进行多次自增或自减运算时产生的未定义行为进行了详细介绍,望帮助大家正确使用自增自减运算符。关键词:C;自增自减运算符;未定义行为中图...
  • C++ 中的未定义行为

    2016-09-18 23:19:26
    C++ 程序经常因为未定义行为而出现各种千奇百怪的 Bug,调试起来也十分困难。相反,其他很多语言中并没有未定义行为,比如 python,当访问 list 越界时会抛出 list index out of range ,这些语言中不会因为未定义...
  • 导致C++中产生未定义行为

    千次阅读 2019-03-12 21:24:48
    1、位运算: ...因此会产生未定义行为。 关于符号位如何处理C++标准没有明确规定,所以强烈建议将位运算用于处理无符号类型。因此,在使用位运算的过程中,因尽量将对象声明为无符号的,如:un...
  • C++2011程序中的一些未定义行为总结: (1)对于带符号的整型来说,赋值或者计算结果超过了范围,将是未定义行为 (2)对于内置类型变量来说,当其定义在原函数外未初始化时,会默认初始化为一个特定的值;对于函数...
  • C++中的未定义行为

    2017-09-14 16:30:41
    2.1 位运算  位运算的运算对象是整数类型...因此会产生未定义行为。 关于符号位如何处理C++标准没有明确规定,所以强烈建议将位运算用于处理无符号类型。因此,在使用位运算的过程中,因尽量将对象声明为无符号的
  • int var(1);... // 出现未定义警告,var居然未定义!!为什么?? 使用dos 命令:g++ -std=c++0x -Wall -o test test.cpp 如果是序列点的问题,那么为什么下面这条语句也是同样的warning?? cout ;
  • 首先请务必读完cppreference上...所以不明白的东西不要用,尽量避免代码中出现reinterpret_cast,因为它引发未定义行为的几率太高了 Whenever an attempt is made to read or modify the stored value of an ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,765
精华内容 7,906
关键字:

c++未定义行为

c++ 订阅