第7章 函数
- 学习笔记
- 书后练习
- 问题1
- 问题7
- 问题8
- 编程练习1
- 编程练习3
学习笔记
可变参数列表是通过宏来实现的,这些宏定义于stdarg.h
头文件,他是标准库的一部分。这个头文件声明了一个类型va_list
和三个宏va_start
、va_arg
和va_end
。可以声明一个va_list
的变量,与这几个宏配合使用,访问参数的值。
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
float
average(int n_values, ...){
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;
}
int
main(int argc, char *argv[]){
float res = average(3, 1, 2, 3);
printf("%f\n", res);
return EXIT_SUCCESS;
}
函数声明了一个叫var_arg
的变量,它用于访问参数列表的未确定部分。这个变量通过调用va_start
来初始化,第一个参数是va_list
变量的名字,自二个参数是省略号前最后一个有名字的参数。初始化过程把var_arg
变量设置为指向可变参数部分的第一个参数。为了访问参数,需要使用va_arg
,这个宏接受两个参数:va_list
变量和参数列表中下一个参数的类型。最后,当访问完毕最后一个可变参数之后,需要调用va_end
。
书后练习
问题1
具有空函数体的函数可以作为存根使用。你如何对这类函数进行修改,使其更加有用?
回答:当存根函数被调用时,打印一条消息,显示它已被调用,或者也可以打印作为参数传递给它的值。
问题7
下面的函数有没有错误?如果有,错在哪里?
int
find_max( int array[10] )
{
int i;
int max = array[0];
for( i = 1; i < 10; i += 1 )
if( array[i] > max )
max = array[i];
return max;
}
回答:这个函数假定它被调用时传递给它的正好是10个元素的数组。如果参数数组更大一些,它就会忽略剩余的元素。如果传递一个不足10个元素的数组,函数将访问数组边界之外的值。
问题8
递归和while循环之间是如何相似的?
回答:递归和迭代都必须设置一些目标,当达到这些目标时便会终止执行。每个递归调用和循环的每次迭代都必须取得一些进展,进一步靠近这些目标。
编程练习1
Hermite Polynomials(厄密多项式)是这样定义的:
H
n
(
x
)
=
{
n
≤
0
:
1
n
=
1
:
2
x
n
≥
2
:
2
x
H
n
−
1
(
x
)
−
2
(
n
−
1
)
H
n
−
2
(
x
)
H_n(x)=\begin{cases} n \leq 0: 1\\ n = 1 : 2x \\ n \geq 2: 2xH_{n-1}(x)-2(n-1)H_{n-2}(x) \end{cases}
Hn(x)=⎩
⎨
⎧n≤0:1n=1:2xn≥2:2xHn−1(x)−2(n−1)Hn−2(x)
例如,
H
3
(
2
)
H_3(2)
H3(2)的值是40。请编写一个递归函数,计算
H
n
(
x
)
H_n(x)
Hn(x)的值。你的函数应该与下面的原型匹配:
int hermite( int n, int x )
#include<stdio.h>
#include<stdlib.h>
int hermite(int n, int x){
if(n <= 0){
return 1;
}
if(n == 1){
return 2 * x;
}
return 2 * x * hermite(n - 1, x) - 2 * (n - 1) * hermite(n - 2, x);
}
int main(int argc, char *argv[]){
int res = hermite(3, 2);
printf("%d\n", res);
return EXIT_SUCCESS;
}
编程练习3
为下面这个函数原型编写函数定义:
int ascii_to_integer( char *string );
这个字符串参数必须包含一个或多个数字,函数应该把这些数字字符转换为整数并返回这个整数。如果字符串参数包含了任何非数字字符,函数就返回零。请不必担心算术溢出。提示:这个技巧很简单——你每发现一个数字,把当前值乘以10,并把这个值和新数字所代表的值相加。
#include<stdio.h>
#include<stdlib.h>
int ascii_to_integer(char *string){
int res = 0;
while(*string >= '0' && *string <= '9'){
res = res * 10 + (*string - '0');
string++;
}
if(*string != '\0')
return 0;
return res;
}
int main(int argc, char *argv[]){
char str[] = "12345";
int res = ascii_to_integer(str);
printf("%d\n", res);
return EXIT_SUCCESS;
}