总结:
1.二维数组名是指向一位数组的指针,本例中,其类型为 int (*)[4],在传递的过程中丢失了第一维的信息,因此需要将第一维的信息传递给调用函数。
关于二维数组名代表的类型,可通过下面的例子看出。
1 /************************************************************************* 2 > File Name: test_2arr.c 3 > Author:Monica 4 > Mail:liling222@126.com 5 > Created Time: Wednesday, July 09, 2014 PM07:29:55 HKT 6 ************************************************************************/ 7 8 #include <stdio.h> 9 int main(int argc, char* argv[]){ 10 int arr[10]; 11 int (*p)[10] = &arr; 12 return 0; 13 }
编译器通过。
2.任何数组都可以看做是比它低一维的数组组成的数组。例如int a[3][4][5]可以看做是二维数组int b[4][5]组成的一位数组。数组和指针存在等价关系。
int a[10] <=> int * const a;
int a[2][3] <=> int (*const a)[3];
当把数组名作为函数参数传递时, 数组退化为上述同类型的指针。因此传递多维数组时, 必须制定处第一维外的所有维度信息。(引用自高质量C/C++程序设计指南第7章)
3.再写一个传递一位数组的例子。
1 #include <stdio.h> 2 3 void print_arr3(int* a, int len){ 4 int i; 5 for(i = 0; i < len; i ++) 6 printf("%d ", a[i]); 7 printf("\n"); 8 } 9 int main(int argc, const char *argv[]) 10 { 11 int a[5] = {1, 2, 3, 4, 5}; 12 print_arr3(a, 5); 13 return 0; 14 }
4.C/C++为什么要把数组传递改写为指针传递呢?(引用自高质量C/C++程序设计指南)
数组在内存中是连续字节存放的, 因此编译器可以通过地址计算来引用数组中的元素。
出于性能考虑。如果把整个数组中的元素全部传递过去, 不仅需要大量的时间来拷贝数组,而且这个拷贝还会占用大量的堆栈空间。
5.采用上述方法传递参数时, 维度已经确定,因此通用性不强,主要有两个解决方案:
用结构体将数组封装起来。
采用动态分配数组直接传递指针变量。
6.对于5的实现例子。
/************************************************************************* > File Name: print_arr2.c > Author:Monica > Mail:liling222@126.com > Created Time: Wednesday, July 09, 2014 PM03:42:43 HKT ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <time.h> #define M 10 #define N 10 typedef struct tag{ int a[M][N]; int m; int n; }ARR; void print_arr2(ARR* arr) { int i,j; for(i=0; i<arr->m; i++){ for(j=0; j<arr->n; j++){ printf("%d\t", arr->a[i][j]); } printf("\n"); } } int main() { ARR arr; // arr.a[3][] = {{1,2 3},{3, 4, 5},{3, 4, 7}}; arr.m = 3; arr.n = 4; int i, j; srand(time(NULL)); for(i=0; i<arr.m; i++){ for(j=0; j<arr.n; j++){ arr.a[i][j] = rand()%10; } } print_arr2(&arr); return 0; }
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define M 3 5 #define N 4 6 7 void print_arr4(int** a, int m, int n){ 8 int i, j; 9 for(i = 0; i < m; i++){ 10 for(j = 0; j < n; j++){ 11 printf("%d ", a[i][j]); 12 } 13 printf("\n"); 14 } 15 } 16 17 int main(int argc, char* argv){ 18 int** arr; 19 int i, j; 20 srand(time(NULL)); 21 arr = (int **)malloc(M * sizeof(int *)); 22 for(i = 0; i < M; i ++){ 23 arr[i] = (int *)malloc(N * sizeof(int)); 24 } 25 for(i = 0; i < M; i++){ 26 for(j = 0; j < N; j++){ 27 arr[i][j] = rand()%10; 28 } 29 } 30 print_arr4(arr, M, N); 31 //free 32 for(i = 0; i < M; i++){ 33 free(arr[i]); 34 } 35 free(arr); 36 return 0; 37 } 38
7.关于内存泄露。
内存泄露简单地说就是分配了一段内存空间,但是没有释放,也没有任何指针指向它。例如
void test(){ int * p = (int *)malloc(10 * sizeof(int)); } int main(){ test(); return 0; }
test函数中申请了40字节的内存空间,由局部变量p指向, 但是调用完test函数之后p就被销毁, 因此该段内存没有被释放,也没法被释放, 因此就造成内存泄露。