首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于在C++中作为函数参数传递的数组,a和&a有所不同

对于在C++中作为函数参数传递的数组,a和&a有所不同
EN

Stack Overflow用户
提问于 2011-02-28 23:54:54
回答 3查看 439关注 0票数 7

为什么对于作为函数参数传递的数组,a和&a的值会不同?对于在函数体中定义的数组,b和&b没有区别。代码如下:

代码语言:javascript
复制
void foo(int a[2])
{
   int b[2];    
   printf("%p %p\n", a, &a);
   printf("%p %p\n", b, &b);
}

int main()
{
   int a[2];
   foo(a);  
   return 0;
}

编辑:

因此,在所有讨论之后,我了解到以下情况正在发生:

main()

代码语言:javascript
复制
int a[2]; /* define an array. */
foo(a);   /* 'a' decays into a pointer to a[0] of type (int*). */
          /* since C is pass-by-value, this pointer is replicated and */
          /* a local copy of it is stored on the stack for use by foo(). */

foo()

代码语言:javascript
复制
printf("%p %p\n", a, &a); /* 'a' is the value of the pointer that has been replicated, */
                          /* and it points to 'a[0]' in main() */
                          /* '&a' is the address of the replicated pointer on the stack. */
                          /* since the stack grows from higher to lower addresses, */
                          /* the value of '&a' is always lower than a. */
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-28 23:58:50

基本上,当您输入void foo( int a[2] )时,您正在以一种有趣的方式编写void foo( int *a )

我将不得不从标准中查找特定的引号,但当分析函数签名时,类型为T的N个元素的类型数组的参数被转换为指向T的指针。当您稍后键入foo(a)时,a衰减为指向第一个元素地址的指针,该指针被复制。在foo中,您可以将指向main中数组a的第一个元素的指针的值与foo中指针a的地址进行比较。

另一方面,在同一函数中,当数组在foo中的b范围内时,数组的地址(&b)和数组的第一个元素的地址(可以通过键入b强制衰减来获得)是相同的地址。

关于未来的两个简单的信息:

函数签名中的

  • 数组被解释为指针:避免使用该语法并使用指针语法,您将获得较少的surprises
  • identifiers,它表示一个数组衰减为指向大多数上下文中第一个元素的指针

示例:

代码语言:javascript
复制
void foo( int a[2] ); // void foo( int *a );
int main() {
   int x[2];
   foo( x );         // foo( &x[0] ); -- inside foo, a is a copy of &x[0]
   printf( "%d\n%d\n", (int)&a, (int)a ); // &a[0] which is the same address as &a
                                          // (different type though)
}
票数 10
EN

Stack Overflow用户

发布于 2011-03-01 00:01:11

数组不是指针。在几乎所有上下文中,它的计算结果都是一个指针,但一个值得注意的例外是&运算符。

因此,如果调用一个以数组作为参数的函数

代码语言:javascript
复制
f(a);

其中的a计算为传递给函数的第一个元素&(a[0])的地址。

如果使用&a,则会将数组的地址作为一个整体获取。它与&(a[0])具有相同的值,但类型不同。&(a[0])的类型是“指向基本类型的指针”,而&a的类型是“指向基本类型数组的指针”。

在函数&a中有一些不同的东西。这里的a是“指向基类型的指针”,所以&a的类型是“指向基类型的指针”,您看到的地址是堆栈上指针的地址,而不是原始数组的地址。

票数 3
EN

Stack Overflow用户

发布于 2011-03-01 00:21:55

当您通过引用将参数传递给函数时,从技术上讲,您将元素的地址放入函数调用堆栈。当您使用带有函数参数的&时,您将获得该值的地址。我将尝试举例说明(所有地址都是任意的,仅用于演示):

代码语言:javascript
复制
int main()
{
   int a[2] ; //  a == &a == 0x001234 
   foo(a); // address of a (0x001234) goes to call stack, 
   // this value is stored in 0x00122C 
   // now inside foo(), &a  == 0x00122C , a == 0x001234


}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5144243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档