“int* p=+s;”做了什么?

63

我在这里看到了一个奇怪类型的程序 here

int main()
{
    int s[]={3,6,9,12,18};
    int* p=+s;
}

以上程序在 GCCClang 编译器上进行了测试,两个编译器都可以正常工作。

我很想知道 int* p=+s; 是做什么用的?

数组 s 是否被衰变成指针类型?


21
C语言中有数组类型。例如尝试使用sizeof来计算一个数组和一个指针的大小。 - Yksisarvinen
8
@ziza arrays are completely different from pointers。例如,如果我们有int b[2]; int a* = b;,那么int *c = b+1int *d = a + 1将包含不同的值。 - phuclv
7
如果你打算编写这样的代码,请至少按照“int* p = +s”的方式书写(在'='周围添加空格),以明确表示这是一个一元'+',除非你想要让维护该代码的人感到困惑...请留意。 - Sean Burton
8
@LưuVĩnhPhúc说:“他们不是同一种东西吗?!?”(https://ideone.com/uvo2CS) 我同意数组和指针是不同的东西,但是你的例子是错误的。 - DevSolar
7
或许有趣的轶事是,+= 运算符最初是 =+,这个顺序被改变了,很可能是因为与一元的 + 符号歧义相关。 - Peter - Reinstate Monica
显示剩余10条评论
5个回答

63
内置的operator+可以将指针类型作为其操作数,因此将数组s传递给它会导致array-to-pointer conversion,然后返回指针int*。这意味着您可以单独使用+s来获取指针。(对于此情况,这是多余的;没有operator+也会衰减为指针,然后赋值给p。)
(强调我的)

内置的一元加运算符返回其操作数的值。唯一不是无操作的情况是当操作数具有整数类型或未作用域枚举类型,并通过整数提升进行更改,例如,它将char转换为int,或者如果操作数受到lvalue-to-rvalue,array-to-pointer或function-to-pointer转换的影响。


这在C语言中也有效吗? - machine_1
5
@machine_1 对不起,我不知道。我不熟悉C语言,它们是不同的编程语言。 :) Translated: @machine_1 Sorry, I don't know. I'm not familiar with C language, they are different programming languages. :) - songyuanyao
4
@machine_1 不完全正确。在C语言中,一元加操作符会将 char 类型转换为 int 类型,就像在C++中一样,但是在C语言中,将一元加操作符放在数组、指针或函数前面是无效的。 - Donald Duck
@DonaldDuck:我认为你的意思是将其放在指针类型值之前,包括数组和函数分解为这些值并不取消引用所得到的指针。给定double arr[20],someFunc(void),x;代码可以完全合法地执行x= +arr[5];x = +someFunc();,因为数组和函数被取消引用了。 - supercat

25

测试一下:

#include <stdio.h>
int main(){
    char s[] = { 'h', 'e', 'l', 'l', 'o' , ' ', 'w', 'o', 'r', 'l', 'd', '!'} ;
    printf("sizeof(s) : %zu,  sizeof(+s) : %zu\n", sizeof(s), sizeof(+s) ) ;
}

在我的电脑上(Ubuntu x86-64),它会打印:

sizeof(s): 12,  sizeof(+s) : 8

在哪里

12 = number of elements s times size of char, or size of whole array
 8 = size of pointer

6
s的赋值语句应该是char s[] = "Hello world";,这样会更易读。 - David Foerster
13
“Hello world!”末尾会隐含一个 '\0' 字符。 - chtz

11

那是一个单元加号符号,它在这里没有实际作用。例如:

#include <iostream>

int main() {
    int a[] = {1};

    std::cout << a << " " << +a << std::endl;
}

这将打印出相同的地址,无论是a还是+a。数组按照通常的方式衰减为指针。

请注意,如果使用一元减号-a,GCC将显示错误:

error: wrong type argument to unary minus

编辑:尽管它对 OP 的代码没有影响,但 a+a 并不完全相同。 有关详细信息,请参阅 Khurshid Normuradov 和 songyuanyao 的答案。


你的回答与大多数其他人不同,因为它说“这里没有实际效果的一元加号符号”。然而,std::cout << a;之所以只打印相同的内容,是因为operator<<也会触发指针衰减,但a是一个数组,而+a是指向第一个元素的指针。 - 463035818_is_not_a_number
我认为你的回答是正确的,因为在OP的代码中,“+”实际上没有任何实际效果,因为(如果我没有弄错的话),已经“=”使数组衰减。尽管如此,你的回答可能会被误解为“a”和“+a”是相同的。 - 463035818_is_not_a_number
@user463035818 你是对的。其他两个答案比我的更好地涵盖了这一点。因此,我稍微编辑了答案以避免这种混淆。 - taskinoor

10

数组s被降解为指针类型吗?

是的。

int* p=+s;是什么意思?

一元运算符+强制将数组降解为指针。

C++标准,5.3.1一元运算符(P7):

一元运算符+的操作数必须具有算术、未作用域枚举或指针类型,结果是参数值。对整数或枚举操作数进行整数提升。结果的类型是提升操作数的类型。

一元+形式(+s)强制将操作数评估为数字或指针。

更多信息,请参见此stack overflow answer


0

这里的一元+仅仅是让*p指向Integer数组的地址。 我们来看两个数组s1和s2

int s1[]={1,5,2};
int s2[]={2,5,2};

int *p=+s1;
p=+s2; 
printf("%d",(int)p[0]);

输出:2

在我看来,一元+只是将指针p指向数组s的起始地址。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接