此示例编译时没有警告/错误(gcc 4.8.2-Wall):
#include <stdio.h>
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 [&amp; i]编译?是故意还是意外? 语法c [&amp; i]在语义上是否有效? (它有任何有用的含义吗?)
我的输出示例:(指针每次更改)
0xbfb2577c b7718cea
0xbfb2577b 08
这个问题起源于这里有一个奇怪的代码'ch2 [&amp; i]': C duplicate character,character by character
关于重复/类似问题的注释#0(经过反思更新): 这个问题不是关于c数组引用的链接问题的重复。它是相关的,因此引用它们很有用。相关问题讨论了有效的a [b]和b [a]情况,其中a或b中的一个是指针而另一个是int。这个问题涉及更奇怪的,也许应该是无效的情况,其中a或b中的一个是char。 对于C数组,为什么a [5] == 5 [a]? 14个答案 With arrays, why is it the case that a[5] == 5[a]? 字符串作为数组索引3答案 String as an array index
注意#1:编译器会发生这种情况,因为变量c的类型是char,当与指针结合使用时,它可以用作数组的索引。
注意#2:出于某种原因,c[<ptr>]
的类型评估为<ptr>
的类型。
例如: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]);
^
答案 0 :(得分:4)
在C中,[]
后缀指针移位运算符是可交换的。如果a[i]
是一个有效的表达式,那么i[a]
也是如此,意味着同样的事情。虽然我们必须观察运营商的关联性和优先级,以确保我们正确地进行逆转。您的c[&i]
与(&i)[c]
的含义相同:指针&i
被整数c
取代。
[]
的可交换性的基础是索引与指针位移和解除引用的组合之间的等价,其中+
运算符是可交换的:
E1[E2] <--> *(E1 + E2)
^ ^
| |
v v
E2[E1] <--> *(E2 + E1)
在这里,我们理解E1
是完全括号表达式,因此我们不关心优先级。实际上,我们正在操纵抽象语法树,其中E1
和E2
是节点。
答案 1 :(得分:0)
编译时没有错误。完全有效的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;
}