第七章 函数
这一章对于有一定C的基础的人有一定优秀代码风格的人来说,并非非常虐。关于stdarg宏可能有些陌生。它负责可变參数列表的定义。
总结:
新式风格和旧式风格就不要提了。八百年前的事情。
函数常见的是把原型放在一个单独的文件中,当其它文件须要这个原型时,就用#include指令把这个文件包括进来,这个技巧能够使原型必需的拷贝份数降低到最低,有助于提高程序的可维护性。
return语句用于指定从一个函数返回的值,假设没有返回值,为void。
函数的參数是通过传值的方式进行转换,实际传递的实參的一份拷贝。因此,函数能够改动它的形參的拷贝,而不会改变參数原值。
数组名也是通过传值方式传递的。但它传给函数的是一个指针的拷贝。数组形參使用了下标引用操作,就会引发间接訪问操作,实际訪问的是数组元素。
抽象数据类型(ADT),又叫黑盒。
由接口和实现两部分组成。
接口是共同拥有。说明客户怎样使用ADT所使用的功能。
实现是私有,实际运行的部分。
递归函数直接或者间接的调用自身。
有些递归比方尾部递归能够用迭代来实现,效率会高非常多。尤其是斐波那契数列。
可变的參数数量和类型。他们能够用stdarg.h头文件所定义的宏来实现。可变參数能治从第一个到最后一个依次訪问。
以下会弄个样例来说明可变參数。
警告:
1、错误地在其它函数的作用域内编写函数原型。
恩,注意函数的链接属性。
假设在其它函数的代码块里就无法使用该函数。
2、没有为那些返回值不是整数的函数编写原型。
由于返回值的缺省值是整型。
3、在va_arg中使用错误的參数类型。导致没有定义的结果。
看个样例:
#include <stdarg.h>
/* 取形參的平均值 */
float average(int n_value,...)
{
va_list var_arg;
int count;
float sum=0;
/** 准备訪问可变參数 */
va_start(var_arg, n_values);
/* 加入取自可变參数列表的值 */
for(count = 0; count < n_values; count += 1)
{
sum += va_arg(var_arg, int );
}
/* 完毕处理可变參数 */
va_end(var_arg);
return sum/n_values;
}
參数类型必须明白在va_arg(var_arg, ***)中说明,务必!
编程提示:
1、在函数原型中使用參数名。能够给函数的用户提供很多其它的信息。
请尽量使用參数名,不要这样的:
int func(int , int);
从函数名到形參一坨shi。
2、抽象数据类型能够降低程序对模块实现的细节的以来。提高可靠性。
3、当递归定义清晰的这点能够补偿它的效率时。就用递归吧。