dar*_*rix 28 c arrays pointers memory-address
我很难理解C中数组名称的类型和用法.这可能看起来很长,但请耐心等待.
我理解以下语句声明a是类型,int []即整数数组.
int a[30];
Run Code Online (Sandbox Code Playgroud)
同时a也指出数组的第一个元素和类似*(a+2)的东西是有效的.因此,a看起来像一个指向整数的指针.但实际上类型int []和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));
}
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
a:2686720 &a:2686720
6
Run Code Online (Sandbox Code Playgroud)
那么,上面的代码是如何工作的呢?我有两个问题:
a并&a具有相同的值.为什么?int (*p)[3];做什么的?它声明了一个指向数组的指针,我知道这一点.但是,如何是一个指针数组从不同的阵列的第一个元素的指针和所述阵列的名字?任何人都可以澄清一切吗?我有很多困惑.
我知道我应该使用%p占位符而不是%d用于打印指针变量的值.使用整数占位符可能会打印截断的地址.但我只想保持简单.
hac*_*cks 48
其他答案已经解释了这个问题.我试图用一些图解释它.希望这会有所帮助.
声明数组时
int a[3] = {5, 4, 6}
Run Code Online (Sandbox Code Playgroud)
记忆安排看起来像
现在回答你的问题:
a并且&a具有相同的价值.怎么样?
正如您所知,a数组类型和数组名称a成为指向数组第一个元素的指针a(在衰减之后),即它指向地址0x100.注意,它0x100也是内存块(数组a)的起始地址.你应该知道,通常,第一个字节的地址被称为变量的地址.也就是说,如果变量是100个字节,那么它的地址等于其第一个字节的地址.
&a是整个存储块的地址,即它是数组的地址a.见图:

现在您可以理解为什么a并且&a两者具有相同的地址值,尽管两者的类型不同.
它究竟是什么
int (*p)[3];声明一个指向数组的指针,我知道这个.但是,指向数组的指针与指向数组的第一个元素和数组名称的指针有何不同?
参见上图,清楚地解释了指向数组的指针与指向数组元素的指针的不同之处.
分配&a给p,然后p指向具有起始地址的整个数组0x100.
注意:关于线路
...在
C数组中通过引用传递(sizeof函数除外).
在C中,参数按值传递.C中没有通过引用传递.当普通变量传递给函数时,其值被复制 ; 对相应参数的任何更改都不会影响变量.
数组也通过值传递,但区别在于数组名称衰减到指向第一个元素的指针,并且该指针分配给函数的参数(这里,指针值被复制); 数组本身不会被复制.
相比于普通变量,作为自变量的阵列无法防止发生任何变化,因为没有复制由与阵列本身的,对第一元件由代替指针的复制.
您还应该注意,这sizeof不是函数,在这种情况下,数组名称不作为参数.sizeof是运算符,数组名称用作操作数.当数组名是一元运算&符的操作数时,同样适用.
oua*_*uah 16
- a和&a有相同的值.怎么样?
它们具有相同的值但不同的类型.数组对象在元素之间(之前或之后)没有填充,因此数组的地址和数组的第一个元素的地址是相同的.
那是:
(void *) a == (void *) &a
Run Code Online (Sandbox Code Playgroud)
- 它究竟是做什么int(*p)[3]; 声明一个指向数组的指针,我知道这个.但是,指向数组的指针与指向数组的第一个元素的指针和数组的名称有何不同?
这是两种不同的指针类型.以比例算术为例:
a + 1 /* address of the second element of the array */
&a + 1 /* address one past the last element of the array */
Run Code Online (Sandbox Code Playgroud)
编辑:由于受欢迎的需求,我在下面添加了一些有关数组转换的信息.
除了三个例外,在表达式中,将array类型的对象T转换为T指向数组的第一个元素的类型指针的值.例外情况是对象是操作数sizeof或&一元运算符,或者对象是初始化数组的字符串文字.
例如这句话:
printf("a:%d\t&a:%d\n", a, &a);
Run Code Online (Sandbox Code Playgroud)
实际上相当于:
printf("a:%d\t&a:%d\n", &a[0], &a);
Run Code Online (Sandbox Code Playgroud)
另请注意,d转换说明符只能用于打印有符号整数; 要打印指针值,你必须使用p说明符(并且参数必须是void *).所以要正确使用:
printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);
Run Code Online (Sandbox Code Playgroud)
分别:
printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);
Run Code Online (Sandbox Code Playgroud)