函数调用中char[]和char*之间的差异
Difference between char[] and char* in function call
我发现自己无法解释为什么下面的代码可以工作。不用说,我对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
的类型指针的声明。
数组名称指向数组第一个元素的地址。请参阅:数组名称是指针吗?
- C++17:unique_ptr<char[]> 和 shared_ptr<char[] 之间的指针存储差异>
- char 和 char& 之间是否存在相对复制开销差异?
- 如果 strlen 在 char 数组之间遇到空格,它会怎么做
- void*和char*之间的差异
- "char *"和"char * = new char[]"之间的C++区别
- qsort()中的char*和char []之间的混淆
- (char*)和char*之间有什么区别
- C++ 中 int* 和 char* 之间的区别
- 函数调用中char[]和char*之间的差异
- 指针上的interpret_cast在char和unsigned char之间存在缺陷
- 我不能理解const char*和char*之间的区别
- 类和char *之间的强制转换
- char、char[]、char*之间的差异
- const void*到char之间的转换
- 在const wchar_t*和const char*之间进行转换,不允许使用qt
- char[]和char*之间的差异
- 为什么在多重定义的情况下char*和char[]之间存在差异
- char**和char*[]之间有什么区别
- "istream::get"和"operator>>(istream&, char&)"之间的区别
- ANSI代码页中wchar_t char之间的转换