void main(void)
{
int a[5] = {1, 2, 3, 4, 5};
printf("%p\n", a);
printf("%p\n", &a);
}
为什么打印出来结果会是一样的?
谢谢。
1
stebest 2019-10-16 10:23:15 +08:00
第一个是数组第一个元素的指针,第二个是数组的指针,打印出来的结果当然一样
|
2
kljsandjb 2019-10-16 10:27:19 +08:00 via iPhone
c 语言的 legacy
|
3
Rasphino 2019-10-16 10:30:26 +08:00
int *p;
和 int (*p)[5]; |
6
CRVV 2019-10-16 10:55:27 +08:00
a 是一个变量,类型是 int[5]
数组是一段连续的内存上放了多个元素,很多语言的数组( std::vector )是一个 struct,包含了这段内存的地址,数组的长度容量这些信息。 但是 C 的数组只是那一段用来放元素的内存,没有其它的东西了,数组的地址,数组本身都是指那一段内存。 |
8
stebest 2019-10-16 11:11:08 +08:00
@waiaan 值一样,但类型不一样,移动的步长不一样!数组指针移动一个位置的话,就跳过了整个数组,元素指针移动一个位置,就跳一个元素
|
9
summer20100514 2019-10-16 11:31:43 +08:00
|
10
opensail 2019-10-16 11:38:30 +08:00
测试结果是 0x7ffd361b7420
0x7ffd361b7420 |
11
opensail 2019-10-16 11:44:07 +08:00
@opensail
我得理解 a 是一个指针,指向了数组首元素,第一个输出是指针 a 本身得地址,第二个输出是指针 a 所指向元素得地址,也是数组第一个元素,小白回答,望指教,已收藏问题 |
13
v2bee 2019-10-16 12:12:29 +08:00
《 C 专家编程》里作者说“数组名是指针”的这一页撕下来...
|
14
misaka19000 2019-10-16 12:14:30 +08:00
反编译一下,看汇编就清楚了
|
17
shfanzie 2019-10-16 15:16:59 +08:00
void main(void)
{ int a[5] = {1, 2, 3, 4, 5}; printf("%p\n", a); printf("%p\n", &a); } printf("%p\n", a); 打印 a 的地址,a 的地址就是它本身,指向 int[5]的地址; printf("%p\n", &a); 这个地方的&是取址运算符,也就意味着取一个变量的地址并付给指针变量。 所以以上两句打印的同一个地址。 |
18
raysonx 2019-10-16 15:55:55 +08:00 3
好久没答语言相关的问题了。 @stebest 和 9 楼的链接是对的。认同“数组名是指针”的建议把以前看的书撕掉。
C 语言里数组就是数组,在类型上指针是不一样的。当你定义 int arr[10]; 的时候,arr 的类型就是 int[10],sizeof(arr)的结果等于 sizeof(int) * 10 而不是 sizeof(int*)。 问题在于,在很多情况下 C 语言的数组可以退化(decay)成指向第一个(也可以说第 0 个)元素的指针,比如以参数形式传给另一个函数的时候,比如 foo(arr),或者向另一个指针赋值的时候,比如 int *p = arr。这种情况下的 arr 等价于&arr[0]。C 语言的这种特性可以视为隐式类型转换或者语法糖。如果这时你用 sizeof 去测试 p 或者 foo 函数的参数,你会得到等同于 sizeof(int*)的值也就是指针的长度( 32 位系统下为 4,64 位系统下为 8 )。 而 &arr 会返回指向整个数组的指针,类型为 int(*)[10]。因为 C 语言的数组实质就是元素组成的连续内存,所以数组的地址和第一个元素的地址在数值上是相等的,这也是为什么 &arr 在数值上等同于 &arr[0]。但注意它们的类型是不同的。如果你对&arr 进行指针运算,比如 &arr + 1,则计算得到的新地址会指向整个数组之后的下一个字节,而不是指向 arr[1]。 |