Inspried by LeetCode, I plan to write this blog to distinguish some confusion between different arrays in C language,especally between pointer array and two-dimensional array.
First:一维数组的数组名及其参与的函数的参数传递
一、一维数组的数组名:
1、一维数组的数组名与关键字”sizeof“连用表示计算数组所占字节数或者与“&”连用时表示获得整个数组的地址。
2、一维数组的数组名除了上述使用情形外,则表示数组首元素的地址。
arr[ ]:
sizeof(arr) --- 计算数组arr所占字节数,arr代表整个数组
arr == &arr[0]; --- 首元素地址与数组名的含义相同
&arr+1 --- 跳过数组arr访问
&arr == arr --- &arr得到整个数组地址在数值上 == arr数组名/首元素地址
&arr != arr --- &arr得到整个数组的地址在含义上 != arr数组名
arr+x --- 得到数组中第x+1个元素的地址
二、一维数组的参数传递:
1、一维数组参与函数传参时,实际上传过去的数组首元素的地址或者说是数组名,本质上是一个地址。
2、在形参接收时,只需要用一个指针变量或者写成arr[ ]的方式即可。
3、通常函数传递数组时,一般会操作数组的元素,因此在函数传递的同时,最好也将数组元素的个数传递过去,防止数组越界访问。
实参写法:arr或者&arr[0]
形参接收:数组类型+指针变量 或者 数组类型+arr[ ]
//假定int arr[];
print(arr,sizeof(arr)/sizeof(arr[0])); //形参
void print(int* arr,int sz); //实参
void print(int arr[],int sz); //实参
Second:二维数组的数组名及其参与的函数的参数传递
一、二维数组的数组名
1、二维数组的数组名与关键字”sizeof“连用表示计算数组所占字节数或者与“&”连用时表示获得整个数组的地址。
2、二维数组的数组名除了上述的使用情形外,则表示二维数组中第一行元素的整体地址或者说是二维数组中第一个一维数组的地址。
arr[ ][ ]:
sizoeof(arr) --- 计算二维数组所占字节数
&arr --- 整个二维数组的地址
arr --- 第一行元素的整体地址或第一个一维数组的地址
&arr == arr == &arr[0] == arr[0] == &arr[0][0] --- 地址在数值上相等
&arr != arr != arr[0] --- &arr整个二维数组的地址,arr[0]二维数组的首个一维数组名
&arr[0] == arr --- 都代表二维数组第一行元素的地址
arr[0] != &arr[0] --- arr[0]是二维数组中首个一维数组的数组名,&arr[0]首个一维数组地址
arr[0] ==&arr[0][0] --- 都代表二维数组第一行第一列元素的地址
二、二维数组的参数传递
1.二维数组的参数传递分为行指针传递和列指针传递。行指针转递指将二维数组看成多个一维数组的值的集合,传递一维数组的地址,在形参接收时采用数组指针来接收;列指针指将二维数组的元素分而治之,传递第一个元素的地址。
2.在二维数组作为函数参数传递时,通常在函数内部对二维数组的元素进行操作,通常将二维数组对应的行数和列数也进行传递,避免数组越界访问。
行指针实参写法:arr或者&arr[0]
形参写法:类型名+(*指针名)[行元素个数]
函数中访问元素写法:*(*(p+i)+j)
列指针实参写法:arr[0]或者&arr[0][0]
形参写法:类型名+*指针名
函数中访问元素写法:*(p+i*col+j)
//假定二维数组int arr[][]:
print(arr,ROW,COL);
print(&arr[0],ROW,COL); //行指针实参写法
void print(int(*p)[col],ROW,COL); //行指针形参写法
//int (*p)[col]表示p是一个指针变量,指向的是一个拥有5个元素的数组,数组的元素类型是int型
print(arr[0],ROW,COL);
print(&arr[0][0],ROW,COL); //列指针实参写法
print(int* p,row,col); //列指针实参写法
Third:指针数组的数组名及其参与的函数的参数传递
一、一维指针数组的数组名
1.一维指针数组本质还是一维数组,不过是数组的元素变成了指针变量。数组名的用法与一维数组相同。
2.一维普通数组的数组名是存放的是常量,函数名作为一级指针变量;而指针数组存放的是指针变量,因此指针数组的数组名是二级指针,存放的是指针变量地址。
二、一维指针数组的参数传递
1.一维指针数组的数组名是二级指针,元素存放的是指针变量。
2.在函数的形参接收时,应定义二级指针变量来接受。
实参写法:str或者&str[0]
形参写法:类型名+**指针变量
//假定有数组char* str[5]
print(str,sz);
print(&str[0],sz); //实参写法
void print(char** str,sz); //实参写法
Especally between pointer array and two-dimensional array.
一、指针数组的数组名等于&指针数组的第一个元素
指针数组的数组名不等于指针数组对第一个元素的索引
str == &str[0]
str != str[0]
二、str或者&str[0]拿到的时指针变量类型的数组元素的地址,存放的是指针变量的地址,因此是作为二级指针的存在。
三、指针变量作为函数参数与行指针作为函数参数时对元素访问的一致性
1.在指针数组中,*(str+i)相当于拿到了第i+1个元素的地址;在二维数组中,*(str)+i拿到了第i+1行元素的地址,其本质是相同的。
2.在指针数组中,*(*(str+i)+j)是在拿到第i+1个元素的地址后,访问其第j+1个元素;在二维数组中,*(*(str+i)+j)在拿到第i+1行元素的地址后,访问第i+1行第j+1个元素,其本质是相同的。
3.区分指针数组和二维数组在元素访问以及函数传参方面的相似性。