作为C指针的a和+ 0之间有什么区别?

问题描述 投票:4回答:1

看看C代码。

#include <stdio.h>
int main(void)
{
    int v[3] = {1, 2, 3};
    printf("%d\n", v);
    printf("%d\n", v + 0);
    printf("%zu\n", sizeof(v));
    printf("%zu\n", sizeof(v + 0));
    printf("%zu\n", sizeof(v + 1));
    printf("%zu\n", sizeof(v + 2));
    return 0;
}

这是其中一个输出:

-587904464
-587904464
12
8
8
8

我认为v与v + 0相同。

两者都是指向数组v [3]中第一个元素的指针。

因此,v和v + 0具有相同的值。

但为什么他们不能保持相同的字节? (sizeof(v)和sizeof(v + 0)不同)

c arrays pointers sizeof
1个回答
9
投票

在大多数情况下,数组标识符衰减到指向数组第一个元素的指针。但是,当数组是sizeof运算符的操作数时,不会发生此转换,并且运算符会以字节为单位生成数组的大小。 From §6.3.2.1 ¶3 of the C11 Draft Standard

除非它是sizeof运算符,_Alignof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将具有类型''数组类型''的表达式转换为表达式输入''指向类型'的指针,指向数组对象的初始元素,而不是左值。

请注意,在C18标准中,_Alignof算子已被删除(discussion here)。

因此,sizeof(v)以字节为单位生成数组v[]的大小,即12个字节。也就是说,操作数的类型是int [3],因为数组尚未转换为指向int的指针(就像在大多数表达式中一样),并且sizeof运算符产生这种类型的大小(3个ints的数组)字节。

但是使用sizeof (v + 0),表达式v + 0的类型决定了sizeof算子产生的结果。在表达式v + 0中,数组v[]衰减到指向v[]的第一个元素的指针,然后根据指针算法的规则添加0。结果是指向int的指针(因为&v[0]本身是指向int的指针),因此表达式v + 0的类型是int *。因此,在这种情况下,sizeof运算符产生指向int的指针的大小。同样适用于类似的表达式sizeof (v + 1)等。

另外,请注意,在首次转换为%p之后,必须使用void *转换说明符打印地址,以避免未定义的行为:

printf("%p\n", (void *)v);
printf("%p\n", (void *)(v + 0));
© www.soinside.com 2019 - 2024. All rights reserved.