函数
为什么需要函数
-
避免了重复性操作
-
有利于程序的模块化
1 # include <stdio.h> 2 3 void max(int i, int j)//自定义的函数,相当于一个工具,目的是消除大量同类型的操作,提高代码效率。此函数的功能是比较两个数值的大小,并输出 ;其中int i, int j叫做形式参数,简称形参 4 { 5 if(i>j) 6 printf("%d\n",i); 7 else 8 printf("%d\n",j); 9 } 10 11 int main()//主函数,可以理解为程序的入口和出口 12 { 13 int a, b, c, d, e, f; 14 a = 1, b = 2, c = 4, d = 3, e = 5, f = 6;//运用了逗号表达式 15 16 max(a, b);//程序执行到此步时,会从程序中查找以max命名的函数,如果函数名、形参类型等一致,就会自动跳转到max函数中执行,执行完毕后系统会释放掉分配给max的内存空间 17 max(c, d);//系统会再次分配给max函数内存空间,运行结束时,释放分配的内存空间 18 max(e, f); 19 20 /* 21 if(a>b) 22 printf("%d\n",a); 23 else 24 printf("%d\n",b); 25 26 if(c>d) 27 printf("%d\n",c); 28 else 29 printf("%d\n",d); 30 31 if(e>f) 32 printf("%d\n",e); 33 else 34 printf("%d\n",f); 35 如果需要对大量数字进行比较,那么代码量就会变得十分大,且繁琐。 36 通过总结,我们可以发现一个规律,那就是代码大部分是相同的,不同的是比较的值有所改变 37 */ 38 return 0; 39 }
什么叫函数
逻辑上:能够完成特定功能的独立的代码块
物理上:
能够接受数据[当然也可以不接受数据]
能够对接受的数据进行处理
能够将数据处理的结果返回[当然也可以不返回任何值]
1 # include <stdio.h> 2 3 int f(void)//括号内的void表示该函数不能接受数据 int表示函数的返回值的类型是int 4 { 5 6 return 10;//向主调函数返回10 7 } 8 9 void g(void)//函数名前面的void表示该函数没有返回值 10 { 11 //return 2;//不能写返回值,因为void已经表明没有返回值了 12 } 13 14 int main () 15 { 16 int j, i; 17 18 j = f(); 19 printf("%d\n",j); //输出结果为10 20 21 //i = g()//会报错,因为g函数没有返回值 22 23 return 0; 24 }
总结:函数是个工具,他是为了解决大量类似问题而设计的,函数可以当做一个黑匣子
如何定义函数
函数的返回值 函数的名字(函数的形参列表)
{
函数的执行体
}
-
函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法
-
return 表达式; 的含义
-
终止被调函数,向主函数返回表达式的值
-
如果表达式为空,则只终止函数,不向主调函数返回任何值
-
break是用来终止循环和switch的,return是用来终止函数的
-
-
函数返回值的类型也称为函数的类型,因为如果函数名前的返回值类型和函数执行体中的return表达式;中表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型为准
1 # include <stdio.h> 2 3 int f() 4 { 5 return 10.5;//因为函数的返回值类型是int,那么最终f返回的是10还是10.5 ? 6 } 7 8 int main() 9 { 10 double i; 11 i = f(); 12 printf("i=%lf",i);//输出结果: i=10.000000 13 14 return 0; 15 }
函数的分类
有参函数 和 无参函数
有返回值函数 和 无返回值函数
库函数 和 用户自定义函数
值传递函数 和 地址传递函数
普通函数 和主函数(main函数)
一个程序必须有且只能有一个主函数
主函数可以调用普通函数 普通函数不能调用主函数
普通函数可以相互调用
主函数是程序的入口,也是程序的出口
1 # include <stdio.h> 2 3 int max(int i, int j) 4 { 5 if(i>j) 6 printf("%d\n",i); 7 else 8 printf("%d\n",j); 9 } 10 11 int max2(int i, int j) 12 { 13 if(i>j) 14 return i; 15 else 16 return j; 17 } 18 19 int main()//主函数,可以理解为程序的入口和出口 20 { 21 int a, b, c, d, e, f; 22 a = 1, b = 2, c = 4, d = 3, e = 5, f = 6; 23 24 printf("%d\n",max2(a, b)); 25 printf("%d\n",max2(c, d)); 26 printf("%d\n",max2(e, f)); //输出结果为2 4 6,函数max的功能是比较两个数的大小并将最大值输出,函数max2的功能是比较两个数的大小,然后将最大值返回主调函数 27 28 /* 29 max(a, b); 30 max(c, d); 31 max(e, f); 32 */ 33 34 return 0; 35 } 36
判断一个数是否为素数
1 //素数是在大于1的自然数中,除了1和它本身以外不能再有其他因数的数(也就是不能被其他数整除的数) 2 3 # include <stdio.h> 4 5 bool Isprime(int val)//真假用bool类型表示 6 { 7 int i; 8 9 for(i=2; i<val; ++i) 10 { 11 if(val%i == 0)//如果一个数值能被整除,那么它不是素数,反之一定是素数,因为素数只能被1和它本身整除 12 break;//当一个数值能被整除时,余数为0,表达式成立,执行break语句,跳出循环 13 } 14 if(i == val)//只有素数才能执行到这一步,因为只有i达到最大值,i<不成立,跳出循环,但i的值已经为val了,所以为素数 15 return true; 16 else 17 return false; 18 19 } 20 21 int main() 22 { 23 int m; 24 printf("请输入想测试的数值:\n"); 25 scanf("%d",&m); 26 27 if(Isprime(m)) 28 printf("您输入的值是素数\n"); 29 else 30 printf("您输入的值不是素数\n"); 31 32 return 0; 33 }
注意的问题
函数的调用和函数定义的顺序
如果函数调用写在了函数定义的前面,作为必须加函数前置说明
函数前置声明:
-
告诉编译器即将可能出现的若干个字母代表的是一个函数
-
告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况
-
函数声明是一个语句,末尾必须加分号
-
对库函数的声明是通过 # include <库函数所在的文件的名字.h>来实现的
形参和实参
个数相同 位置一一对应 数据类型必须相互兼容
如何在开发中合理的设计函数来解决实际问题
一个函数的功能尽量独立、单一
多学习,多模仿牛人的代码
1 /* 2 求1到某个数字之间的所有的素数(包括该数字),并将其输出 3 只用main函数实现,有局限性: 4 1.代码的重用性不高 5 2.代码不容易理解 6 */ 7 # include <stdio.h> 8 9 int main() 10 { 11 int m; 12 int i, j; 13 printf("请输入想测试的数值:\n"); 14 scanf("%d",&m); 15 16 for(i=2; i<=m; ++i) //i表示输入值之前的数,也就是说我们需要判断i是否是素数 17 { 18 for(j=2; j<i; ++j)//也就是i需要分别与2~(i-1 ) 之间的值进行除法运算,所以声明一个j 19 { 20 if(0==i%j) 21 break; 22 } 23 if(i==j) 24 printf("%d\n",i); 25 } 26 27 return 0; 28 }
1 /* 2 求1到某个数字之间的所有的素数(包括该数字),并将其输出 3 本程序和上一个程序相比,代码量更少,可重用性更高 4 */ 5 # include <stdio.h> 6 7 //本函数的功能是:判断val是否为素数,是返回true,不是返回false 8 bool Isprime(int val) 9 { 10 int i; 11 12 for(i=2; i<val; ++i) 13 { 14 if(val%i == 0) 15 break; 16 } 17 if(i == val) 18 return true; 19 else 20 return false; 21 22 } 23 24 //本函数的功能是把1和n之间所有的素数在显示器上输出 25 void TraverseVal(int n) 26 { 27 int i; 28 29 for(i=2; i<=n; ++i) //i表示输入值之前的数,也就是说我们需要判断i是否是素数 30 { 31 if( Isprime(i) ) 32 printf("%d\n",i); 33 } 34 } 35 36 37 int main() 38 { 39 int m; 40 printf("请输入想测试的数值:\n"); 41 scanf("%d",&m); 42 43 TraverseVal(m); 44 45 return 0; 46 }
double sqrt(double x);
求的x的平方根
int abs(int x)//x是整数
求x的绝对值
double fabs(double x)//x是小数
求x的绝对值
专题:
递归
实现一种先进后出的一种结构,都可以称为栈
变量的作用域和存储方式
按作用域分
全局变量
在所有函数外面定义的变量叫全局变量
全局变量的使用范围:从定义位置开始到整个程序结束
局部变量
在一个函数内部定义的变量或者函数的形参,都统称为局部变量
局部变量的使用范围:只能在本函数内使用
注意的问题
全局变量和局部变量命名冲突的问题
在一个函数内部如果定义的局部变量的名字和全局变量名一样时,局部变量会屏蔽掉全局变量,也就是说会输出局部变量
按变量的存储方式
静态变量
自动变量
寄存器变量