Appearance
函数
定义:类型 函数名(形式参数)
代码块
老式的代码格式在参数列表和函数体之间定义形式参数
Cint *fint_int(key, array, array_len) int key; int array[]; int len; {
函数声明
当编译器遇到一个函数的时候,如果没有特定的信息,会假定参数的种类和数量是对的,并且返回一个整形
如果一个文件已经出现了一个函数的定义,编译器就会记住,在之后的调用中确保正确,但是老式的定义方法只会检查返回值的定义
在函数的声明的时候,参数的名字不是必要的,但是格式是必要的
一个没有参数的函数
int *func(void);
,如果没有void会使得按照旧式声明
函数的参数
C函数均采用传值调用,会对参数进行一次拷贝,数组除外
在调用旧式参数的时候会对参数进行提升 char、short ==> int , float ==> double,新式函数不会
ADT和黑盒
抽象数据类型(ADT),实现方式:模块具有功能说明以及接口说明,用户并不需要知道细节,除了定义好的接口,用户不能以任何方式访问模块
递归
C
1 #include <stdio.h>
2 //使用递归的方法打印一个数字
3 void binary_to_ascil(unsigned int value)
4 {
5 unsigned int quotient;
6
7 quotient = value / 10;
8 if(quotient != 0)
9 binary_to_ascil(quotient);
10 putchar(value % 10 + '0');
11 }
12 int main(void)
13 {
14 binary_to_ascil(123321);
15 return 0;
16 }
追踪递归函数
函数被调用的时候它的参数是保存在运行时候的堆栈上面,以前调用的函数的参数也保存在堆栈上面,但是被新的函数掩盖不能调用,
C
//计算阶乘
long factorial(int n)
{
if(n <= 0)
return 1;
else
return n * factoral(n-1);
}
C
//计算斐波那契数
long fibonacci(int n)
{
if(n <= 2)
return 0;
return fibonacci(n-1) + fibonacci(n-2);
}
// 由于在调用的时候会导致一个数被反复计算,所以会增加极多的计算量
可变参数列表
使用stdarg.h
定义了一个类型va_list
,三个宏va_start, va_arg, va_end
配合使用
va_start
: 有两个参数,第一个参数是使用va_list
初始化的列表,第二个参数是最后一个有名字的参数
va_arg
: 访问参数,va_list
的变量,以及变量的类型
va_end
: 结束调用
C
#include <stdarg.h>
float average(int n_value, ...)
{
va_list var_arg;
int count;
float num = 0;
va_start(var_arg, n_value);
for(count = 0; count < n_value; count += 1){
sum += va_arg(var_arg, int);
}
va_end(var_arg);
return sum / n_values;
}
**注:**不能判断实际的参数数量,不能判断参数的种类