<C> 函数 函数指针
一.函数相关知识点
1.定义:对做事步骤的封装
2.声明:void PrintArr();
3.组成:返回值类型+函数名+(参数);
注:声明函数的时候 参数可以不写名字 实现的时候必须写
4.位置:主函数上面 头文件下面
5.调用:函数名+(参数);
注:调用位置在主函数中
6.实现:这里就直接放一道例题:数组的输出
1 #include<stdio.h> 2 3 void PrintArr(); 4 5 int main() 6 { 7 PrintArr(); 8 9 return 0; 10 } 11 12 void PrintArr() 13 { 14 int arr[10] = {0,1,2,3,4,5,6,7,8,9}; 15 int i; 16 for(i=0;i<10;i++) 17 { 18 printf("%d ",arr[i]); 19 } 20 }
二.返回值 函数名 以及参数的知识点
1.返回值:
①有返回值:int char float double int*等等类型
②无返回值:void
2.函数名:个人定义即可 但是函数名要有意义 例如:ADD 每个单词首字母最好大写 功能与名称相对应
但是需要注意的是不能和系统的函数重名(这是编译器的要求)
3.参数:个数不限 0个或n个 但是参数是有类型的
注:函数什么时候结束? 答:遇到return就结束
4.函数的参数和返回值:
返回值的类型和参数类型可以不一样 每个参数类型也可以不一样
注:
①函数什么时候要参数? 答:当你所需要的东西需要外部提供的时候 例如:加了豆浆和水的豆浆机 才能出豆浆
②什么时候需要返回值? 答:外部需要我的运行结果 但是有的返回值不一定会用到 例如:喝豆浆就往外倒 不喝就放在豆浆机里
这里也放一道例题:
1 #include<stdio.h> 2 3 void ADD1(int a,int b); 4 int ADD2(int a,int b); 5 6 int main() 7 { 8 int a = 1; 9 int b = 2; 10 ADD1(a,b); 11 printf("%d\n",ADD2(a,b)); 12 return 0; 13 } 14 15 void ADD1(int a,int b) 16 { 17 int sum = a + b; 18 printf("%d\n",sum); 19 } 20 21 int ADD2(int a,int b) 22 { 23 int sum = a + b; 24 return sum; 25 }
注:ADD1(a,b); 这条语句中放的就是实参
下面在实现函数的过程中括号中的参数 即void ADD1(int a,int b) 就是形参
其实这就是个实参赋值给形参的过程 参数的关系是要一一对应的
再放一道例题:定义一个函数 交换两数的值
在编程的过程中 你会发现 单纯的定义一个中间变量是无法交换两个数的值的 这是为什么呢?
因为每个作用域都有其独立的空间 所以 交换两个数的值 我们可以通过拿地址的方式来实现
1 #include<stdio.h> 2 3 void Change(int *p1,int *p2); 4 5 int main() 6 { 7 int a = 1; 8 int b = 2; 9 Change(&a,&b); 10 printf("%d %d ",a,b); 11 return 0; 12 } 13 14 void Change(int *p1,int *p2) 15 { 16 int temp = *p1; 17 *p1 = *p2; 18 *p2 = temp; 19 }
注:主函数中调用的时候:Change(&a,&b); 相当于int* p1 = &a;
三.值传递和地址传递
1.值传递:只是用实参的值
2.地址传递:当需要改变实参的内容的时候
注:指针的最大作用:跨作用域操作内存空间
[]的作用:数组传参的时候相当于*
直接放一道例题:数组传参
1 #include<stdio.h> 2 3 void PrintArr(int arr[],int nLen); 4 5 int main() 6 { 7 int arr[10] = {0,1,2,3,4,5,6,7,8,9}; 8 PrintArr(arr,sizeof(arr)/sizeof(arr[0])); 9 10 return 0; 11 } 12 13 void PrintArr(int arr[],int nLen) 14 { 15 int i; 16 for(i=0;i<nLen;i++) 17 { 18 printf("%d ",arr[i]); 19 } 20 }
四.函数指针
1.我们在主函数外声明了一个函数AA() 如果我们想在主函数中调用它有三种方法:
①AA();
②(&AA)();
③(*AA)();
这三种方法哪个都可以调用AA这个函数
2.函数的调用是:函数名+参数
本质上是:函数地址+参数
函数名就是函数的地址 这个地址指向的是字符常量区你打的这个函数的代码的位置 我们打的代码都是存在字符常量区的
3.声明一个函数的指针:
1 void (*p) () = &AA;
4.通过这个指针调用这个函数:
p(); 或者是 (*p)(); 推荐的是第二种
5.函数指针的用途:(这里我找不到太过华丽的辞藻来形容这个例子 我就直接放一道例题吧)
1 #include <stdio.h> 2 3 void AA(); 4 void BB(); 5 void CC(void (*fp)()); 6 7 int main() 8 { 9 CC(&AA); 10 CC(&BB); 11 12 return 0; 13 } 14 15 void AA() 16 { 17 printf("AA()\n"); 18 19 } 20 21 void BB() 22 { 23 printf("BB()\n"); 24 25 } 26 27 void CC(void (*fp)()) 28 { 29 (*fp)(); 30 }
6.函数指针简单例题:(声明以及调用)
1 #include <stdio.h> 2 3 int Add(int a,int b); 4 5 typedef int (*PFUN)(int,int); 6 7 int main() 8 { 9 int (*fp1)(int,int) = &Add; 10 11 PFUN fp2 = &Add; 12 13 printf("%d\n",fp1(1,2)); 14 printf("%d\n",fp2(1,2)); 15 16 return 0; 17 } 18 19 int Add(int a,int b) 20 { 21 return a+b; 22 }