首页 > 试题广场 >

对以下程序,正确的输出结果是() #include #d

[单选题]
对以下程序,正确的输出结果是() <stdio.h>
#include <stdio.h>
#define SUB(x,y) x-y 
#define ACCESS_BEFORE(element,offset,value) *SUB(&element, offset) = value 
int main() { 
    int array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    int i; 
    ACCESS_BEFORE(array[5], 4, 6); 
    printf("array: "); 
    for (i = 0; i < 10; ++i) { 
        printf("%d", array[i]); 
    } 
    printf("\n"); 
    return (0); 
}
</stdio.h>
  • array: 1 6 3 4 5 6 7 8 9 10
  • array: 6 2 3 4 5 6 7 8 9 10
  • 程序可以正确编译连接,但是运行时会崩溃
  • 程序语法错误,编译不成功
本题主要是考察宏定义的替换,宏替换在预编译阶段进行,不进行语法的检查,当进行替换时,ACCESS_BEFORE(array[5],4,6)被替换成*(&array[5])-4=6 显然这是不正确的,在赋值表达式中,左值必须是一个可修改的内存块,而上述式子的左值是一个字面值常量,这是编译不能通过的
发表于 2016-04-09 13:22:27 回复(6)
这道题大家走出考场后争议非常大。咱啥也不说,直接进mingw跑一下gcc:



gcc提示的错误是“赋值号的左边操作数需要一个左值”。其原因是调用宏的那句被预处理器替换成了:
*&array[5]-4 =6;
由于减号比赋值优先级高,因此先处理减号;由于减号返回一个数而不是合法的左值,所以编译报错。
编辑于 2021-01-16 09:52:42 回复(7)
将*SUB(&element, offset) = value换成*(SUB(&element, offset)) = value就OK了!!
发表于 2016-05-05 15:47:47 回复(0)
ACCESS_BEFORE(array[5], 4, 6);这句话的意思是*&array[5]-4 =6; 也就是6 = 6;这样的语句显然是不对的,因为赋值号的左边操作数需要一个左值。将*SUB(&element, offset) = value换成*(SUB(&element, offset)) = value,ACCESS_BEFORE(array[5], 4, 6)的意思是*(&array[5]-4)=6;
也就是array[1] = 6;输出结果为16345678910
发表于 2019-01-18 10:04:20 回复(0)
编译失败
发表于 2014-10-25 00:25:53 回复(1)
*SUB(&element, offset) = value改成*(SUB(&element, offset) )= value可以成功编译得到A

发表于 2018-09-25 16:31:01 回复(0)
ACCESS_BEFORE(array[5], 4, 6);是 &array[5]-4=6的运算
发表于 2017-06-13 15:30:54 回复(0)
C语言编译分为预编译,编译,链接,最后形成可执行文件,宏替换在预编译阶段进行,不进行语法的检查,但是编译阶段会对每一表达式的合法性进行检查。
发表于 2016-09-24 16:14:12 回复(0)
因为宏定义只做文本替换,这里直接变成*(&a[5])-4=6 左边已经是一个常量2了。如果这里在*SUB加(),写成*(SUB()),这样就是可修改的内存块的值,=value赋值就没错了。或者改宏定义,给x-y外面加()
发表于 2016-08-15 11:36:19 回复(0)
等号右边必须为右值,就是可以取地址
发表于 2016-06-11 16:16:39 回复(0)
宏定义出错,单纯替换,且宏定义不进行语法错误检查
发表于 2019-10-09 21:30:29 回复(0)
这个就存在了对数组内存数据在取值,给一个常量赋值
发表于 2019-10-07 16:45:00 回复(0)
c
发表于 2019-04-28 14:47:26 回复(0)

优先级问题,一定记得加括号

发表于 2018-08-17 09:06:39 回复(0)
define只是简单的实现,是在预编译阶段就替换的,所以不会先执行SUB;
a[5] = 4可以执行,因为数组可以改变数值,但是a[5]-1=4就不能执行了,因为左值是常量。
发表于 2018-02-07 10:42:21 回复(0)
左值的根本含义 和宏定义的替换错误
发表于 2017-07-08 17:17:28 回复(0)
为啥程序员面试宝典里面这个题选的是C
发表于 2017-06-14 17:16:30 回复(1)
此题应该是在宏定义sub时应该将x-y用夸号,避免在替换时造成优先级出问题。
发表于 2017-02-19 17:29:20 回复(0)
宏定义在编译时直接替换,不会自动添加括号!!
发表于 2016-08-27 16:39:16 回复(0)
一般在这种宏定义时记得加括号,因为不确定替换部分中有没有优先级比他高的
#define SUB(x,y) x-y
#define A 3*SUB(3,3)
一个道理
发表于 2016-08-16 20:32:24 回复(0)