Kernighan&里奇第二版。表示:
索引和指针算术之间的对应关系非常接近。根据定义,类型数组的变量或表达式的值是数组的元素零的地址。因此在任命后
pa = &a[0];
pa
和a
具有相同的值。由于数组的名称是初始元素位置的同义词,因此赋值pa=&a[0]
可以也写成
pa = a;
如果a
和pa
相同,那么为什么这段代码:
#include <stdio.h>
int main()
{
char a[] = "hello";
char *pa = a;
printf("Array: %ld\n", sizeof(a));
printf("Pointer: %ld\n", sizeof(pa));
}
输出:
Array: 6
Pointer: 8
非常感谢参考权威来源。
答案 0 :(得分:3)
两个对象可以具有相同的地址,但它们的大小可以不同。
来自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
可以看到a
类型的对象struct A
及其c
类型的数据成员char
具有相同的地址但大小不同。
对于数组,指针是一个存储其他对象地址的对象。要存储其他对象的地址,只需为指针分配4或8个字节的内存即可,具体取决于所使用的系统。
对于数组,它们被命名为内存范围。数组不存储地址。他们存储自己的元素(当然可以是指针)。
表达式中使用的数组名称将转换为指向其第一个元素的指针。
根据C标准(6.3.2.1 Lvalues,数组和函数指示符)
3除非它是sizeof运算符或一元&amp;的操作数。 operator,或者是用于初始化数组的字符串文字, 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";
类型为"Hello"
的字符串文字char[6]
未转换为指针。
但是在这个声明中
char *pa = a;
数组a
被转换为指向其第一个元素的指针。
在本声明中
printf("Array: %ld\n", sizeof(a));
数组a
未转换为指针,因为它是sizeof
运算符的操作数。
但是,如果您在sizeof运算符中使用了一个表达式,例如像
那样sizeof( a + 0 )
然后你会得到一个指针,相应地sizeof
将返回指针的大小而不是数组的大小
答案 1 :(得分:2)
他们确实拥有相同的值。但不意味着它们是相同的。
a
仍固定大小的数组。 pa
仍是指针。
sizeof
是一个识别这种差异的运算符。
您的数组有6个大小为char
的元素(sizeof(char)
由标准定义为1)。 (第6个元素是字符串null终止符)。
sizeof(char*)
为8。它可能是64位。
答案 2 :(得分:2)
数组不是指针。在许多情况下,数组名称衰减指向其第一个元素的指针,但sizeof
是少数例外之一。
C11§6.3.2.1左值,数组和函数指示符
除非它是
sizeof
运算符,_Alignof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,类型为“数组类型”的类型转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素,而不是左值。
答案 3 :(得分:1)
a
和pa
不相同。永远记住:数组不是指针。当在表达式中使用时,数组被转换为指向其第一个元素的指针,但有一些例外,包括作为sizeof
运算符的操作数。
sizeof(a)
将给出数组的大小,而sizeof(pa)
将给出指针的大小。
答案 4 :(得分:1)
char a[] = "hello";
char *pa = a;
此处sizeof(a)
会给出数组a
的大小。而sizeof(pa)
会给出指针pa
的大小。两者都不同。
同样在函数参数中,数组衰减到指针但是这一个与&
一起是异常。
同样在打印类型size_t
时,您应该使用说明符%zu
(在ANSI C99中指定)。