首页 > 试题广场 >

下列 C 代码中,不属于未定义行为的有:______。

[单选题]
下列 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://zh.wikipedia.org/wiki/%E6%9C%AA%E5%AE%9A%E4%B9%89%E8%A1%8C%E4%B8%BA
编辑于 2015-03-24 09:45:56 回复(3)
未定义行为(Undefined Behavior)是指C语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。一句话,未定义行为就是运行结果不确定
1.变量即是左边结果,又是右边的操作数,如a+=a++,a %= b ^= a ^= b ^= a
2.使用越界数组也是C的一个“未定义行为”
3.允许一个随便指的指针的读写。
4.使用未初始化的变量
等等
http://blog.jobbole.com/53211/
编辑于 2015-08-21 09:27:58 回复(6)
A选项,不知道编译器会怎么选择自增和赋值的顺序,所以这是由编译器决定的,属于未定义行为。
B选项,”hello“这个字符串属于一个字符串常量了,指针p指向了这个字符串常量,通过这个指针来直接修改常量第二个字符,这也属于未定义行为。
C选项,只是通过指针找到第二个字符并将它赋值给一个字符变量,并没有改变这个字符串常量,所以不属于未定义行为。
D选项,在printf语句中,i++和i–谁先执行由编译器决定,这是未定义行为。

故此题选C。
发表于 2018-02-26 11:42:17 回复(5)
A:在GCC下输出:0
      在VC6.0下输出:1
B:在GCC下输出:段错误 (核心已转储)
      在VC6.0下输出:已停止工作,出现了一个问题,导致程序停止正常工作。
C:正常
D:在GCC下输出:-1 0
      在VC6.0下输出:0 0

发表于 2015-08-08 19:59:56 回复(2)
对于B就一种解释,常量字符串不允许修改,因为放在常量区,一修改就错
发表于 2015-10-27 08:26:20 回复(0)
选C没错!C修改的是指针的值 没有修改指针指向常量的值 是正确的!ABD 行为结果是不可预测的 环境不同结果也不定 固都是未定义的
编辑于 2015-05-04 22:13:46 回复(2)
答案 F
解释: 所以的选项都符合语法。
发表于 2015-01-08 10:20:29 回复(6)
发表于 2015-07-15 20:52:48 回复(1)
个人观点,如果考虑有欠缺希望题友指正:
A错,因为i++返回的是0,而此时i应该是1。然后又让i=0,不同编译器的不同入栈方式,可能得到i=0或i=1两种结果。
B错,因为一个指针企图修改一个const char*编译器是不允许的吧。
C没问题,c去读一个const char*,ch=‘c’。
D错,与A类似。我们希望得到的结果是01,但是由于不同编译器printf的入栈顺序有所差异,可能会得到00(先计算i--,再计算i++)的结果。
综上叙,E F不正确,由此得到C。
发表于 2017-12-03 10:20:10 回复(1)
选C  可以去看看楼上伙计提供的维基百科连接,里面有很多例子。未定义行为 英语undefined behavior )是指行为不可预测的计算机代码。
发表于 2015-04-01 18:20:02 回复(3)

指针相关的常见未定义行为有如下内容:

  • 解引用 nullptr 指针;
  • 解引用一个未初始化的指针;
  • 解引用 new 操作失败返回的指针;
  • 指针访问越界(解引用一个超出数组边界的指针);
  • 解引用一个指向已销毁对象的指针;

其他常见未定义行为如下:

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

更完整的未定义行为列表可以在这里找到。

详细内容参考:
http://selfboot.cn/2016/09/18/c++_undefined_behaviours/
发表于 2016-09-19 07:44:48 回复(0)
B中的p[1]='E',在VC6.0下编译没有语法错误,但链接时出错。这里的p指向一个常量,常量是不能被改变的吧,所以p[1]='E'会有错呀。
发表于 2015-01-22 15:57:11 回复(2)
A,D的输出依赖编译器。
B是错误语句,“hello”存在常量存储区,是不能改变的。
C是先取出p指向的值,即h,然后将指针p++。
发表于 2017-01-10 11:41:19 回复(0)
D 答案有点问题,应为,  int i=0;printf(“%d%d\n”,i++ , i--)
发表于 2015-08-22 11:05:51 回复(3)
C选项是先取第一个字符h,然后对h的ascll自增1,也就是i,最后的结果p还是hello,ch为i。
发表于 2023-09-05 10:54:10 回复(1)
不理解什么是未定义行为。
未定义行为(Undefined Behavior)是指C语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。一句话,未定义行为就是运行结果不确定
1.变量即是左边结果,又是右边的操作数,如a+=a++,a %= b ^= a ^= b ^= a
2.使用越界数组也是C的一个“未定义行为”
3.允许一个随便指的指针的读写。
4.使用未初始化的变量
发表于 2022-06-12 19:18:29 回复(0)
int i=0;i=(i++);不知道编译器会怎么选择自增和赋值的顺序,所以这是由编译器决定的,属于未定义行为。
char *p=”hello”;p[1]=’E’“hello”这个字符串属于一个字符串常量了。指针p指向了这个字符串常量,通过这个指针来直接修改常量第二个字符,这也属于未定义行为。
char *p=”hello”;char ch=*p++ 只是通过指针找到第二个字符并将它赋值给一个字符变量,并没有改变这个字符串常量,所以不属于未定义行为。

在printf语句中,i++和i--谁先执行由编译器决定,这是未定义行为。
编辑于 2021-06-24 10:05:39 回复(0)
关于B选项,需要注意的是char* p = "hello";语句定义了一个指向字符串字面量"hello"的指针p,该字符串字面量位于全局只读存储区中(.rodata段),故一般而言字符串字面量中的字符是不可被改变的(至少gcc编译器中,会出现内存错误)。

发表于 2021-03-06 13:35:13 回复(0)
jzx头像 jzx
c修改的是指针的值,没修改指针指向常量的值
发表于 2021-02-28 17:31:15 回复(0)
个人观点
A选项
个人觉得这就是程序执行顺序的问题,++i  和i++  ,i++ 是下一个循环才会执行加1操作;
(1) i=i++------>先执行赋值i=i  -------> 结果是i=0;
(2)i=i++------>后执行 i = i + 1 -------> 结果是i=1;
所以,这就不行了呗,你让人家等于啥 →_→😌
编辑于 2019-09-12 09:19:11 回复(0)