为什么会出现数组';s地址等于它在C中的值?

为什么会出现数组';s地址等于它在C中的值?,c,pointers,arrays,C,Pointers,Arrays,在下面的代码位中,指针值和指针地址与预期不同 但是数组值和地址不能 这怎么可能 输出 my_array = 0022FF00 &my_array = 0022FF00 pointer_to_array = 0022FF00 &pointer_to_array = 0022FEFC #包括 int main() { char my_数组[100]=“some cool string”; printf(“我的\u数组=%p\n”,我的\u数组); printf(&my\u数组=%p

在下面的代码位中,指针值和指针地址与预期不同

但是数组值和地址不能

这怎么可能

输出

my_array = 0022FF00
&my_array = 0022FF00
pointer_to_array = 0022FF00
&pointer_to_array = 0022FEFC
#包括
int main()
{
char my_数组[100]=“some cool string”;
printf(“我的\u数组=%p\n”,我的\u数组);
printf(&my\u数组=%p\n“,&my\u数组);
char*指向数组的指针=我的数组;
printf(“指向数组的指针=%p\n”,指向数组的指针);
printf(“&pointer\u-to\u-array=%p\n”、&pointer\u-to\u-array”);
printf(“按ENTER键继续…\n”);
getchar();
返回0;
}
这是因为数组名(
my_array
)与指向数组的指针不同。它是数组地址的别名,其地址定义为数组本身的地址

但是,指针是堆栈上的普通C变量。因此,您可以获取其地址,并从其内部保存的地址中获取不同的值


我写过关于这个主题的文章-请看。

数组的名称通常计算为数组第一个元素的地址,因此
数组
数组
具有相同的值(但类型不同,因此如果数组长度超过1个元素,
数组+1
&array+1
将不相等)

有两种例外情况:当数组名是
sizeof
或一元
&
(的地址)的操作数时,该名称指数组对象本身。因此,
sizeof array
提供整个数组的字节大小,而不是指针的大小

对于定义为
T数组[size]
的数组,其类型将为
T*
。当/如果增加它,则进入数组中的下一个元素

&array
的计算结果是相同的地址,但给定相同的定义,它会创建一个类型为
T(*)[size]
的指针——即,它是指向数组的指针,而不是指向单个元素的指针。如果增加这个指针,它将增加整个数组的大小,而不是单个元素的大小。例如,使用如下代码:

char array[16];
printf("%p\t%p", (void*)&array, (void*)(&array+1));
我们可以预期第二个指针比第一个指针大16个(因为它是一个由16个字符组成的数组)。由于%p通常以十六进制格式转换指针,因此它可能类似于:

0x12341000    0x12341010
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
^
|
Address of my_array.

在C语言中,当您在表达式中使用数组的名称(包括将其传递给函数)时,除非它是(
&
)运算符地址的操作数或
sizeof
运算符的操作数,否则它将衰减为指向其第一个元素的指针

也就是说,在大多数上下文中,
array
在类型和值上都等同于
&array[0]

在您的示例中,
my_array
具有类型
char[100]
,当您将其传递给printf时,该类型会衰减为
char*

&my_数组
的类型为
char(*)[100]
(指向100的数组的指针
char
)。由于它是
&
的操作数,这是
my_array
不会立即衰减为指向其第一个元素的指针的情况之一

指向数组的指针与指向数组第一个元素的指针具有相同的地址值,因为数组对象只是其元素的连续序列,但指向数组的指针与指向该数组元素的指针具有不同的类型。在对这两种类型的指针执行指针算术时,这一点很重要

指向数组的指针
的类型为
char*
-初始化为指向数组的第一个元素,因为这是
我的数组
在初始化表达式中衰减为的内容-而
指向数组的指针
的类型为
char**
(指向
char
的指针)


其中:
myu数组
(衰减为
char*
)、
myu数组
指向数组的指针
都直接指向数组或数组的第一个元素,因此具有相同的地址值。

实际上
&myarray
myarray
都是基地址

如果您想看到差异,而不是使用

printf("my_array = %p\n", my_array);
printf("my_array = %p\n", &my_array);
使用


查看阵列的内存布局时,可以很容易地理解
my_array
my_array
导致相同地址的原因

假设您有一个10个字符的数组(而不是代码中的100个字符)

my_数组的内存类似于:

0x12341000    0x12341010
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
^
|
Address of my_array.
在C/C++中,数组衰减到表达式中第一个元素的指针,如

printf("my_array = %p\n", my_array);
如果检查数组的第一个元素所在的位置,您将看到其地址与数组的地址相同:

my_array[0]
|
v
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
^
|
Address of my_array[0].

在B编程语言中,它是C的直接前身, 指针和整数可以自由互换。该系统将表现为 虽然所有的记忆都是一个巨大的阵列。每个变量名都有一个全局变量 或堆栈相对地址 与之相关联的是,对于每个变量名,编译器只需跟踪它是全局变量还是局部变量,以及它相对于第一个全局变量或局部变量的地址

给定一个全局声明,如
i[无需指定类型,因为所有内容都是整数/指针]将由
编译器为:
address\u of\u i=next\u global++;内存[地址\的\ i]=0
和类似
i++
的语句将被处理为:
memory[address\u of_i]=memory[address\u of_i]+1

类似于
arr[10]的声明将被处理为
address\u of\u arr=next\u global;内存[下一个全局]=下一个全局;下一个_global+=10。请注意,一旦处理了该声明,编译器就可以立即忘记
arr
是一个数组。类似于
arr[i]=6的语句将被处理为
内存[内存[地址\地址\地址\地址\地址\地址\地址]=6。编译器不会关心是否my_array[0]
|
v
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
^
|
Address of my_array[0].