c - a 和 a + 0 作为 C 指针有什么区别?

标签 c arrays pointers sizeof

查看 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) 不同)

最佳答案

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

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue.

请注意,在 C18 标准中,_Alignof 运算符已从该段落中删除 (discussion here)。

因此,sizeof(v) 产生数组 v[] 的字节大小,即 12 字节。也就是说,操作数的 typeint [3] 因为数组还没有被转换为指向 int 的指针(因为它会在大多数表达式中),sizeof 运算符以字节为单位生成此类型的大小(3 个 int 的数组)。

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

顺便说一句,请注意,在第一次转换为 void * 后,您必须使用 %p 转换说明符打印地址,以避免未定义的行为:

printf("%p\n", (void *)v);
printf("%p\n", (void *)(v + 0));

关于c - a 和 a + 0 作为 C 指针有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52359809/

相关文章:

c - 为什么我的 string_split 实现不起作用?

c - fgets() 自行初始化变量

c - 如何将 tolower() 与 char* 一起使用?

c++ - 对包含特殊字符的二维数组进行排序 C++

c - wcwidth() 参数的预期编码

php - 在 PHP 中计算数组的中位数

c++ - 指向 char 数组的指针,指针的值不是地址?

c - 如何用C语言中的一个函数来操作不同大小的矩阵?

c - C中的文件截断和填充

c - 来自两个不同文件的 fscanf