一元&的语义在数字文字上

时间:2014-10-07 14:22:46

标签: c++ c pointers

什么是一元 - &在这儿干?

int * a = 1990; 
int result = &5[a]; 

如果您要打印result,您将获得2010年的价值。

您必须使用-fpermissive进行编译,否则会因错误而停止。

4 个答案:

答案 0 :(得分:10)

在C中,x [y]和y [x]是相同的。因此& 5 [a]与& a [5]相同。

答案 1 :(得分:5)

&5[a]&a[5]相同,与a + 5相同。在你的情况下,它是未定义的行为,因为a指向无处。

C11标准章节6.5.6 Additive operators/8(在C ++中相同):

  

如果两个指针都有   操作数和结果指向同一个数组对象的元素,或者指向最后一个数组对象的元素   数组对象的元素,评估不得产生溢出;否则,   行为未定义。

答案 2 :(得分:3)

" ...一元&关于数字文字"?

C中的后缀运算符始终具有比前缀1更高的优先级。如果是&5[a],则[]的优先级高于&。这意味着在&5[a]中,一元&未应用于"数字文字"因为你似乎错误地相信。它适用于整个5[a]子表达式。即&5[a]相当于&(5[a])

至于5[a]的含义 - 这是一个被打死的FAQ。查一查。

不,你没有"用-fpermissive"编译它。 (我的编译器告诉我它甚至不知道-fpermissive是什么)。你必须弄清楚这个

int * a = 1990; 

不是C或C ++中的合法代码。如果有的话,它需要一个明确的演员

int * a = (int *) 1990; 

目前您正在使用的某些特定编译器并不是一些模糊的开关。这同样适用于int result = &5[a]中的另一个非法初始化。

最后,即使我们忽略了非法代码和由5[a]触发的未定义行为,此代码的行为仍将高度依赖于实现。即答案是否定的,一般情况下,您不会在2010中获得result

答案 3 :(得分:1)

您无法将一元&运算符应用于整数文字,因为文字不是左值

由于运算符优先级,您的代码不会这样做。由于索引运算符[]的绑定比一元&更紧密,因此&5[a]等同于&(5[a])

这是一个类似于你的程序,除了它是有效的代码,不需要-fpermissive编译:

#include <stdio.h>
int main(void) {
    int arr[6];
    int *ptr1 = arr;
    int *ptr2 = &5[ptr1];
    printf("%p %p\n", ptr1, ptr2);
}

this questionmy answer中所述,索引运算符是可交换的(因为它是根据加法定义的,并且加法是可交换的),因此5[a]等同于{{1 }}。因此,表达式a[5]计算&5[ptr1]的元素5的地址。

在你的计划中:

arr

int * a = 1990; int result = &5[a]; 的初始化无效,因为a的类型为aint*的类型为1990,并且int没有隐式转换{1}}到int。同样,int*的初始化无效,因为result的类型为&5[a]。显然int*会导致编译器违反语言规则并允许这些无效的隐式转换。

至少在我正在使用的gcc版本中,-fpermissive选项仅对C ++和Objective-C有效,而不适用于C.在C中,gcc允许这样的隐式转换(带警告) 。我强烈建议使用此选项。 (你的问题被标记为C和C ++。请记住,C和C ++是两种不同的,虽然密切相关的语言。在这种情况下它们的行为似乎相似,但通常最好选择一种语言或另一种语言。)< / p>