2016-11-03 168 views
-4

任何人都可以请解释我为什么这个代码打印1 3 0 0 0 -1,而不是1 2 3 0 0 0?这个定义的调用工作如何?此代码打印什么?为什么?

#include<stdio.h> 
#define SOMETHINGDEFINED(i) A[i%4] 

int main(void) { 
    int i, A[6] = { 1 }; 
    SOMETHINGDEFINED(1) = 2; 
    SOMETHINGDEFINED(5) = 3; 
    SOMETHINGDEFINED(4 + 2) = SOMETHINGDEFINED(1 + 3 + 1)--; 
    for (i = 0; i < 6; i++) { 
     printf("%d ", A[i]); 
    } 
    return 0; 
} 
+0

什么是4 + 2%4和1 + 3 + 1%4? – immibis

回答

2

#define做文本替换,所以

SOMETHINGDEFINED(1 + 3 + 1)-- 

成为

A[1 + 3 + 1%4]-- 

现在你可以看到模仅适用于过去的操作数,而不是整个表达式。您必须将宏定义为

#define SOMETHINGDEFINED(i) A[(i)%4] 

将其正确应用于整个表达式。

+0

其实,我有这样的任务。它问这个代码打印什么,我试图解决它,然后编译它,而VS的结果与我的不同。试过调试它,并没有得到它,所以... 嗯,谢谢杰克! :) – redbaron

1

SOMETHINGDEFINED(4 + 2) = SOMETHINGDEFINED(1 + 3 + 1)--;转化为A[4 + 2 % 4] = A[1 + 3 + 1 % 4]--;A[6]=A[5]--;即需要A[5]--A[5]即0的旧值,并返回它,然后减小A[5],则指派指派的A[5]A[6]旧值。

+0

幸运的是'1 + 3 + 1%4'是5而不是4,否则就是_undefined behavior_。 –

+0

@RolandIllig我不好,你说得对。 – grigor

1

在C中,宏是一个简单的文本替换。自己进行替换(不插入额外的括号),或者了解如何在不实际编译C编译器预处理代码的情况下进行编译。这会给你足够的信息来理解这个话题。

顺便说一句,示例代码是一个很好的演示,为什么你尽可能不要使用C宏。