一、数组参数,指针参数
1、一维数组传参
#include <stdio.h>
void test(int arr[])//ok?
{}
void test(int arr[10])//ok?
{}
void test(int *arr)//ok?
{}
void test2(int *arr[20])//ok? int *arr[]也可以
{}
void test2(int **arr)//ok?
{}
int main()
{
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
}
//上面的5种形式一维数组参数都可以
2、二维数组传参
void test(int arr[3][5])//ok?对
{}
void test(int arr[][5])//ok?对
{}
void test(int arr[3][])//ok? 错
{}
void test(int arr[][])//ok?错
{}
/*总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
这样才方便运算。
*/
void test(int *arr){}//ok?错误
//因为传入二维数组的数组名是首元素地址这个首元素是指第一个行整个数组组成首元素
void test(int **arr){}//ok?错误
/*二级指针用来存放一级指针的地址;而传过来的参数是数组首元素地址不是一个指针地址
注意:
二级指针用来存放一级指针的地址
这里是传过来的是数组首元素地址这个首元素也是一个数组组成的首元素
不是指针的地址,所以不可以
*/
void test(int* arr[5]){}//ok?错误
void test(int (*arr)[5]){}//ok?正确-->用数组指针存放数组的地址
int main()
{
int arr[3][5] = {0};
test(arr);
}
3、一级指针传参
#include <stdio.h>
void print(int *p, int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d\n", *(p+i));
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9};
int *p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
//一级指针p,传给函数
print(p, sz);
return 0;
}
//当一个函数的参数部分为一级指针的时候,函数能接收什么参数?
/*
void test1(int *p){} test1函数能接收什么参数?
void test2(char* p){} test2函数能接收什么参数?
*/
4、二级指针传参
#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;
}
//当函数的参数为二级指针的时候,可以接收什么参数?
void test(char **p)
{
}
int main()
{
char c = 'b';
char*pc = &c;
char**ppc = &pc;
char* arr[10];
test(&pc);
test(ppc);
test(arr);//Ok
//因为数组里面存放的是指针地址,然后将数组名传进去,相当于传入的是数组首元素地址
//该首元素是指针
//用二级指针接收一级指针的地址 ok的
return 0;
}
5、函数指针( int(*)(int,int ) )
函数指针的样子就是上面的返回值和参数类型都可变化.
void test()
{
printf("hehe\n");
}
//下面pfun1和pfun2哪个有能力存放test函数的地址?
void (*pfun1)();
void *pfun2();
/*
首先,能给存储地址,就要求pfun1或者pfun2是指针,那哪个是指针?
答案是:
pfun1可以存放。pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参
数,返回值类型为void。
pfun2和()先结合说明pfun2是一个函数 然后返回值是void*
*/
两道例题:
6、函数指针数组( int(* 指针变量[ ])(int,int) )
函数指针数组的样子返回值和参数类型都可变。
int (*parr1[10])();
/*
parr1 先和 [] 结合,说明 parr1是数组,数组的内容是什么呢?
是 int (*)() 类型的函数指针。
*/
//函数指针数组的用途:转移表
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{ int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
while (input)
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
if ((input <= 4 && input >= 1))
{
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( "输入有误\n" );
printf( "ret = %d\n", ret);
}
return 0;
}
7、回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个 函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数
传入的函数称为回调函数:这里Add就是一个回调函数。