两个对象可以有相同的地址,但它们的大小可以不同。
来自 C 标准(6.5.3.4 sizeof 和 alignof 运算符)
2 sizeof 运算符产生其操作数的大小(以字节为单位),即
可以是表达式或类型的括号名称。 尺寸为
根据操作数的类型确定....
考虑以下示例
#include <stdio.h>
int main( void )
{
struct A
{
char c;
int x;
} a;
printf( "object a:\taddress - %p size - %zu\n",
&a, sizeof( a ) );
printf( "object a.c:\taddress - %p size - %zu\n",
&a.c, sizeof( a.c ) );
}
程序输出是
object a: address - 0x7fff164e16d0 size - 8
object a.c: address - 0x7fff164e16d0 size - 1
可以看出struct A 类型的对象a 及其char 类型的数据成员c 具有相同的地址但大小不同。
对于数组,指针是一个存储其他对象地址的对象。要存储其他对象的地址,根据使用的系统为指针分配例如 4 或 8 个字节的内存就足够了。
对于数组,它们被命名为内存范围。数组不存储地址。它们存储自己的元素(当然也可以是指针)。
表达式中使用的数组名被转换为指向其第一个元素的指针。
根据 C 标准(6.3.2.1 左值、数组和函数指示符)
3 除非它是 sizeof 运算符的操作数或一元 &
运算符,或者是用于初始化数组的字符串文字,an
具有“类型数组”类型的表达式被转换为
类型为“类型指针”的表达式,指向初始
数组对象的元素并且不是左值。如果数组对象
有注册存储类,行为未定义。
在此引用中,列出了数组未转换为指向其第一个元素的指针的情况。例如,当数组是sizeof 运算符的操作数时。
如果要返回你的程序
int main()
{
char a[] = "hello";
char *pa = a;
printf("Array: %ld\n", sizeof(a));
printf("Pointer: %ld\n", sizeof(pa));
}
那么在这个语句中
char a[] = "hello";
类型为char[6] 的字符串文字"Hello" 不会转换为指针。
然而在这个声明中
char *pa = a;
数组a 被转换为指向其第一个元素的指针。
在此声明中
printf("Array: %ld\n", sizeof(a));
数组a 未转换为指针,因为它是sizeof 运算符的操作数。
但是,如果您在 sizeof 运算符中使用了表达式,例如这样
sizeof( a + 0 )
然后你会得到一个指针,相应地sizeof 会返回指针的大小而不是数组的大小