03数组参数、指针参数 一维数组传参 #include stdio.h//形参写成数组形式void test(int arr[]){}void test(int arr[10]){}/形参写成指针形式void test(int *p){}void test2(int *arr[]){}void test2(int *arr[20]){}void test
03数组参数、指针参数
一维数组传参
#include <stdio.h>
//形参写成数组形式
void test(int arr[])
{}
void test(int arr[10])
{}
/形参写成指针形式
void test(int *p)
{}
void test2(int *arr[])
{}
void test2(int *arr[20])
{}
void test2(int** p)
{}
int main()
{
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
return 0;
}
二维数组传参
//形参写成数组的形式
void test(int arr[3][5])
{}
//1. 行可以省略,但列不能省略
void test(int arr[][5])
{}
//形参写成指针形式
//1. 列不可省略
//2. *p指向的是第一行的地址,5代表一行有多少个元素
//3. int *p[5]是错误的,它是一个指针数组
void test(int(*p)[5])
{}
//错误写法
//1. 一级指针接受普通变量的地址
void test(int *arr)
{}
//2. 第一行的地址放在了一个数组里,错误
void test(int* arr[5])
{}
//3. 二级指针是用来存放一级指针地址
void test(int** arr)
{}
int main()
{
int arr[3][5] = {0};
test(arr)
return 0;
}
一级指针传参
案例:一级指针传参遍历数组并打印;
void test(int* ptr, int sz)
{
int i = 0;
for(i = 0; i < sz; i++)
{
printf("%d ", *ptr);
ptr++;
}
}
int main()
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int* p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
test(p, sz); //p是一级指针
retuen 0;
}
当形参是一级指针的时候 int* ptr
,实参有以下情况:
//一级指针
int a = 10;
test(&a);
int *p = &a;
test(p);
//数组
int arr[10];
test(arr)
二级指针传参
void test(char** ppc)
{}
int main()
{
char a = 'w';
char* pa = &a;
char** ppa = &pa;
test(ppa);
return 0;
}
当函数的参数为二级指针的时候test(char** ppc)
,实参有如下情况:
char ch = 'a';
char* pc = &ch;
char** ppc = &pc;
char* arr[4];
test(arr);
test(&pc);
test(ppc);
函数指针
指向函数的指针,
int Add(int x, int y)
{
return x + y;
}
int test(char* str)
{}
int main()
{
int arr[10];
int (*p)[10] = &arr; //p是一个数组指针变量
//函数地址
printf("%p\n", &Add);
printf("%p\n", Add);
int (*pf)(int int) = Add; //pf就是函数指针变量
int (*pt)(char*) = test;
//调用函数
int ret = (*pf)(2,3);
//int ret = pf(2,3);
//int ret = Add(2,3);
printf("%d\n", ret);
return 0;
}
来自《C陷阱与缺陷》的一个例子:如何解释
(*(void(*)())0)()
void(* signal(int, void(*)(int)))(int)
int main()
{
//代码1:
//void(*)() 是一个函数指针类型
//(void(*)()())0 对0进行强制类型转换
//(*(void(*)()())0)()
//1. 首先是把0强制类型转换为一个函数指针类型,这就意味着0地址处放一个返回类型是void,无参的一个函数
//2. 调用0地址处的这个函数
//代码2:
//函数声明:int Add(int, int)
//signal是一个函数声明
//signal函数的参数,第一个是int类型,第二个是void(*)(int)的函数指针类型
//signal函数的返回值类型也是:void(*)(int)的函数指针
//简化:
//typedof void(* pf_t)(int); //给函数指针类型void(*)(int)重新起名叫:pf_t
//pf_t signal(int,pf_t);
return 0;
}
函数指针数组
int Add(int x, int y)
{
return x+y;
}
int Sub(int x, int y)
{
return x-y;
}
int Mul(int x, int y)
{
return x*y;
}
int Div(int x, int y)
{
return x/y;
}
int main()
{
//指针数组
//字符指针数组
char* arr[5];
//整形指针数组
int* arr2[4];
int (*pf1)(int, int) = Add;
int (*pf2)(int, int) = Sub;
int (*pf3)(int, int) = Mul;
int (*pf4)(int, int) = Div;
//函数指针数组
int (*pf[4](int, int)) = {Add, Sub, Mul, Div};
int i = 0;
for(i = 0; i<4; i++)
{
pf[i](8,2);
printf("%d\n", ret);
}
return 0;
}
案例:设计一个简单的计算器
#include <stdio.h>
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x * y;
}
int Div(int x, int y)
{
return x / y;
}
void menu()
{
printf("**************************\n");
printf("**** 1.add 2.sub ****\n");
printf("**** 3.mul 4.div ****\n");
printf("**** 0.exit ****\n");
printf("**************************\n");
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
//转移表
int (*pfArr[])(int, int) = {0, Add, Sub, Mul, Div};
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
if(input == 0)
{
printf("退出计算器\n");
}
else if(input >= 1 && input <=4)
{
printf("请输入两个操作数:>");
scanf("%d %d", &x, &y);
ret = pfArr[input](x, y);
printf("ret = %d\n", ret);
}
else
{
printf("选择错误\n");
}
}while(input);
return 0;
}
03-10