C 什么';这是args和&;阿格斯?
这是我的密码剪C 什么';这是args和&;阿格斯?,c,arrays,C,Arrays,这是我的密码剪 #include <stdio.h> void change(int a[]){ printf("%p\n",&a); } int main(){ int b[] = {1,2} ; printf("%p\n",&b); change(b); return 0; } 我们可以看到,实际参数地址与形式参数地址不同 然后我编辑了我的以下内容
#include <stdio.h>
void change(int a[]){
printf("%p\n",&a);
}
int main(){
int b[] = {1,2} ;
printf("%p\n",&b);
change(b);
return 0;
}
我们可以看到,实际参数地址与形式参数地址不同
然后我编辑了我的以下内容
0x7fff5def1c60
0x7fff5def1c38
#include <stdio.h>
void change(int a[]){
printf("%p\n",a);
}
int main(){
int b[] = {1,2} ;
printf("%p\n",b);
change(b);
return 0;
}
因此,实际参数和形式参数似乎具有相同的地址。
我很困惑&a和a(a是一个数组)之间有什么不同,为什么我从第一个代码片段中得到了不同的地址?
谢谢 在main()
中,b是一个数组,如果从初始化中派生,则其大小为,&b
表示数组的地址
在change()
中,a是一个大小未知的数组,它作为参数作为指针处理&a
是此指针的地址
在代码的第二个版本中,如果没有&
,则在这两种情况下都引用指针的值
以下是C11标准的相关摘录:
6.5.3一元运算符,第3部分:一元运算符和运算符生成其操作数的地址
6.7.6.3函数声明器,第7部分:将参数声明为“类型数组”应调整为“合格指针”
类型“”,其中类型限定符(如果有)是在
数组类型派生的[and]
在:
您正在将地址打印到第一个阵列单元
在:
具体而言:
void change(int a[]){
printf("%p\n",&a);
}
您正在打印变量a
的地址,该变量本身就是一个衰减的指针。所以它在语义上等同于:
void change(int* a){
printf("%p\n",&a);
}
要检索数组的第一个单元格,您需要将函数编写为:
void change(int* a){
printf("%p\n", a);
// ^^
}
您可以认为
a
是存储数组[1,2]
的内存的起始地址。
还请考虑a
是一个存储数组地址的变量。变量意味着它本身在内存中的某个地方。因此&a
是变量a
的地址。总之,内存中的地址&a
存储数组[1,2]
的地址
在第一种情况下,将变量b
的地址传递给函数change
,以便函数变量a
存储变量b
的地址。但是&a
是a
的地址,而不是a
的内容。这就是造成差异的原因。运算符“&”返回变量的地址,printf中的“%p”构造返回指针的地址
在您的示例中,main()中的这些调用是等效的:
printf("%p\n",b);
printf("%p\n",&b);
两者都返回b的内存位置,在您的示例中是0x7fff56501c60
定义函数时,会引入局部变量a:
void change(int a[]){
这是一个指针(相当于int*a),有自己的内存地址
在函数内部调用此函数时:
printf("%p\n",a);
得到与上面相同的结果:b的地址:指针b的值被复制到a,printf告诉您它指向的位置
但是,如果您这样做:
printf("%p\n",&a);
然后得到局部变量a的地址,它与b不同。在您的示例中,函数“change”甚至不使用b的值,您也可以运行以下命令:
#include <stdio.h>
void change(int a[]){
printf("%p\n",&a);
}
int main(){
int b[] = {1,2} ;
printf("%p\n",&b);
change((int *)0);
return 0;
}
#包括
无效更改(int a[]){
printf(“%p\n”、&a);
}
int main(){
int b[]={1,2};
printf(“%p\n”、&b);
更改((int*)0);
返回0;
}
这运行带有空指针的“change”,它仍然相当于您的第一个示例:“change”只打印出局部变量a的地址,而不考虑其内容。因为我认为目前的答案还不够强调它,我将给出另一个答案: 如果
b
是数组,则b
和&b
之间没有区别。数组几乎像指针,但不是100%。指针是存储地址的变量,如您所知。因此,当您创建一个指针p
,您将创建一个新变量,然后为其分配一些地址。现在指针变量p
有一个地址,它的值也是一个地址。你可以用它做三件事:
-使用&p
-使用p
s获取p
s值
-使用*p
对于数组ar
,它是不同的。它就像一个指针,但它不是一个存储地址的独特变量!通过创建数组,您只需为要存储的元素分配内存,而不是为存储这些元素地址的变量分配内存。变量ar
只是“代表”第一个元素的地址,但它并没有保存在额外的空间中;编译器确保将ar
翻译到第一个元素的内存中,这一点很重要。因此,您可以用它来做:
-使用&ar
或ar
获取ar
s地址
-使用ar[0]获取ar
s值
这就是为什么在change
函数中,int a[]
与int*a
相同,但在主函数中,int b[]
与int*b
不同的原因。后者为地址分配内存,而前者仅为指定数量的元素创建内存,并仅使用b
作为这些元素的第一个地址的占位符-没有为第一个元素的地址分配额外的内存,就像指针一样
这也是为什么在main
中不能执行b=some_pointer
,但可以在change
中执行此操作的原因-因为其中一个是分配了内存的指针,因此可以像其他变量一样更改其值,另一个只是它的第一个元素的占位符,因此不能更改它的值
我希望没有
printf("%p\n",a);
printf("%p\n",&a);
#include <stdio.h>
void change(int a[]){
printf("%p\n",&a);
}
int main(){
int b[] = {1,2} ;
printf("%p\n",&b);
change((int *)0);
return 0;
}