提示:本文是对C语言基础知识:函数部分的回顾总结
文章目录
函数定义
函数的定义就是 函数体 的实现。
函数体 就是一个代码块。
函数定义的语法如下:
类型 函数名( 形式参数 )
代码块
funciton_name()
{
...
}
函数声明出现在函数被调用的的地方。
return语句 :当执行流到达函数定义的末尾时,函数就将返回(return),也就是说,执行流返回到函数被调用的地方。
return语句允许从函数体的任何位置返回,并不一定要在函数体的末尾。
return expression;
函数声明
原型
函数原型 :总结了函数定义的起始部分声明,并向编译器提供有关该函数应该如何调用的完整信息。
int *find_int( int key, int array[], int len);
注意:最后面的分号,区分了函数原型和函数定义的起始部分。
一个没有参数的函数的原型应该写成下面的样子:
int *func( void ); //关键字 void 提示没有任何参数,而不是表示它有一个类型为 void 的参数
函数的缺省认定
当函数调用一个无法见到原型的函数时,编译器便认为该函数返回一个整型值。
值的类型并不是值的内在本质,而是取决于它被使用的方式。
函数的参数
C函数的所有参数均以 “传值调用” 方式进行传递,这意味着函数将获得参数值的一份拷贝。
但是,如果传递的参数是一个 数组名 ,并且在函数中使用下标引用该数组的参数,则咋i函数中对数组元素进行修改实际上修改的是调用程序中的数组元素。—— “传址调用”
总结:
1、传递给函数的 标量参数 是 传值调用的。
2、传递给函数的 数组参数 在行为上就像它们是通过 传址 调用的那样。
递归
C通过运行时堆栈支持递归函数的实现。
递归函数 :就是直接或间接调用自身的函数。
当函数被调用时,它的变量的空间时创建于运行的堆栈上的。
以前调用的函数的变量仍然保留在堆栈上,但是它们被新函数的变量所覆盖,因此是不能被访问的。
/*
** 接受一个整型值(无符号),把它转换为字符并打印它,前导零被删除
*/
#include <stdio.h>
void binary_to_ascii( unsigned int value )
{
unsigned int quotient;
quotient = value / 10;
if( quotient != 0 )
bainary_to_ascii( quotient );
putchar( value % 10 + '0' );
}
//1、将函数除以10。
//2、如果quotient的值为非零,调用binary_to_ascii打印quotient当前值的给位数字。
//3、接着,打印步骤1中除法运算的余数。
阅读递归函数最容易的方法不是纠缠于它的执行过程,而是相信递归函数会顺利完成它的任务。
可变参数列表
stdarg宏
可变参数列表是通过宏来实现的,这些宏定义于 stdarg.h 头文件中,它是标准库的一部分。
此头文件声明一个类型 va_list 和三个宏—— va_start、va_arg、va_end 。我们可以声明一个类型为 va_list 的变量,与这几个宏配合使用,访问参数的值。
va_start :用于 初始化 ,他的第1个参数是va_list 变量的名字,第2个参数是省略号前最后一个有名字的参数。
va_arg :用于 访问参数 ,接受两个参数:va_list 变量 和 参数列表下一个参数的类型。
va_end :用于结束访问,只接受1个参数即 va_list 变量。
可变部分的参数只能从第1个到最后1个依次进行访问。
/*
** 计算指定数量的值的平均值
*/
#include <stdarg.h>
float average( int n_values, ... ) //n_values指其后输入值的数目
{
va_list var_arg; //用于访问参数列表韦确定的部分
int count;
float sum = 0;
/*准备访问可变参数*/
va_start( var_arg, n_values ); //把var_arg指向可变参数的第1个参数
/*添加取自可变参数列表的值*/
for( count = 0; count < n_values; count += 1 )
sum += va_arg( var_arg, int ); //返回当前可变参数的值
/*完成处理可变参数*/
va_end ( var_arg );
return sum / n_values;
}