关于二维数组做参数的问题

来源:互联网 发布:大明王朝 知乎 编辑:程序博客网 时间:2024/05/17 23:12
  1. #include <stdlib.h> 
  2. #include <stdio.h> 
  3. funciton(int **a); 
  4. main() 
  5.     int i,j; 
  6.     int a[5][5]; 
  7.     for (i=0;i<5;i++) 
  8.         for (j=0;j<5;j++) 
  9.     { 
  10.         a[i][j]=i*5+j; 
  11.     } 
  12.     funciton((int **)(a)); 
  13.     printf("sizeof:%d",sizeof(a)); 
  14.     printf("sizeof:%d",sizeof(&a)); 
  15.     printf("sizeof:%d",sizeof(a)/sizeof(int)); 
  16.     printf("sizeof:%d",sizeof(&a[0])); 
  17.  
  18.  
  19. funciton(int **a) 
  20.     int i,j; 
  21.      
  22.     for (i=0;i<5;i++) 
  23.         for (j=0;j<5;j++) 
  24.         { 
  25.             printf("%d\t",*(*(a+i)+j)); 
  26.             if (j==4) 
  27.             { 
  28.                 printf("\n"); 
  29.             } 
  30.         } 
  31.  


学过C语言的人,应该有一个常识,调用函数时。是不能传递整个数组的。

只能传递数组的地址。即首元素地址。

对于一维数组,比较好理解。


#include <stdlib.h>
#include <stdio.h>
funciton(int a[]);
main()
{
int a[5]={0,1,2,3,4};
    funciton(a);
}
funciton(int a[])
{
printf("sizeof:%d",sizeof(a));

}

调用函数时,实参为a或者&a[0]时,不会有错误不会有警告。如下图

实参为&a时,没有错误产生警告。如下图:

不解释了。直接说吧。

a代表数组首元素地址。也就是&a[0].所以可以赋值给执行int类型的指针,即int *

&a为一维数组的地址。值为首元素的地址。本质上是指向数组的指针。它只是个指针。所以sizeof(&a)=4;

a值等于&a[0],但是sizeof(a)=20=5*sizeof(int)。这个a不是一般的指针。也不能叫数组指针。

因为数组指针就是指向数组的指针。声明为 int (*p)[5];

大家记住:a值为&a[0],但是sizeof(a)为数组的总大小。所以sizeof(a)/sizeof(int)为数组的元素个数

二维数组:

二维数组的存储是嵌套的一维数组。

main()
{
int i,j;
int a[5][5];
for (i=0;i<5;i++)
  for (j=0;j<5;j++)
{
  a[i][j]=i*5+j;
}
    funciton(a);
printf("sizeof:%d",sizeof(a));
printf("sizeof:%d",sizeof(&a));
printf("sizeof:%d",sizeof(a)/sizeof(int));
printf("sizeof:%d",sizeof(&a[0]));


}
funciton(int a[][5])
{
int i,j;

for (i=0;i<5;i++)
  for (j=0;j<5;j++)
  {
   printf("%d\t",a[i][j]);
   if (j==4)
   {
    printf("\n");
   }
  }

}

没有错误,没有警告。

估计这是最常用的了。

    funciton(a);

a表示整个二维数据。

不要忘了,多维数组只是嵌套的一维数组。

所以a的值和&a[0].是一样的。不管a是几维的。同样sizeof是不一样的。


换成如下:

funciton(&a);

指向二维数组的指针。

funciton(a[0]):

表示一个数组即a[0][0]到a[0][4]

funciton(&a[0]):

无警告

funciton(&a[0][0]):

指向int的指针。

函数调用时。只是会把实参复制过来。传值。而他们的值都是一样的。所以没问题。可以执行。不会有错误。

但我们应该注意,意义是不一样的。

因为函数声明了

funciton(int a[][5]);

所以在函数内部。a就只会当做指向一维数组的指针。来使用。

所以可以a[i][j]和*(*(a+i)+j)

*(*(a+i)+j)含义不解释。

这样声明可以么?

funciton(int (*a)[5]);

答案是,必须可以的。

funciton(int *a);

这个时候,在函数内,a为指向整数的指针。所以,*(*(a+i)+j)不能用了

但是我们可以利用*(a+i*5+j)和a[i*5+j].其实他们是一样的。

笔者经常在使用数组时,经常用

int *p=(int *)malloc(sizeof(int)*n)来代替。感觉很好用,这样的话。传值就更明朗了。

只是一定要记住,不用的时候,一定要free(p);否则会发生内存泄露。

你觉得

funciton(int **a);

应该往里面传什么呢?

首先,在函数内部。a是一个指向指针的指针。就是二维指针。

不如这样吧。

int *p1=(int *)malloc(sizeof(int)*5);

int *p0=(int *)malloc(sizeof(int)*5);

int *p2=(int *)malloc(sizeof(int)*5);

int *p3=(int *)malloc(sizeof(int)*5);

int *p4=(int *)malloc(sizeof(int)*5);

int **p=(int **)malloc(sizeof(int *)*5);

明白了么?

真正的二维。

可以用*(*(p+i)+j)来访问。