函数
为什么需要函数
避免了重复性操作
有利于程序的模块化
1 /* 2 2015年4月3日 08:53:09 3 目的: 4 函数的例子,输出a , b 5 c , d 6 e , f 7 中的最大值 8 9 */ 10 11 # include <stdio.h> 12 13 int main(void) 14 { 15 int a, b, c, d, e, f; 16 17 a = 1, b = 2, c = 3, d = 9, e = -5, f = 100; 18 //逗号表达式从左往右执行,整体表达式的值是100,即最右边的值 19 20 if (a > b) 21 printf("%d\n", a); 22 else 23 printf("%d\n", b); 24 25 if (c > d) 26 printf("%d\n", c); 27 else 28 printf("%d\n", d); 29 30 if (e > f) 31 printf("%d\n", e); 32 else 33 printf("%d\n", f); 34 35 return 0; 36 37 } 38 /* 39 在VC6.0中运行结果是: 40 ----------------------------- 41 2 42 9 43 100 44 ----------------------------- 45 总结:重复代码不合适 46 47 48 */
1 /* 2 2015年4月3日 09:05:30 3 目的: 4 函数的例子,输出a , b 5 c , d 6 e , f 7 中的最大值 8 9 */ 10 11 # include <stdio.h> 12 13 //max是函数名, i 和 j 是形式参数,简称形参,void表示函数没有返回值 14 void max(int i, int j) 15 { 16 if (i > j) 17 printf("%d\n", i); 18 else 19 printf("%d\n", j); 20 } 21 22 int main(void) 23 { 24 int a, b, c, d, e, f; 25 26 a = 1, b = 2, c = 3, d = 9, e = -5, f = 100; 27 28 max(a, b); //a和b是实参(实际参数),分别传递给i, j 29 max(c, d); 30 max(e, f); 31 32 return 0; 33 34 } 35 /* 36 在VC6.0中运行结果是: 37 ----------------------------- 38 2 39 9 40 100 41 ----------------------------- 42 总结:定义max函数 43 44 45 */
什么叫函数
逻辑上:能够完成特定功能的独立代码块
物理上:能够接收数据(也可不接受)
能够对接收的数据进行处理
能够将数据处理的结果返回(也可以不返回任何值)
总结:函数是个工具,它是为了解决大量类似问题而设计的,函数可以当做一个黑匣子
1 /* 2 2015年4月4日 16:46:04 3 目的: 4 函数的例子 5 6 */ 7 8 # include <stdio.h> 9 10 int f(void) //括号中的void表示该函数不能接收数据,int表示函数返回值是int类型 11 { 12 return 10; //向主调函数返回10 13 } 14 15 void g(void) //函数名前的void表示该函数没有返回值 16 { 17 // return 10; //error,与void相矛盾 18 } 19 20 int main(void) //main函数是主调函数,f函数是被调函数 21 { 22 int j = 88; 23 24 j = f(); 25 printf("%d\n", j); 26 27 // j = g(); //错误语句,因为g函数没有返回值 28 29 return 0; 30 31 } 32 /* 33 在VC6.0中运行结果是: 34 ----------------------------- 35 10 36 ----------------------------- 37 总结: 38 39 40 */
如何定义函数
函数的返回值 函数的名字(函数的形参列表)
{
函数的执行体
}
函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法
1.函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法
2.return 表达式; 的含义:
1> 终止被调函数,向主调函数返回表达式的值
2> 如果表示为空,则终止函数,不向主调函数返回任何值
1 /* 2 2015年04月06日 14:32:51 3 目的:return 和 break 的区别 4 5 6 */ 7 8 # include <stdio.h> 9 10 void f(void) 11 { 12 int i; 13 14 for (i=0; i<5; ++i) 15 { 16 printf("大家辛苦了!\n"); 17 return; //return是终止函数f 18 } 19 } 20 21 int main(void) 22 { 23 f(); 24 25 return 0; 26 27 } 28 /* 29 在VC6.0中运行结果是: 30 ----------------------------- 31 大家辛苦了! 32 ----------------------------- 33 总结: 34 35 */
1 /* 2 2015年04月06日 14:32:51 3 目的:return 和 break 的区别 4 5 6 */ 7 8 # include <stdio.h> 9 10 void f(void) 11 { 12 int i; 13 14 for (i=0; i<5; ++i) 15 { 16 printf("大家辛苦了!\n"); 17 break; //break是终止for循环 18 } 19 printf("同志们好!\n"); 20 } 21 22 int main(void) 23 { 24 f(); 25 26 return 0; 27 28 } 29 /* 30 在VC6.0中运行结果是: 31 ----------------------------- 32 大家辛苦了! 33 同志们好! 34 ----------------------------- 35 总结: 36 37 */
3> break是用来终止循环和switch的,return是用来终止函数的
例子:
void f()
{
return; //return只用来终止函数,不向主调函数返回任何值
}
int f()
{
return 10; //第一:终止函数;第二:向主调函数返回10
}
3.函数返回值的类型也称为函数的类型,因为如果函数名前的返回值类型 和 函数执行体中的 return 表达式; 中表达式的类型不同的话,则最终函数返回值的类型 以函数 名前的返回值类型为准
1 /* 2 2015年04月06日 14:18:16 3 目的:到底什么是函数的类型 4 5 6 */ 7 8 # include <stdio.h> 9 10 int f() 11 { 12 return 10.5; //因为函数的返回值类型是int 所以最终f返回的是10,而不是10.5 13 } 14 15 int main(void) 16 { 17 double i = 6.6; 18 19 i = f(); 20 printf("%lf\n", i); 21 22 return 0; 23 24 } 25 /* 26 在VC6.0中运行结果是: 27 ----------------------------- 28 10.000000 29 ----------------------------- 30 总结: 31 32 */
函数的分类
有参函数 和 无参函数
有返回值 和 无返回值函数
库函数 和 用户自定义函数
值传递函数 和 地址传递函数
普通函数 和 主函数(main函数)
一个程序必须有且只能有一个主函数
主函数可以调用普通函数 普通函数不能调用主函数
普通函数可以相互调用
主函数是程序的入口,也是程序的出口
例子:
1 /* 2 2015年04月06日 15:08:19 3 目的: 4 函数_判断一个数字是否是素数 5 6 7 */ 8 9 # include <stdio.h> 10 11 int main(void) 12 { 13 int val; 14 int i; 15 16 scanf("%d", &val); 17 for (i=2; i<val; ++i) 18 { 19 if (val%i == 0) 20 break; 21 } 22 if (i == val) 23 printf("Yes!\n"); 24 else 25 printf("No!\n"); 26 27 return 0; 28 29 } 30 /* 31 在VC6.0中运行结果是: 32 ----------------------------- 33 1 34 No! 35 ----------------------------- 36 总结:只能被1和它本身整除的数是素数(1除外,1不是素数) 37 38 */
1 /* 2 2015年04月06日 15:23:40 3 目的: 4 函数_判断一个数字是否是素数 5 6 7 */ 8 9 # include <stdio.h> 10 11 bool IsPrime(int val) 12 { 13 int i; 14 15 for (i=2; i<val; ++i) 16 { 17 if (val%i == 0) 18 break; 19 } 20 if (i == val) 21 return true; 22 else 23 return false; 24 } 25 26 int main(void) 27 { 28 int m; 29 30 scanf("%d", &m); 31 if ( IsPrime(m) ) 32 printf("Yes!\n"); 33 else 34 printf("No!\n"); 35 36 return 0; 37 38 } 39 /* 40 在VC6.0中运行结果是: 41 ----------------------------- 42 19 43 Yes! 44 ----------------------------- 45 总结:只能被1和它本身整除的数是素数(1除外,1不是素数) 46 47 */
注意的问题
函数调用和函数定义的顺序
如果函数调用写在了函数定义的前面,则必须加函数前置声明
函数前置声明的:
1. 告诉编译器即将可能出现的若干个字母代表的是一个函数
2. 告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况
3. 函数声明是一个语句,末尾必须加分号
4. 对库函数的声明是通过 "# include <库函数所在的文件的名字.h>" 来实现的
1 /* 2 2015年04月06日 16:14:42 3 目的: 4 一定要明白该程序为什么是错误的 5 一定要明白该程序第k行生效之后程序为什么就正确了 6 */ 7 8 # include <stdio.h> 9 10 //void f(void); //第k行,此行是自定义函数f的声明 11 12 void g(void) 13 { 14 f(); //因为函数f的定义放在了调用f语句的后面,所以语法出错 15 } 16 17 void f(void) 18 { 19 printf("哈哈!\n"); 20 } 21 22 int main() 23 { 24 g(); 25 26 return 0; 27 28 } 29 /* 30 在VC6.0中运行结果是: 31 ----------------------------- 32 33 ----------------------------- 34 总结: 35 36 */
形参和实参
个数相同 位置一一对应 数据类型必须相互兼容
如何在软件开发中合理的设计函数来解决实际问题
一个函数的功能尽量独立、单一
多学习,多模仿牛人的代码
1 /* 2 2015年04月06日 19:35:38 3 目的: 4 求1到某个数字之间所有的素数,并将其输出 5 只用main函数实现,有局限性: 6 1.代码的重用性不高 7 2.代码不容易理解 8 */ 9 10 # include <stdio.h> 11 12 int main() 13 { 14 int val; 15 int i; 16 int j; 17 18 scanf("%d", &val); 19 for (i=2; i<=val; ++i) 20 { 21 for (j=2; j<i; ++j) 22 { 23 if (0 == i%j) 24 break; 25 } 26 if (j == i) 27 printf("%d\n", i); 28 } 29 30 return 0; 31 } 32 /* 33 在VC6.0中运行结果是: 34 ----------------------------- 35 99 36 2 37 3 38 5 39 7 40 11 41 13 42 17 43 19 44 23 45 29 46 31 47 37 48 41 49 43 50 47 51 53 52 59 53 61 54 67 55 71 56 73 57 79 58 83 59 89 60 97 61 ----------------------------- 62 总结: 63 64 */
1 /* 2 2015年04月06日 19:47:19 3 目的: 4 求1到某个数字之间所有的素数,并将其输出 5 用一个函数判断一个数是否是素数 6 */ 7 8 # include <stdio.h> 9 10 bool IsPrime(int m) 11 { 12 int i; 13 14 for (i=2; i<m; ++i) 15 { 16 if (0 == m%i) 17 break; 18 } 19 if (i == m) 20 return true; 21 else 22 return false; 23 } 24 25 int main() 26 { 27 int val; 28 int i; 29 30 scanf("%d", &val); 31 for (i=2; i<=val; ++i) 32 { 33 if ( IsPrime(i) ) 34 printf("%d\n", i); 35 } 36 37 return 0; 38 } 39 /* 40 在VC6.0中运行结果是: 41 ----------------------------- 42 99 43 2 44 3 45 5 46 7 47 11 48 13 49 17 50 19 51 23 52 29 53 31 54 37 55 41 56 43 57 47 58 53 59 59 60 61 61 67 62 71 63 73 64 79 65 83 66 89 67 97 68 ----------------------------- 69 总结: 70 71 */
1 /* 2 2015年04月06日 20:07:59 3 目的: 4 求1到某个数字之间所有的素数,并将其输出 5 定义两个函数来实现求1到某个数字之间所有的素数,并将其输出 6 */ 7 8 # include <stdio.h> 9 void TraverseVal(int n); 10 bool IsPrime(int m); 11 12 //本函数的功能是把1到n之间所有的素数在显示器上输出 13 void TraverseVal(int n) 14 { 15 int i; 16 17 for (i=2; i<=n; ++i) 18 { 19 if ( IsPrime(i) ) 20 printf("%d\n", i); 21 } 22 } 23 24 //本函数的功能是:判断m是否是素数,是返回true,不是返回false 25 bool IsPrime(int m) 26 { 27 int i; 28 29 for (i=2; i<m; ++i) 30 { 31 if (0 == m%i) 32 break; 33 } 34 if (i == m) 35 return true; 36 else 37 return false; 38 } 39 40 int main() 41 { 42 int val; 43 44 scanf("%d", &val); 45 TraverseVal(val); 46 47 return 0; 48 } 49 /* 50 在VC6.0中运行结果是: 51 ----------------------------- 52 100 53 2 54 3 55 5 56 7 57 11 58 13 59 17 60 19 61 23 62 29 63 31 64 37 65 41 66 43 67 47 68 53 69 59 70 61 71 67 72 71 73 73 74 79 75 83 76 89 77 97 78 ----------------------------- 79 总结: 80 81 */
常用的系统函数
double sqrt (double x);
求x的平方根
int abs (int x);
求x的绝对值
double fabs (double x);
求x的绝对值
好书推荐:Turboc2.0实用大全
专题:
递归
变量的作用域和存储方式:
按作用域分:
全局变量
在所有函数外部定义的变量叫全局变量
全局变量使用范围:从定义位置开始到整个程序结束
局部变量
在一个函数内部定义的变量或者函数的形参 都统称为局部变量
void f (int i)
{
int j = 20;
}
i 和 j 都属于局部变量
局部变量适用范围:只能在本函数内部使用
注意的问题:
全局变量和局部变量命名冲突的问题
在一个函数内部如果定义的局部变量的名字和全局变量名一样时,局部变量会屏蔽掉全局变量
1 /* 2 2015年04月07日 10:12:42 3 目的: 4 全局变量和局部变量命名冲突的问题 5 6 */ 7 8 # include <stdio.h> 9 10 int i = 99; 11 12 void f(int i) 13 { 14 printf("i = %d\n", i); 15 } 16 17 int main(void) 18 { 19 f(8); 20 21 return 0; 22 } 23 /* 24 在VC6.0中运行结果是: 25 ----------------------------- 26 i = 8 27 ----------------------------- 28 总结: 29 30 */
按变量的存储方式
静态变量
自动变量
寄存器变量