数组做实参和形参的秘密

来源:互联网 发布:人工智能英语论文 编辑:程序博客网 时间:2024/06/03 16:48

#include <stdlib.h>#include <stdio.h>funciton(int **a);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((int **)(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){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");}}}


 

学过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)来访问。

 

 

 

 

 

 

 

 


 

 

 

 

原创粉丝点击