10.函数【郝斌C语言入门学习】
函数
C语言的函数和其他语言的函数使用方法存在很大的不同,学好C语言的面向过程的函数才能理解面向对象的函数。
1.为什么需要函数
避免了重复性操作,有利于程序的模块化
# include <stdio.h> //max是函数的名字,x和y是形式参数,void表示函数没有返回值 void max(int x, int y) { if (x>y) printf("%d\n", x); else printf("%d\n", y); } int main(void) { int a, b, c, d, e, f; a=1, b=2, c=3, d=9, e=-5, f=100; max(a, b); max(c, d); max(e, f); /* if (a>b) printf("%d\n", a); else printf("%d\n", b); if (c>d) printf("%d\n", c); else printf("%d\n", d); if (e>f) printf("%d\n", e); else printf("%d\n", f); */ return 0; } /* 在vc++6.0中的输出结果: 2 9 100 */
2.什么叫函数
1 #include <stdio.h> 2 int f(void) //括号中的void表示该函数不能接受数据,函数名前int表示函数返回值是int类型 3 { 4 return 10;//向主调函数返回10 5 } 6 void g(void) //函数名前的void表示没有返回值 7 { 8 // rerurn 10;//与7行的void相矛盾 9 10 } 11 int main(void) 12 { 13 int j = 88; 14 15 j = f(); 16 printf("%d\n", j); 17 // j = g(); //错误因为g()没有返回值 18 return 0; 19 }
逻辑上:能够完成特定功能的独立的代码单元。
物理上:A.能够接收数据[当然也可以不接受数据]
B.能够对接收的数据进行处理
C.能够将数据处理的结果返回[当然也可以不返回任何值]
总结:函数是个工具,是为了解决大量类似问题而设计的,函数可当做一个黑匣子。
3.如何定义函数
函数的返回值 函数的名字(函数的形参列表)
{
函数的执行体;
}
1)函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法。
2)return 表达式;的含义:
A.终止被调函数,向主调函数返回表达式的值。
B.如果表达式为空,则只终止函数,不向主调函数返回任何值。
C.break语句是用来终止循环和switch的,return是用来终止函数的
例题:
1 void f() 2 { 3 return;//return只终止函数,不向主调函数返回任何值 4 } 5 int f() 6 { 7 return 10;//终止被调函数,向主调函数返回表达式的值 8 }
1 # include <stdio.h> 2 void f(void) 3 { 4 int i; 5 for (i=0; i<5; ++i) 6 { 7 printf("大家辛苦了!\n"); 8 return;//return终止整个函数 9 } 10 printf("同志们好!\n"); 11 } 12 13 int main(void) 14 { 15 f(); 16 return 0; 17 }
3)函数返回值的类型也称为函数的类型,因为如果函数名前的返回值类型和函数执行体中的return表达式;中表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型为准。
例题:
1 # include <stdio.h> 2 int f() 3 { 4 return 10.5;//因为函数的返回值类型是int,所以最终f返回的10而不是10.5 5 } 6 int main(void) 7 { 8 int i = 99; 9 double x = 6.6; 10 x = f(); 11 printf("%lf\n", x); 12 return 0; 13 } 14 /* 15 在vc++6.0中的输出结果:10.000000 16 */
4.函数的分类
1)有参函数和无参数函数
2)有返回值函数和无返回值函数
3)库函数和用户自定义函数
4)值传递和地址传递函数
5)普通函数和主函数(main函数)
一个程序必须有且只有一个主函数
主函数可以调用普通函数,普通函数不能调用主函数
普通函数可以相互调用
主函数是程序的入口,也是程序的出口
例题1:判断两个数的大小
1 # include <stdio.h> 2 //定义比较两个整数大小的函数,输出较大的数,函数无返回值。 3 void max1(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 int main(void) 19 { 20 int a, b, c, d, e, f; 21 a=12, b=3, c=4, d=6, e= 10, f=13; 22 max1(a, b); 23 max1(c, d); 24 max1(e, f); 25 printf("%d\n", max2(a, b)); 26 printf("%d\n", max2(c, d)); 27 printf("%d\n", max2(e, f)); 28 return 0; 29 }
例题2;判断是否是素数
1 # include <stdio.h> 2 //编写函数应该尽量简单,只判断是否是素数 3 bool IsPrime(int val) 4 { 5 int i; 6 for (i=2; i<val; ++i) 7 { 8 if (val%i == 0) 9 break;//终止for循环 10 } 11 if (i == val) 12 return true; 13 else 14 return false; 15 } 16 int main(void) 17 { 18 int n;//可以定义int val,因为函数的变量只能在函数的内部使用。 19 scanf("%d", &n); 20 /* int i; 21 for(i=2; i<val; ++i) 22 { 23 if (val%i == 0) 24 break; 25 } 26 if (i == val) 27 printf("Yes!\n"); 28 else 29 printf("No!\n"); 30 */ 31 if (IsPrime(n)) 32 printf("YES!\n"); 33 else 34 printf("NO!\n"); 35 return 0; 36 }
注意:函数中定义的变量只能在函数的内部使用。
5.注意的问题
(1)函数调用和函数声明的顺序:
如果函数调用写在函数定义的前面,则必须加函数前置申明。
函数前置声明的作用:A.告诉编译器即将可能出现的若干字母代表的是一个函数;
B.告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况;
C.函数声明是一个语句,末尾必须加分号;
D.对库函数的声明是通过# include <库函数所在的文件的名字.h>来实现的
1 #include <stdio.h>//库函数的声明是通过# include <库函数所在的文件的名字.h>来实现的 2 void f(void); 3 void g(void) 4 { 5 f();//因为函数f的定义放在调用f语句的后面,所有语法出错 6 } 7 void f(void) 8 { 9 printf("哈哈!\n"); 10 } 11 12 int main(void) 13 { 14 g(); 15 return 0; 16 }
(2)函数的形参和实参
个数相同 位置一一对应 数据类型必须相互兼容
(3)如何在软件开发中合理的设计函数来解决实际问题
例题1:输出1-任意一个数之间的素数
1 /* 2 ,并输出。 3 只用main函数实现,有局限性: 4 1.代码的重用性不高 5 2.代码不容易理解 6 */ 7 # include <stdio.h> 8 int main(void) 9 { 10 int val; 11 int i; 12 int j; 13 scanf("%d", &val); 14 //输出素数 15 for (i=2; i<=val; ++i) 16 { 17 //判断i是否是素数,是输出,不是不输出 18 for (j=2; j<i; ++j) 19 { 20 if (i%j == 0) 21 break; 22 } 23 if (j == i) 24 printf("%d ", i); 25 } 26 return 0; 27 } 28 /* 29 在vc++6.0中的输出结果:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 30 */
例题2:输出1-任意一个数之间的素数(用函数调用实现)
/* 求1-某个数之间所有的素数,并输出。
用一个函数来判断一个数是否是素数
优点代码可重用性高 代码更容易理解
缺点:可重用性仍然不高。如:求1000个数字,求它们每个数字从1到它本生的素数
for (i=2; i<=val; ++i)
{ //判断i是否是素数,是输出,不是不输出 if (IsPrime(i)) printf("%d ", i); }
此处要写1000次
*/
# include <stdio.h> bool IsPrime(int val)//判断一个数是否是素数 { int i; for (i=2; i<val; ++i) { if(val%i == 0) break; } if (i == val) return true; else return false; } int main(void) { int val; int i; scanf("%d", &val); //输出素数 for (i=2; i<=val; ++i) { //判断i是否是素数,是输出,不是不输出 if (IsPrime(i)) printf("%d ", i); } return 0; } /* 在vc++6.0中的输出结果:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 */
例题3:求1000个数字,求它们每个数字从1到它本身的所有素数。
1 /* 2 求1-某个数之间所有的素数,并输出。 3 */ 4 # include <stdio.h> 5 bool IsPrime(int m); 6 //把1-n之间的所有素数输出 7 void TraverseVal(int n) 8 { 9 int i; 10 for (i=2; i<=n; ++i) 11 { 12 if (IsPrime(i)) 13 printf("%d ", i); 14 } 15 } 16 //判断m是否是素数,是返回true,不是返回false 17 bool IsPrime(int m) 18 { 19 int i; 20 for (i=2; i<m; ++i) 21 { 22 if(m%i == 0) 23 break; 24 } 25 if (i == m) 26 return true; 27 else 28 return false; 29 } 30 int main(void) 31 { 32 int val; 33 scanf("%d", &val); 34 TraverseVal(val); 35 return 0; 36 } 37 /* 38 在vc++6.0中的输出结果:20 39 2 3 5 7 11 13 17 19 40 */
如何在软件开发中合理的设计函数并解决实际问题:一个函数的功能尽量独立、单一,多学习,多模仿牛人的代码。

浙公网安备 33010602011771号