- 论坛徽章:
- 1
|
二维数组做函数参数的问题
C语言中,对多维数组的传递,有些捉襟见肘。这是由于C的低级性导致的。理解了数组名、地址、指针的概念以及C是怎么样实现的时候,就能明白了。^_^,这还真是C中的难点。
这些东西在《C专家编程》中有非常详细的说明。
问题是这样的:
实参:你传递给参数的实参是一个二维数组的数组名,也就是二维数组的首地址。
形参:是一个指针的指针。
<查阅一下用数组名定位数组元素和用指针定位元素的不同>;
为了说明问题,不妨把你的形参重新定义成s。所以,在函数的内部,把s处理成指针(注意,不是数组名了!问题就出在这里)。因为s是指针(一个指针的指针)了,所以s就被解释为*(s+i)。看到了吗?这里,函数就无法“正确”(指和我们头脑想的一样)确定步长了。因为s是指针的指针,所以,i的步长被解释为一个指针的大小,自然和你的二维数组的一维大小是不一样的了。这是第一个错误的原因。
第二个错误的原因是因为编译器处理指针和处理数组存在本质的区别。看看我的例子程序,对于数组,data+1和*(data+1)的值是一样的,而对于指针,就严格的“指”过去了。这是因为,数组名,不过是个名字,是个地址。而指针则是个变量。这个在《C专家编程》中有详述,我就不多说了。例子如下:
- [yangwl:/home/users50/yangwl/test/data]$ cat test.c
- #include <stdio.h>;
- #include <stdlib.h>;
- void fun(char **data);
- int main(void)
- {
- char data[2][5];
- printf("in main\n");
- printf("data:%p\n", data);
- printf("*data:%p\n", *data);
- printf("data+1:%p\n", data+1);
- printf("*(data+1):%p\n", *(data+1));
- printf("data[1]:%p\n", data[1]);
- printf("&data[1][3]:%p\n", &data[1][3]);
- fun(data);
- exit(0);
- }
- void fun(char **data)
- {
- printf("in fun\n");
- printf("data:%p\n", data);
- printf("*data:%p\n", *data);
- printf("data+1:%p\n", data+1);
- printf("*(data+1):%p\n", *(data+1));
- printf("data[1]:%p\n", data[1]);
- printf("&data[1][3]:%p\n", &data[1][3]);
- return ;
- }
- [yangwl:/home/users50/yangwl/test/data]$ gcc test.c
- test.c: In function `main':
- test.c:17: warning: passing arg 1 of `fun' from incompatible pointer type
- [yangwl:/home/users50/yangwl/test/data]$ ./a.out
- in main
- data:0xbffffbd0
- *data:0xbffffbd0
- data+1:0xbffffbd5
- *(data+1):0xbffffbd5
- data[1]:0xbffffbd5
- &data[1][3]:0xbffffbd8
- in fun
- data:0xbffffbd0
- *data:0x4212aa58
- data+1:0xbffffbd4
- *(data+1):0x4212a2d0
- data[1]:0x4212a2d0
- &data[1][3]:0x4212a2d3
- [yangwl:/home/users50/yangwl/test/data]$
复制代码
所以,用到传递参数的时候,尽量不要传递多维数组。需要传递的时候(一般也就是字符串数组),建立一个指针数组对应,然后传递。对于整“块”的多维数组,谨慎的使用全局量好了。 |
|