第一种函数形参的写法:
#include <stdio.h>
#define R 5 // 行数
#define C 5 // 列数
void printMatrix ( int a[ ][C] , int row, int column ) // 使用 int a[R][C] 也可以 , 但是 int a[][] ,就不行!
{
int i , j;
for ( i = 0; i < row; i++)
{
for( j = 0; j < column; j++)
printf(" %d\t", a[i][j] );
printf("\n");
}
}
int main()
{
int a[R][C];
int i , j;
int count = 1;
for ( i = 0; i < R; i++)
for( j = 0; j < C; j++)
a[i][j] = count++;
printMatrix(a,R,C); //打印二维数组
return 0;
}
第二种函数形参的写法:
#include <stdio.h>
#define R 5
#define C 5
void printMatrix ( int (*a)[C] , int row, int column )
......(其他代码,同上)
第三种函数形参的写法:
#include <stdio.h>
#define R 5
#define C 5
void printMatrix ( int *a , int row, int column )
{
int i , j;
for ( i = 0; i < row; i++)
{
for( j = 0; j < column; j++)
printf(" %d\t", *( (a+(i*column)) + j ) );
// i*column 是相对数组首地址的“行偏移”量 ,j 是行内的“列偏移”
printf("\n");
}
}
int main()
{
int a[R][C];
int i , j;
int count = 1;
for ( i = 0; i < R; i++)
for( j = 0; j < C; j++)
a[i][j] = count++;
printMatrix( (int *)a, R, C); // 将二维数组名(数组首元素地址)强制转换 为 int *类型, 即转换为指向整型的指针
return 0;
}
总结:
1. 在第一种和第二种函数形参列表的写法中,必须给出二维数组的第二维的值(即列数),而且必须是常量! !!
2. 第三中写法中,注意对数组名(数组首元素地址)的强制转换,将其转换为普通的整型指针变量!
(因为,二维数组名虽然代表了一个整型指针,但是这个整型指针的属性(步长)是 ( sizeof(int) * column )就是 4 * 5 = 20 个字节 ,见下图)
//其他代码同上
printf(" a = %d \n", a); //打印 a的值,即二维数组首元素的地址
printf("a+1 = %d \n", a + 1 ); //打印 a+1 的值, 测试 a 的步长
3. 由第2点可以知道,第三种写法的本质是将一个“二维数组” 当做一个 “一维数组” 来操作! (其实,二维数组,在内存中就是按一维形式存储的! 好吧! 写个测试程序!)
#include <stdio.h>
int main()
{
int a[3][3] ={ { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
printf("a[2][2] = %d\n", a[1][1] );
printf("a[0][4] = %d\n", a[0][4] ); //二维数组(或更高维数组)是以一维的形式存储的(物理内存单元都是连续的)
printf("\n");
printf("*((int*)a + (1*3)+1) = %d\n" , *((int*)a + (1*3)+1) ) ;
//同上, (int *)a 是强制转换,(1*3)是相对首地址的“行偏移”,1是“列偏移”
return 0;
}