Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 什么';这是args和&;阿格斯?_C_Arrays - Fatal编程技术网

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;
}