我发现自己无法解释为什么以下代码有效。毋庸置疑,我对C ++很陌生......
#include <cstdio>
void foo(char* p)
{
p[0] = 'y';
}
int main()
{
char a[1];
a[0] = 'x';
printf("a[0] = %c\n", a[0]);
foo(a);
printf("a[0] = %c\n", a[0]);
return 0;
}
该程序输出
a[0] = x
a[0] = y
让我感到好奇的是,我没有将指针传递给foo。那么如何才能改变数组的值?这是否仅适用于char数组?
Difference between char and char[1]的回答证实了我的观察,但没有详细说明为什么就是这种情况。
谢谢!
答案 0 :(得分:5)
当您将数组传递给函数时,它会衰减到指向第一个元素的指针。
以下内容完全相同:
void foo(char* p);
void foo(char p[]);
void foo(char p[42]); /* Or any other number. */
这是否仅适用于char数组?
它适用于任何阵列。我推荐aryptr section of the C FAQ。
答案 1 :(得分:4)
在C中,数组在大多数情况下(*)衰减成指向第一个元素的指针。
在您的情况下,数组a
会衰减为指向a[0]
的指针。
数组int arr[12][23]
在仅由其标识符使用时衰减到指向其第一个元素的指针,即arr[0]
,其类型为int (*)[23]
(指向23个int的数组的指针) )。
(*)当用作sizeof
运算符的参数时,或者当用作&
运算符的参数或用作字符的初始值设定项(字符串文字)时,数组不会衰减阵列。
答案 2 :(得分:1)
当你说
时char a[5];
编译器分配5个连续的内存块,并将第一个块的地址分配给a。因此,根据定义,数组的名称(在我们的例子中是a)只是指向内存位置的指针。
现在当我们说[0]时,编译器将其操作为*(a + 0 * sizeof(数组数据类型,即char,int等)),象征性地a [i]表示为*(a + i * sizeof) (数组数据类型,即char,int等)))
就函数参数传递而言当我们将数组传递给函数时,它基本上就是传递的第一个元素的地址。有关此plz的更多详细信息,请关注this link或阅读@cnicutar的答案(因为他已经发布了正确的答案,没有必要重复这一点)......
答案 3 :(得分:1)
你可以尝试这样来说服自己这是如何运作的。
int a[8], *p;
p = a;
printf("%p, %p, %p\n", a, &a[0], p);
答案 4 :(得分:0)
数组只不过是一个指针(指向第一个元素),至少对于参数传递而言。
答案 5 :(得分:0)
这里的三个原型是等价的:
void foo(char *p);
void foo(char p[]);
void foo(char p[42]);
C表示T
数组类型的参数声明已调整为指向T
的类型指针的声明。
答案 6 :(得分:0)
数组名称指向数组第一个元素的地址。请参阅:Is an array name a pointer?