📀4.数组参数
💿4.1.一维数组传参
🌰请看代码👇
#include<stdio.h> void test(int arr[])//ok {} void test(int arr[10])//ok {} void test(int* arr)//ok {} void test2(int* arr2[20])//ok {} void test2(int **arr2)//ok {} int main() { int arr[10] = { 0 }; int* arr2[20] = { 0 }; test(arr); test2(arr2); return 0; }
💡一维数组传参的时候,形参可以是数组,也可以是指针
💡当参数是指针的时候,要注意类型
💿4.2.二维数组传参
🌰请看代码👇
void test(int arr[3][5])//ok {} void test(int arr[][])//NO {} void test(int arr[][5])//ok {} //二维数组传参,函数形参的设计只能省略第一个[]的数字 //因为对一个二维数组。可以不知道有多少行,但是必须知道一行有多少个元素 void test(int *arr)//NO {} void test(int* arr[5])//NO {} void test(int (*arr)[5])//ok {} void test(int **arr)//NO {} int main() { int arr[3][5] = { 0 }; test(arr); return 0; }
💡二维数组传参,参数可以是指针,也可以是数组
💡如果是数组,行可以省略,但是列不能省略
💡如果是指针,传过去的是第一行的地址,形参就应该是数组指针
📀5.指针参数
💿5.1.一级指针传参
🌰请看代码👇
void print(int* p, int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d\n", *(p + 1)); } } 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]); //一级指针p,传给函数 printf("%d\n", sz); print(p, sz); return 0; }
💡当函数的参数部分是一级指针的时候,可以接收什么参数?
👉 int a;
print (&a,10);
👉 int * p1= &a;
print (p1,10);
👉int arr[10];
print (arr,10);
💿5.2.二级指针传参
🌰请看代码👇
void test(int** ptr) { printf("%d\n", **ptr); } int main() { int n = 10; int* p = &n; int **pp = &p; test(pp); test(&p); return 0; }
💡当函数的参数部分是二级指针的时候,可以接收什么参数?
👉 test (二级指针变量);
👉 test (一级指针变量的地址);
👉 int * arr[10];
👉 test (arr);
📀6.函数指针
👉类比一下:
整型指针 ---- 指向整型的指针 ---- int *
字符指针 ---- 指向字符的指针 ---- char *
数组指针 ---- 指向数组的指针 ---- int arr[10]; int (*p)[10] = &arr;
函数指针 ---- 指向函数的指针 ---- int (*pf)(int, int) = Add;
💡函数名 和 &函数名 都是函数的地址,没有区别👇
int main() { printf("%p\n", &Add); printf("%p\n", Add); return 0;
🌰请看代码👇
int Add(int x, int y) { return x + y; } // &函数名得到的就是函数的地址 int main() { //printf("%p\n", &Add); //printf("%p\n", Add); int (*pf)(int, int) = Add;//函数的地址要存起来,就要放在 函数指针变量 中 // pf就是函数指针 //int ret = (*pf)(3, 5); 这里的*没什么用,就是摆设 //int ret = Add(3, 5); int ret = pf(3, 5); printf("%d\n", ret); return 0; }
🌰再举个栗子,请看代码👇
char* test(int c, float* pf) { } int main() { char* (*pt)(int, float*) = test; return 0; }
🥰希望烙铁们能够理解🥰
💿6.1. 代码1
看代码和注释👇
int main() { (*( void (*)() ) 0)();// 这是一次函数调用 //1.将0强制类型转换成 void(*)()类型的函数指针 //2.这就意味着0地址处放着一个函数,函数没参数,返回类型是 void //3.调用0地址处的这个函数 return 0; }
💿6.2. 代码2
int main() { void (* signal(int, void(*)(int) ) )(int);// 是一个函数的声明 //函数的名字是 signal //signal函数的参数第一个是int类型,第二个是void(*)(int)类型的函数指针 //该函数指针指向的函数参数是int,返回类型是void // //signal函数的返回类型也是一个函数指针 //该函数指针指向的函数参数是int,返回类型是void return 0; }
📀7.函数指针数组
💡数组的每个元素是一个函数指针
🌰请看代码👇
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() { //存放函数指针的数组 ---- 函数指针数组 int(*pf[4])(int, int) = { Add,Sub,Mul,Div }; int i = 0; for (i = 0; i < 4; i++) { int ret = pf[i](8, 4); printf("%d\n", ret); } 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; } void menu() { printf("****************************************\n"); printf("****** 1.add 2.sub *******\n"); printf("****** 3.mul 4.div *******\n"); printf("****** 5.exit *******\n"); printf("****************************************\n"); } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; //转移表 int (*pf_Arr[5])(int, int) = {NULL,Add,Sub,Mul,Div}; do // 0 1 2 3 4 { menu(); printf("请选择:>"); scanf("%d", &input); if (input == 0) { printf("退出计算器\n"); break; } else if (input >= 1 && input <= 4) { printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = pf_Arr[input](x, y); printf("%d\n", ret); } else { printf("选择错误\n"); break; } } while (input); return 0; }