本章问题

1.具有空函数体的函数可以作为存根使用,你如何对这类函数进行修改,使其更有用?

answer:Have the stub(存根) print out a message when it is called,perhaps printing the values it was given as arguments.

(存根可以在它被调用的时候打印出相应的信息,可能打印出参数的值)

2.在ANSI C中,函数的原型非必需,请问这个规定是优点还是缺点?

answer:An advantage is that it allows you to be lazy;there is less code to write.The other consequences,such as being able to call functions with the wrong numbers or types of arguments,are all disadvantages.

(一个优点是它允许你偷懒,可以写更少的代码,其他后果比如调用函数时使用错误的数字或参数类型都是缺点)

3.如果在一个函数的声明中它的返回类型为A,但它的函数体内有一条return语句,返回了一个类型为B的表达式,请问,这将导致什么后果?

answer:The value is converted to the type specified by the function,The Standard indicates that this is done the same as if the value had been assigned to a variable of that type.

(这个值将会被函数转换成指定的类型A,标准显示将会把该值指定为返回类型的变量)

4.如果一个函数声明的返回类型为void,但它的函数体中包含一条return语句,返回了一个表达式,请问,这将导致什么后果?

answer:This is not allowed;the compiler should give an error message.

(编译器不会允许编译通过而将会给出一条错误信息)

5.如果一个函数被调用之前,编译器无法看到它的原型,那么当这个函数返回一个不是整型的值时,会发生什么情况?

answer:The value returned is interpreted as if it were an interger.

(这个值将会被理解为整型)

6.如果一个函数被调用之前,编译器无法看到它的原型,如果当这个函数被调用时,实际传递给它的参数与它的形参类型不匹配,会发生什么情况?

answer:The argument values are interpreted as the types of the formal paramenters,not their real types.

(参数的值将会被理解为形参的类型而不是它们实际的类型)

7.下面的函数有没有错误,如果有,错在哪里?

int
find_max(int array[])
{
int i;
int max = array[];
for(i = ; i < ; i += ){
if(array[i] > max)
max = array[i];
}
return max;
}

answer:The function assumes that it will be called with an array of exactly ten elements.If called with a larger array.it ignores the remaining elements,if called with a shorter array ,it accesses values outside of the array.

(这个函数假定被调用的时候数组有十个元素,当被一个更大的数组调用是,将忽略一些元素,当被一个更小的数组调用时,将访问数组之外的元素)

8.递归和while循环之间为什么相似?

answer:There must be some goal at which the recursion(递归) or the iteration(迭代) stops.and each recursive call and each iteration of the loop must make some progress toward this goal.

(它们必须有一些目标使递归和迭代停止运行,每个递归和迭代产生一些过程来接近目标)

9.请解释把函数原型单独放在#include文件中的优点

answer:

a. It is easier to use a #include in several source files than to copy the prototype.

(使用include包含与许多源文件中比福祉原型更容易)

b. There is only one copy of the prototype itself.

(只有一份原型的拷贝)

c. #includeing the prototype in the file that defines the function ensures that they match.

(包括原型在文件中,在定义函数时确保它们匹配)

10.在你的系统中,进入递归形式的菲波那契函数,并在函数的起始出增加一条语句,它增加一个全局整型变量的值。现在编写一个main函数,把这个全局变量设置为0并计算Fibonacci(1).重复这个过程,计算FIbonacci(2)至Fibonacci(10)。在在每个计算过程中分别调用了几次Fibonacci函数?这个全局变量值的增加和菲波那契数列本身有没有任何关联?基于上面这些信息,你能不能计算出Fibonacci(11)、Fibonacci(25)、Fibonacci(50)分别调用了多少次Fibonacci函数?

answer:

//参考程序,不含有检错操作
#include <stdio.h> int Fibonacci(int n);
static int count; int main()
{
count = ;
int x;
printf("please input the x:\n");
scanf("%d",&x);
Fibonacci(x);
printf("the count is %d",count);
return ;
} int Fibonacci(int n)
{
count++;
if(n == )
return ;
else if(n == )
return ;
else
return Fibonacci(n - ) + Fibonacci(n - );
}

The progression is indeed related to the Fibonacci numbers:each count is the sum of the two preceding counts plus one.Here are the values requested.plus some additional counts to show how bad the recursive function really is.

(这个过程确实跟fibonacci数字有关系,每一个计数加一是前两项的总和,下面是测试的结果,count显示使用递归计算fibonacci数列有多糟糕)

Fibonacci(n) Number of Calls
1 1
2 1
3 3
4 5
5 9
6 15
7 25
8 41
9 67
10 109
11 177
15 1219
20 13529
25 150049
30 1664079
40 204668309
50 25172538049
75 4222970155956099
100 708449696358523830149

