一维数组传参
void test(int arr[])
{}
void test(int arr[10])
{}
void test(int *arr)
{}
void test2(int *arr[20])
{}
void test2(int **arr)
{}
int main(){
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);//看类型是否匹配
test2(arr2);
system("pause");
return 0;
}//以上的传参都不会引发错误
//实际传递的数组大小与函数形参指定的数组大小没有关系。编译器把arr解析成指向整形元素的指针,也就是数组的首地址,方括号中加不加指定数字都可以,因为编译器根本不看,实际传递的数组大小与函数形参指定的数组大小没有关系。因此最好不写,以免引起误解。
//正确的传参方式写法:
void test(int arr[])//正确写法1
{}//数组作为函数参数的时候,不会把整个数组传递过去。
//实际上只是把数组的首元素的地址传递过去了。所以即使在函数参数部分写成数组的形式:
//int arr[] 表示的依然是一个指针: int *arr
void test2(int* arr)//正确写法2
{}//参数是指向整形元素的指针,而数组的名字又是首元素的地址,也印证了数组名是指针常量。
//数组传参,如果函数内部需要知道数组元素个数,应该在函数外部算出元素个数,以参数的形式传递给函数
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{}
array(i) = (array + i) //这是个指针,指向第i个元素。
array[i] = *(array + i) //这是数组的第i个元素。
二维数组传参
void test(int arr[3][5]) //√
{}
void test(int arr[][]) //×
{}
void test(int arr[][5]) //√
{}
//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
void test(int *arr) //×
{}
void test(int* arr[5]) //×
{}
void test(int(*arr)[5]) //√
{}
void test(int **arr) //×
{}
int main()
{
int arr[3][5] = { 0 };
test(arr);
return 0;
}
//第一种形参 二维数组
(声明)
void function(int a[m][n]);
void function(int a[][n]);//不论多少维数组,第一维都可省略
//第二维就不可省略,由编译器的寻址方式决定
(调用)
function(a);//直接写数组名
(操作元素)
1. *(a[i] + j) //代表第 i 行 第 j 列
2. *(*(a+i) + j) //同上
3. *((int *)a +i*n +j )//同上,n表示第二维数组长度,即列宽4
//a[i][j]不被允许。由编译器的寻址方式决定。
//第二种形参 数组指针
(只是声明和第一种不同)
void function(int (*a)[n]); //[] 的 优先级比 *的大
//第三种形参 二级指针
(声明)
void function(int **a,int n); //n表示第二维数组长度,即列宽
(调用)
function( (int **)a,int n);
(操作元素)
*((int *)a +i*n +j )//只有一种。n表示第二维数组长度,即列宽
指针传参
函数传参:就是形参复制一份实参的值,抱回函数体里算
- 函数内部修改外部变量的值,需要一级指针;
- 函数内部修改外部指针变量的值,需要二级指针;
//一级指针传参
#include <stdio.h>
void print(int *p, int sz) {
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d\n", *(p+i));
}
}
void test(int *p)
{}
int main()
{
int num;
int *p2 = #
int arr[10];
test(&num);
test(p2);
test(arr);
}
//当一个函数的参数部分为一级指针的时候,函数能接收什么参数?
//整型变量的地址
//一级指针
//数组首元素的地址(整形地址)
//二级指针传参
#include <stdio.h>
void test(int** ptr)
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}//n的地址存放在p中,p的地址存放在pp中。
//p是一级指针,pp是二级指针。
//**pp先通过*pp找到p,然后再对p进行解引用操作:*p, 找到a.
//当函数的参数为二级指针的时候,可以接收什么参数?
//一级指针变量取地址
//二级指针变量
//指针数组
void test(char **p) {}
int main()
{
char c = 'b';
char*pc = &c;
char**ppc = &pc;
char* arr[10];
test(&pc);
test(ppc);
test(arr);
return 0;
}