我很难理解 C 中数组名称的类型和使用。这可能看起来很长,但请耐心等待。
我理解以下声明声明a
属于类型int []
i.e 整数数组.
int a[30];
While a
还指向数组的第一个元素以及诸如此类的东西*(a+2)
是有效的。因此,使得a
看起来像一个指向整数的指针。但实际上类型int []
and int*
是不同的;而前者是数组类型后来是一个指向整数的指针.
也是一个类型变量int []
被转换为类型变量int*
将其传递给函数时;如C
数组通过引用传递(除了sizeof
操作员)。
让我犹豫不决的一点来了。看一下下面的代码:
int main()
{
int (*p)[3];
int a[3] = { 5, 4, 6 };
p = &a;
printf("a:%d\t&a:%d\n",a,&a);
printf("%d",*(*p + 2));
}
OUTPUT:
a:2686720 &a:2686720
6
那么,上面的代码是如何工作的呢?我有两个问题:
-
a
and &a
具有相同的值。为什么?
- 到底是做什么的
int (*p)[3];
做?它声明了一个指向数组的指针, 我知道这个。但如何是一个指向数组的指针不同于指向数组第一个元素的指针 and 数组的名称?
有人能澄清一下吗?我有很多困惑。
我知道我应该使用%p
作为占位符而不是使用%d
用于打印指针变量的值。因为使用整数占位符可能会打印截断的地址。但我只是想让事情变得简单。
Other answers already explained the issue. I am trying to explain it with some diagram. Hope this will help.
当你声明一个数组时
int a[3] = {5, 4, 6}
内存排列看起来像
现在回答你的问题:
-
a
and &a
具有相同的值。如何?
正如你已经知道的那样a
是数组类型和数组名称a
成为指向数组第一个元素的指针a
(衰减后),即它指向地址0x100
。注意0x100
也是内存块的起始地址(数组a
)。你应该知道,一般来说,第一个字节的地址称为变量的地址。也就是说,如果一个变量有 100 个字节,那么它的地址等于它的第一个字节的地址。
&a
是整个内存块的地址,即它是数组的地址a
。看图:
现在你可以明白为什么了a
and &a
尽管两者的类型不同,但它们具有相同的地址值。
它到底是做什么的int (*p)[3];
声明一个指向数组的指针,我知道这一点。但是,指向数组的指针与指向数组第一个元素和数组名称的指针有何不同?
看上图,清楚地解释了指向数组的指针与指向数组元素的指针有何不同。
当你分配时&a
to p
, then p
指向具有起始地址的整个数组0x100
.
NOTE:关于线路
...如C
数组通过引用传递(除了sizeof
功能)。
在 C 中,参数是按值传递的。 C 中没有按引用传递。当普通变量传递给函数时,其值为copied;对相应参数的任何更改都不会影响该变量。
数组也是按值传递,但不同之处在于数组名称衰减为指向第一个元素的指针,并将此指针分配给函数的参数(这里,指针值被复制);数组本身不会被复制。
与普通变量相比,用作参数的数组不会受到任何更改的保护,因为数组本身没有副本,而是复制指向第一个元素的指针。
您还应该注意的是sizeof
不是函数,在这种情况下数组名称不充当参数。sizeof
is an operator和数组名称作为operand。当数组名称是一元操作数时,同样成立&
操作员。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)