函数调用中char[]和char*之间的差异

Difference between char[] and char* in function call

本文关键字:char 之间 函数调用      更新时间:2023-10-16

我发现自己无法解释为什么下面的代码可以工作。不用说,我对C++还很陌生。。。

#include <cstdio>
void foo(char* p)
{
    p[0] = 'y';
}
int main()
{
    char a[1];
    a[0] = 'x';
    printf("a[0] = %cn", a[0]);
    foo(a);
    printf("a[0] = %cn", a[0]);
    return 0;
}

该程序输出

a[0] = x
a[0] = y

让我感兴趣的是,我不是在向foo传递指针,而是一个数组。那么,foo如何更改数组a的值呢?这只适用于字符数组吗?

char和char之间的差异[1]的答案证实了我的观察结果,但它没有详细说明为什么会出现这种情况。

谢谢!

在C中,数组在大多数上下文(*)中会衰减为指向其第一个元素的指针。

在您的情况下,数组a衰减为指向a[0]的指针。

当仅由其标识符使用时,数组int arr[12][23]衰减为指向其第一个元素的指针,即arr[0],其类型为int (*)[23](指向23 int数组的指针)。

(*)用作sizeof运算符的参数、用作&运算符的参数或用作字符数组的初始值设定项(字符串文字)时,数组不会衰减。

当您将数组传递给函数时,它会衰减为指向第一个元素的指针。

以下内容完全等效:

void foo(char* p);
void foo(char p[]);
void foo(char p[42]); /* Or any other number. */ 

这只适用于字符数组吗?

它适用于任何数组。我推荐C常见问题解答的aryptr部分。

当你说时

char a[5];

编译器分配5个连续的内存块,第一个块的地址被分配给a。因此,根据定义,数组的名称(在我们的例子中是a)只是指向内存位置的指针。

现在,当我们说a[0]时,编译器将其操作为*(a+0*sizeof(数组数据类型,即char、int等)),象征性地,a[i]表示为*(a+i*sizeof,数组数据类型即char、int.))

就函数参数传递而言,当我们将数组传递给函数时,基本上它只是传递的第一个元素的地址。有关这个plz的更多细节,请点击此链接或阅读@cnicutar的回答(因为他已经发布了正确的答案,所以没有必要再重复了)。。。

您可以尝试这样做来说服自己这是如何工作的。

int a[8], *p;
p = a;
printf("%p, %p, %pn", a, &a[0], p);

数组只不过是一个指针(指向第一个元素),至少为了传递参数。

这里的三个原型是等价的:

void foo(char *p);
void foo(char p[]);
void foo(char p[42]);

C表示T的类型数组的参数声明被调整为指向T的类型指针的声明。

数组名称指向数组第一个元素的地址。请参阅:数组名称是指针吗?