函数

来源:互联网 发布:ubuntu 17.04 lts 编辑:程序博客网 时间:2024/06/04 19:53
c语言是模块化程序设计。
函数可以看成模块化程序设计的最小单位
c程序可以由一个或多个源程序文件组成,一个源程序文件又可以由多个函数组成。
main()是一个程序的入口
函数分为:
1,标准库函数:调用这些函数需要包含头文件.<stdio.h>,<math.h>.
2.自定义函数。

函数的定义:
返回值类型  函数名(  类型  形式参数1,类型 形式参数2,...)     <--函数头部
{
声明语句序列
可执行语句序列
}


在函数体内部定义的变量只能在函数体内部访问。
函数头部参数表里的变量称为形式参数,形参也是内部变量,只能在函数体内部访问
形参表是函数的入口。
如果说函数名相当于说明运算的规则的话,那么形参表里的形参就相当于运算的操作数,函数的返回值就是运算的结果。
没有返回值就用void定义返回值的类型。

关键字return后面的变量或表达式的值代表函数要返回的值,它的类型应该与函数定义头部中声明的函数返回值类型一致。

一个函数必须被main()调用才能发挥作用。
函数调用:main()函数调用函数Fact(),必须提供一个成为实际参数的表达式给被调用的函数。
调用其他函数称为主调函数,被调用的函数称为被调函数,实参复制给形参的过程被称为参数传递。

若定义main()时未显示指明其返回值的类型,也未使用void,则其返回值将被默认为int类型,但通常将函数写成:
int main () int main (void)
{ {
..... 或者....
return 0 ; return 0;
} }

一般都是前者居多。


函数的封装:函数调用时用户只需要知道函数对外的接口(参数和返回值),不需要知道算法实现和内部定义的变量。

函数对外界的影响仅仅是几个入口参数。


//求n!#include <stdio.h>long jiecheng( int n ){int i = 1;long result = 1;if( n == 0||n == 1 ){result = 1;}else{for( i = 1;i <= n ;i++ )  //循环n次{result *= i;}}return result ;}int main(){int a = 0;long jieguo = 0;do {printf("input a num for n!\n");scanf("%d",&a);}while( a < 0 );            //判断参数是否输入正确jieguo = jiecheng( a );      //传参printf("%d! = %ld\n",a,jieguo);return 0;}
input a num for n!
12      
12! = 479001600


刚刚的阶乘的函数需要进行对入口(参数)的合法性的维护,维护程序的健壮性。
判断n必须大于0

//求组合C k(上标) m(下标) =  m!/{k!*(m-k)!}#include <stdio.h>long jiecheng( int n )   //阶乘函数{int i = 1;long result = 1;for ( i = 1;i <= n; i++){result *= i;}return result;}int main(){int m = 0;int k = 0;long zuhe ;    printf(" input k m :\n ");scanf("%d,%d",&k,&m);if( m < k || m <= 0 || k <= 0 )      //判断值是否输入正确{printf("input error!,please reinput!\n");printf(" input k m :\n ");scanf("%d,%d",&k,&m);}if( m == k )      //组合特殊情况{zuhe = 1;}else{zuhe = jiecheng( m )/(jiecheng( k )*jiecheng( m - k ));//公式}printf("result = %ld\n",zuhe);return 0;}

[root@localhost 413hanshu]# ./a.out
 input k m :
 5,10
result = 252
[root@localhost 413hanshu]# ./a.out
 input k m :
 3,6
result = 20


如果一个对象部分地由它自己组成或按它自己定义,则我们称之为递归。就是由自己推出自己
还是阶乘的问题:
n!:1           n=0,1;
n*(n-1)!  n>=2;

//求n!#include <stdio.h>long jiecheng( int n ){int i = 1;long result = 1;if ( n == 0||n == 1 ){result = 1;}else{result = (n*jiecheng(n - 1 ));   //阶乘}return result ;}int main(){int a = 0;long jieguo = 0;do {printf("input a num for n!\n");scanf("%d",&a);}while( a < 0 );            //判断参数是否输入正确jieguo = jiecheng( a );      //传参printf("%d! = %ld\n",a,jieguo);return 0;}

递归调用函数必须包含两种部分:
1.由其自身定义的与原始问题类似的的更小的规模的子问题,它使递归过程持续进行,称为一般情况。
2.递归调用的最简形式,它是一个能够用来结束递归调用过程的条件,通常称为基线情况

变量的作用域和存储类型
不在任意的语句块定义的变量叫全局变量。全局变量的作用域为整个程序,即全局变量在程序的所有位置都有效。
结合递归和全局变量:打印出函数fib(n)的输出值和循环次数
fib(n): 0                n=0;
1     n=1;
fib(n-1)+fib(n-2)   n>1;

#include <stdio.h>#include <stdlib.h>int count = 0;              //计数递归调用了多少次int fib( int n){int result = 0;count ++;                //计数递归调用次数if( n < 0)               //判断是否输入正确{printf("input error!\n");exit (0) ;}else if( n == 0 ){result = 0;}else if( n == 1 ){result = 1;}else{result = fib( n - 1) + fib ( n - 2 );  //递归}return result;}int main(){int a = 0;int Result = 0;printf("intput n \n");scanf("%d",&a);Result = fib (a);printf("result = %d\n",Result);printf("count = %d\n",count);return 0;}

[root@localhost 413hanshu]# ./a.out
intput n 
5
result = 5
count = 15


变量的存储类型:
存储类型  数据类型  变量名表;

c语言提供了了一下几种不同的存储类型:
1.自动变量
2.静态变量
3.外部变量
4.存储器变量

1自动变量:格式: auto  类型名  变量名 
因为经常使用 auto可以省略。

在不同的并列语句内可以同名变量,不会互相干扰,因为它们各自占据着不同的内存单元,并且有着不同的作用域。
例如:形参就可以与实参同名。

可以用const将形参声明成常量,可以有效防止形参值在函数内被修改。
1.自动变量在定义 时不会自动初始化
2.自动变量在退出函数后,其分配的内存立即释放。

静态变量: static  类型名  变量名;生存周期是整个程序运行时间。整个程序执行期间,只能被初始化一次。
具有一定的记忆功能。


外部变量:  extern 类型名  变量名 ;
外部变量保存在静态存储区内,在程序运行期间分配固定的存储单元,气生存期是整个程勋的运行期。自动初始化0.

寄存器变量:没有必要。
0 0
原创粉丝点击