我想访问表单的几个变量:
int arr1=1;
int arr2=1;
int arr3=1;
所以我写了
#define arr(i) arr##i
但是下面的代码片段并不像我期望的那样工作
#include <stdio.h>
int main(){
int arr1=1;
int arr2=1;
int arr3=1;
int j;
for(j=1; j<3; j++)
printf("%d",arr(j));
return 0;
}
答案 0 :(得分:6)
你不能这样做。变量名在运行时不存在于C.
中您的宏将扩展为arrj
,这是一个未定义的变量名称。使用正确的数组:
int arr[] = { 1, 1, 1 };
然后打印arr[j]
,但循环如下:
for(j = 0; j < sizeof arr / sizeof *arr; ++j)
printf("%d\n, arr[j]);
答案 1 :(得分:3)
宏代码用于预处理器阶段,而不用于运行时阶段
如果使用gcc -E
生成预处理器代码。您将看到您的代码等同于:
int main(){
int arr1=1;
int arr2=1;
int arr3=1;
int j;
for(j=1; j<3; j++)
printf("%d",arrj);
return 0;
}
当你构建你的程序时,gcc会从你的c代码中生成anoter c代码,并在其中用宏内容替换你代码中的所有宏(这个阶段叫做preprocesser阶段)。然后生成asm代码,然后生成二进制文件。
您可以通过gcc -E
:预处理器阶段代码
答案 2 :(得分:0)
因此,结果会产生arrj
。
C的宏阶段是在程序运行之前发生的事情,甚至在它被解析为实际C之前。
很久以前,预处理器是一个完全独立的程序,对C语言知之甚少。
与今天的大多数编译器一样,cc
当时只运行了不同的阶段。在运行编译器,汇编器和链接器之前,它运行cpp
, C预处理器。
cpp 刚刚解析了定义,然后扩展了宏,然后退出了。然后 cc 将运行编译器。目前,宏扩展内置于编译器中,但它根据原始设计处理程序的文本输入。
今天在某些系统上仍有/usr/bin/cpp
,但它通常只是一个shell脚本,它运行编译器映像,其中包含不编译的选项。