函数调用中char []和char *之间的区别

时间:2012-02-20 10:02:52

标签: c++ c char

我发现自己无法解释为什么以下代码有效。毋庸置疑,我对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]的回答证实了我的观察,但没有详细说明为什么就是这种情况。

谢谢!

7 个答案:

答案 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?