本章练习

1.Hermite Polynominal(厄米多项式)是这样定义的

  n ≤ 0 :   1

Hn(x) =     n = 1 :  2x

      n ≥ 2 :  2xHn-1(x) - 2(n - 1) Hn-2(x)

例如,H3(2)的值是40,请编写一个递归函数,计算Hn(x)的值,你的函数应该与下面的原型匹配:

int hermite( int n, int x)

answer:

#include <stdio.h>

int hermite(int n, int x);

int main(void)
{
int n;
int x;
printf("please input n and x:\n");
scanf("%d%d",&n,&x);
printf("the Hn(x) is: %d",hermite(n,x));
} int hermite(int n, int x)
{
if(n <= )
return ;
else if(n == )
return * x;
else
return * x * hermite(n - ,x) - * (n - ) * hermite(n - ,x);
}

2.两个整型值M和N(M、N均大于0)的最大公约数可以按照下面的方法计算:

       M % N = 0  :   N

gcd(M,N)   =

       M % N = R, R > 0 :     gcd(N,R)

answer:

//迭代法
int gcd(int m, int n)
{
int r;
if(m <= || n <= )
return ;
do{
r = m % n;
m = n;
n = r;
}while(r > ); return m;
} //递归法
int gcd(int m, int n)
{
int r;
if(m <= || n <= )
return ;
r = m % n;
if(r == )
return n;
else if(r > )
return gcd(n,r);
}

3.为下面这个函数原型编写函数定义:

int ascii_to_integer(char *string);

这个字符串参数必须包含一个或多个数字,函数应该把这些数字字符转换为整数并返回这个整数,如果字符串参数包含了任何非数字字符,函数就返回零。请不必担心算数溢出。提示:这个技巧很简单,你每发现一个数字,把当前值乘以10,并把这个值和新数字所代表的值相加。

answer:

int ascii_to_integer(char *string)
{
int result = ;
char *p = string;
while(*p >= '' && *p <= ''){
result *= ;
result += *p - '';
p++;
} if(*p != '\0')
result = ;
return result;
}

4.编写一个名叫max_list的函数,它用于检查任意数目的整型参数并返回它们中最大值。参数列表必须以一个负数结尾,提示列表结束。

answer:

int max_list(int x,...){
int max = x;
va_list var_list;
va_start(var_list,x);
do{
int temp = va_arg(var_list,int);
if(temp > max)
max = temp;
}while(temp > );
   va_end(var_list);
return max;
}

5.实现一个简化的printf函数,它能够处理%d,%f,%s和%c格式码,根据ANSI标准的原则,其他格式码的行为是未定义的,你可以假定已经存在函数print_integer和print_float,用于打印这些类型的值,对于另外两种类型的值,使用putchar来打印。

answer:

void myprintf(char *string,...)
{
char *p = string;
va_list var_list;
va_start(var_list,string); while(*p != '\0'){
if(*p == '%'){
switch(*++p){
case 'd':
print_integer(va_arg(var_list,int));
break;
case 'f':
print_float(va_arg(var_list,float));
break;
case 'c':
putchar(va_arg(var_list,int));
case 's':
char *q = va_arg(var_list,char *);
while(*q != '\0')
putchar(*q++);
break;
default:
break;
}
}else{
putchar(*p);
}
p++;
}
va_end(var_list);
}

6.编写函数:

void written_amount(unsigned int amount,char *buffer);
它把amount表示的值转化为单词形式,并存储于buffer中,这个函数可以在一个打印支票的程序中使用。例如,如果amount的值是16312,那么buffer中存储的字符串应该是:SIXTEEN THOUSAND THREE HUNDRED TWELVE

调用程序应该保证buffer缓冲区的空间足够大。

有些值可以用两种不同的方法进行打印。例如,1200可以是ONE THOUSAND TWO HUNDRED或TWELVE HUNDRED。你可以选择一种你喜欢的形式。

answer:

#include <stdio.h>
#include <string.h> #define LONG 1000 char *unit[] = {" zero"," one"," two"," three",
" four"," five"," six"," seven",
" eight"," nine"}; char *ten[] = {" ten"," eleven"," twelve",
" thirteen"," fourteen"," fifteen",
" sixteen"," seventeen"," eighteen",
" nineteen"}; char *decade[] = {" "," "," twenty"," thirty",
" forty"," fifty"," sixty",
" seventy"," eighty"," ninety"}; void written_amount(unsigned long int amount,char *buffer); int main()
{
unsigned long int amount;
char buffer[LONG] = "";
scanf("%lu",&amount);
written_amount(amount,buffer);
printf("%s",buffer);
return ;
} void written_amount(unsigned long int amount,char *buffer)
{
unsigned long int n = ;
if(amount / n != ){
int temp = amount / n;
amount %= n;
written_amount(temp,buffer);
strcat(buffer," billion");
} n = ;
if(amount / n != ){
int temp = amount / n;
amount %= n;
written_amount(temp,buffer);
strcat(buffer," million");
} n = ;
if(amount / n != ){
int temp = amount / n;
amount %= n;
written_amount(temp,buffer);
strcat(buffer," hundred");
} n = ;
if(amount / n != ){
int temp = amount / n;
amount %= n;
if(temp == ){
strcat(buffer,ten[amount]);
}else{
strcat(buffer,decade[temp]);
if(amount != )
strcat(buffer,unit[amount]);
}
}else{
strcat(buffer,unit[amount]);
}
}

