题
在下面的C程序,我不理解后我调用foo为什么BUF [0] = 'A'。不FOO做通按值?
#include <stdio.h>
#include <stdlib.h>
void foo(char buf[])
{
buf[0] = 'A';
}
int main(int argc, char *argv[])
{
char buf[10];
buf[0] = 'B';
printf("before foo | buf[0] = %c\n", buf[0]);
foo(buf);
printf("after foo | buf[0] = %c\n", buf[0]);
system("PAUSE");
return 0;
}
输出:
before foo | buf[0] = 'B'
after foo | buf[0] = 'A'
解决方案
void foo(char buf[])
是相同的
void foo(char* buf)
在调用它,foo(buf)
,按值传递指针,所以指针的一个拷贝。
指针所指向的拷贝到相同的对象的原始指针(或者,在此情况下,到所述阵列的所述初始元素)。
C没有通过引用语义通在这个意义上,C ++有通过引用语义通。用C一切都按值传递。指针被用来通过引用语义来获得通
其他提示
的阵列仅仅是一个奇特的方式来使用一个指针。当你通过buf
的功能,你传递一个的指针的按价值计算,但是当你解引用指针,你仍然引用字符串它指向。
数组作为函数参数相当于一个指针,以便声明
void foo( char buf[] );
是相同的
void foo( char* buf );
在数组参数是和腐烂以指针到它的第一个元素。
阵列的处理方式不同比其他类型;你不能在C.通过“由值”的数组
在线C99标准(草案n1256)一>,第6.3.2.1节 “左值,数组和功能标示符”,第3段:
除非它是sizeof运算符的操作数或一元&运算,或者是一个 字符串常量用于初始化一个数组,具有类型“类型的阵列'的表达式”是 转换为与类型“‘指针为类型’”,它指向的初始元件的表达 阵列对象,并不是左值。如果数组对象具有寄存器存储类中, 行为是未定义。
在呼叫
foo(buf);
阵列表达buf
不是sizeof
或&
的操作数,也不是字面被用来初始化一个数组的字符串,所以它是隐式转换从类型(“衰变”)“炭的10个元素的数组”到“指针炭”,而地址所述第一元件的被传递给FOO。因此,任何你做buf
在foo()
将反映在buf
的main()
阵列英寸因为数组下标是如何定义的,你可以在一个指针类型使用标运算符所以它的外观的像你使用数组类型的工作,但你不是。
在一个功能参数声明,T a[]
和T a[N]
的上下文与T *a
同义,但是这是仅情况下这是真的。
*炭的buf []实际上意味着焦炭**所以你由指针/引用传递。 这使你的buf是指针,在两者的主强>()和 FOO 强>()函数。
由于要传递一个指针buf
(由值)。因此,通过buf
被指向所述内容被改变。
使用指针它的不同;你被值传递,但什么要传递是指针,这是不一样的数组的值的值。
因此,指针的值不会改变,但你修改什么它指向。
数组和指针是(几乎)相同的事情。
int* foo = malloc(...)
foo[2]
相同*(foo+2*sizeof(int))
趣闻:你写的
int main(int argc, char *argv[])
它也是合法的(编译和工作相同),以写入
int main(int argc, char **argv)
和也
int main(int argc, char argv[][])
它们实际上是相同的。它比稍微复杂一些,因为数组知道它有多少个元素了,而指针没有。但它们被使用的相同。
为了通过由值,则该函数将需要知道参数的大小。在这种情况下你只是传递指针。
您通过引用在这里传递。在这个例子中,可以通过所希望的该阵列的索引处传递一个单个字符解决问题。
如果您想保留原始数组的内容,你可以复制该字符串在函数的临时存储。
编辑:如果你包裹在一个结构中的字符数组,并通过结构会发生什么?我认为,可能工作过,虽然我不知道什么样的开销,可能需要在编译器级别创建。
请注意一件事,
声明
void foo(char buf[])
说,将要使用[]符号。不将使用哪种阵列的元件。
如果你想说的是,你想要得到一些特定的值,那么你应该声明此功能
void foo(char buf[X]); //where X would be a constant.
当然是不可能的,因为这将是无用的(对于在阵列的第n个元素操作功能?)。你不必写下你想获得哪个数组元素的信息。你所需要的一切都很简单声明:
voi foo(char value);
所以...
void foo(char buf[])
是说要使用哪个符号的声明。([] - 部分),并且它也包含指向一些数据
此外...你会想到......你送到函数foo阵列的名称
foo(buf);
这相当于&BUF [0]。所以...这是一个指针。
在C数组不是由值来传递。他们甚至不合法的功能参数。相反,编译器看到的是你想传递一个数组并把它降级到指针。它这样做是默默地,因为它的邪恶。它也喜欢踢幼犬。
在功能参数使用数组是一个很好的方式,以信号到你的API的用户,这件事应该是一个内存块分成n字节大小的块,但不要指望编译器,如果你拼写char *foo
char foo[]
或char foo[12]
关心在功能参数。他们不会。