如果我为 a 分配内存char a[256]
,请将每个元素初始化为不同的值并将其传递给某个函数:
int subFunc(a);
堆栈帧subFunc
看起来如何?
堆栈帧是否包含其中的所有 256 个字节或仅包含指向a
(4 个字节)地址的指针。
如果是指针,那么它如何访问内部的数据subFunc
或者这些数据在哪里可用subFunc
?
如果我为 a 分配内存char a[256]
,请将每个元素初始化为不同的值并将其传递给某个函数:
int subFunc(a);
堆栈帧subFunc
看起来如何?
堆栈帧是否包含其中的所有 256 个字节或仅包含指向a
(4 个字节)地址的指针。
如果是指针,那么它如何访问内部的数据subFunc
或者这些数据在哪里可用subFunc
?
C 语言不需要基于堆栈的机器。也就是说,在基于堆栈的机器上,很可能在堆栈上分配了一个块范围数组。
您不能将数组传递给 C 中的函数。语言指定subFunc(a)
接收指向a
. subFunc (char *a)
这可以通过两个声明(或原型)和subFunc (char a[])
被视为相同的事实来例证。
subFunc
将收到指向 的指针char
,而不是 的数组char
。该指针如何传递的细节将因实现而异。指针值可以被压入堆栈,也可以在寄存器中传递(Red Hat 上的 gcc 2.96 执行前者,而 SLES 10 上的 gcc 4.1.2 执行后者),这可能取决于优化设置等因素,您是否正在生成调试版本等。确定它如何在您的平台上工作的唯一方法是对其进行编码、构建并查看生成的机器代码。
在大多数情况下,“N-element array of”类型的表达式T
将被转换(“decay”)为“pointer to T
”类型的表达式,表达式的值将是数组第一个元素的地址. 此规则的例外情况是数组表达式是 、 或一元运算符的操作数sizeof
,_Alignof
或者&
是用于在声明中初始化另一个数组的内容的字符串文字。
给定代码
char a[256];
...
subFunc(a);
a
调用中的表达式subFunc
类型为“256 元素数组char
”;根据上面的规则,它被替换为“指向char
”( char *
) 类型的表达式,其值是 的地址a[0]
。
因此,subFunc
接收一个指针值,而不是一个数组char
。
请注意,在函数参数声明的上下文中,T a[]
和T a[N]
被解释为T *a
; 如果你的原型subFunc
是
int subFunc(char a[256])
它将被解释为
int subFunc(char *a)
堆栈帧中只有一个 4 字节长的值(在 32 位操作系统上),其值是char a[256]
. 现在我们知道从哪里a
开始,我们可以访问数据了。
调用的函数subFunc()
有char a[256]
。该函数将首先在堆栈中。然后,subFunc()
一直被压入堆栈。但是调用的函数subFunc()
需要传递 to 的首a
地址subFunc()
。如果你传递 to 的长度会a
更好subFunc()
。 subFunc()
应该这样改变:
int subFunc(char *, int);