《C与指针》第七章练习的更多相关文章

  1. C和指针 第七章 习题

    7.1 hermite递归函数 int hermite(int n, int x) { if (n <= 0) { return 1; } if (n == 1) { return 2 * x; ...

  2. C和指针 第七章 可变参数

    可变参数列表是通过stdarg.h内的宏来实现的: 类型 va_list 三个宏: va_start va_arg va_end 我们可以声明一个va_list变量,与这三个宏配合使用. 可变参数必须 ...

  3. C和指针 第七章 函数递归与迭代

    C语言通过运行时堆栈支持递归函数的实现,递归函数时直接或者间接调用自身的函数,经常有人拿斐波那契实现当做递归的实现,然后这样做效率并不高. n < 1;  Fib(1) =1 n = 2;  F ...

  4. C和指针第七章第五题

    实现一个简化的printf函数,能够处理%d,%f,%s,%c等格式. /*************************************************************** ...

  5. C和指针 (pointers on C)——第七章:函数(上)

    第七章 函数 这一章对于有一定C的基础的人有一定优秀代码风格的人来说,并非非常虐.关于stdarg宏可能有些陌生.它负责可变參数列表的定义. 总结: 新式风格和旧式风格就不要提了.八百年前的事情. 函 ...

  6. apue第七章学习总结

    apue第七章学习总结 1.main函数 程序是如何执行有关的c程序的? C程序总是从main函数开始执行.main函数的原型是 int main(int argc,char *argv[]); 其中 ...

  7. Linux内核探讨-- 第七章

    本文是个人分析<Linux内核设计与实现>而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/136 ...

  8. 第七章Bulk设备

    小川工作室编写,本书为LM3S的USB芯片编写,上传的均为草稿,还有没修改,可能还有很多地方不足,希望各位网友原谅! QQ:2609828265 TEL:15882446438 E-mail:paul ...

  9. Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧

    第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...

  10. [Python学习笔记][第七章Python文件操作]

    2016/1/30学习内容 第七章 Python文件操作 文本文件 文本文件存储的是常规字符串,通常每行以换行符'\n'结尾. 二进制文件 二进制文件把对象内容以字节串(bytes)进行存储,无法用笔 ...

随机推荐

  1. css模块化策略

    为什么要模块化? 分治和复用 封装,不污染全局,不被全局污染. 继承 BEM(block:块,Element:元素,Modifier:修饰符)策略 .block__Element--Modifier ...

  2. 02-编写第一个C语言程序

    本文目录 1.打开Xcode,新建Xcode项目 2.选择最简单的命令行项目 3.输入项目信息 4.选择一个用来存放C程序代码的文件夹 5.运行项目 说明:这个C语言专题,是学习iOS开发的前奏.也为 ...

  3. sqlalchemy 优化count()……

    一.sqlalchemy 中的count() count()统计数据特别慢: session.query(cls).count()  8W 数据花费了近50s 但是在数据库中直接查询: select ...

  4. 学习mongo系列(八)密码与权限

    一.设置密码及用户角色[1] > db.createUser(... {... user: "maxh",... pwd: "123",... roles ...

  5. Python_Day1_基础1

    一. Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为AB ...

  6. dev uploadcontrol 上传图片

    <script type="text/javascript"> // <![CDATA[ function Uploader_OnUploadStart() { ...

  7. Linux Socket编程(不限Linux)

    "一切皆Socket!" 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信 ...

  8. Python学习笔记----序列共性

    序列操作符 作用seq[ind] 获得下标为ind 的元素seq[ind1:ind2] 获得下标从ind1 到ind2 间的元素集合seq * expr 序列重复expr 次seq1 + seq2 连 ...

  9. DbUtils常用API的使用 方便以后查阅

    package com.lizhou.Test; import java.sql.SQLException; import java.util.List; import java.util.Map; ...

  10. Octopus系列之各个页面调用示例

    调用首页产品 可选参数如下 New = 1, Hot = 2, Best = 3, Special = 4, Featured = 5, Other = 6 #foreach($item in $oc ...