为什么’c ‘编译而’c ‘没有?

此示例编译时没有警告/错误(gcc 4.8.2 -Wall):

#include  int main() { char c; int i; printf("%p %02x\n",&i,c[&i]); printf("%p %02x\n",&c,c[&c]); // important to note that this line DOESN'T compile: //printf("%p %02x\n",&i,c[i]); // which makes sense as c is NOT an array, it is a char. return 1; } 

为什么语法c [&i]编译? 是故意还是意外? 语法c [&i]在语义上是否有效? (它有什么有用的意义吗?)

我的输出示例:(指针每次都改变)

 0xbfb2577c b7718cea 0xbfb2577b 08 

这个问题起源于这里有一个奇怪的代码’ch2 [&i]’: C重复字符,逐个字符

注意关于重复/类似问题的#0(在反思时更新):这个问题与c数组引用的链接问题不重复。 它是相关的,因此引用它们很有用。 相关问题讨论了有效的a [b]和b [a]情况,其中a或b中的一个是指针而另一个是int。 这个问题涉及更奇怪的,也许应该是无效的情况,其中a或b中的一个是char。 对于C数组,为什么a [5] == 5 [a]? 14答案对于数组,为什么a [5] == 5 [a]? 字符串作为数组索引3将String作为数组索引

注意#1:编译器会发生这种情况,因为变量c的类型是char,当与指针结合使用时,它可以用作数组的索引。

注2:由于某种原因, c[]类型评估为类型。

例如:结果类型的c[&pi]c[&pc]会在以下代码中引起警告:

 int *pi; char *pc; pi=&i; pc=&c; printf("%p %02x\n",&pi,c[&pi]); printf("%p %02x\n",&pc,c[&pc]); 

类型’int *’或’char *’而不是’unsigned int’的警告:

 c/so_cweirdchar2.c: In function 'main': c/so_cweirdchar2.c:13:5: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'int *' [-Wformat=] printf("pi %p %02x\n",&pi,c[&pi]); ^ c/so_cweirdchar2.c:14:5: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'char *' [-Wformat=] printf("pc %p %02x\n",&pc,c[&pc]); ^ 

在C中, []后缀指针移位运算符是可交换的。 如果a[i]是一个有效的表达式,那么i[a]也是如此,意思相同。 虽然我们必须观察运营商的关联性和优先级,以确保我们正确地进行逆转。 你的c[&i](&i)[c] c[&i]意思相同:指针&i被整数c取代。

[]的可交换性的基础是索引与指针位移和解除引用的组合之间的等价,其中+运算符是可交换的:

 E1[E2] <--> *(E1 + E2) ^ ^ | | vv E2[E1] <--> *(E2 + E1) 

在这里,我们将E1理解为完全带括号的表达式,因此我们不关心优先级。 实际上,我们正在操纵抽象语法树,其中E1E2是节点。

编译没有错误。 完全有效的C:

 int main (int argc, char** argv) { int n=5; char *a="abcdefghijk"; printf("%c\n", a[n]); printf("%c\n", n[a]); return 0; }