《C与指针》第七章练习
本章问题
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与指针》第七章练习的更多相关文章
- C和指针 第七章 习题
7.1 hermite递归函数 int hermite(int n, int x) { if (n <= 0) { return 1; } if (n == 1) { return 2 * x; ...
- C和指针 第七章 可变参数
可变参数列表是通过stdarg.h内的宏来实现的: 类型 va_list 三个宏: va_start va_arg va_end 我们可以声明一个va_list变量,与这三个宏配合使用. 可变参数必须 ...
- C和指针 第七章 函数递归与迭代
C语言通过运行时堆栈支持递归函数的实现,递归函数时直接或者间接调用自身的函数,经常有人拿斐波那契实现当做递归的实现,然后这样做效率并不高. n < 1; Fib(1) =1 n = 2; F ...
- C和指针第七章第五题
实现一个简化的printf函数,能够处理%d,%f,%s,%c等格式. /*************************************************************** ...
- C和指针 (pointers on C)——第七章:函数(上)
第七章 函数 这一章对于有一定C的基础的人有一定优秀代码风格的人来说,并非非常虐.关于stdarg宏可能有些陌生.它负责可变參数列表的定义. 总结: 新式风格和旧式风格就不要提了.八百年前的事情. 函 ...
- apue第七章学习总结
apue第七章学习总结 1.main函数 程序是如何执行有关的c程序的? C程序总是从main函数开始执行.main函数的原型是 int main(int argc,char *argv[]); 其中 ...
- Linux内核探讨-- 第七章
本文是个人分析<Linux内核设计与实现>而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/136 ...
- 第七章Bulk设备
小川工作室编写,本书为LM3S的USB芯片编写,上传的均为草稿,还有没修改,可能还有很多地方不足,希望各位网友原谅! QQ:2609828265 TEL:15882446438 E-mail:paul ...
- Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧
第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...
- [Python学习笔记][第七章Python文件操作]
2016/1/30学习内容 第七章 Python文件操作 文本文件 文本文件存储的是常规字符串,通常每行以换行符'\n'结尾. 二进制文件 二进制文件把对象内容以字节串(bytes)进行存储,无法用笔 ...
随机推荐
- Head First 设计模式 --3 装饰者模式 开闭原则
装饰者模式:动态的将责任附加到对象上,若要扩展功能,装饰者提供了比集成更有弹性的替代方案.设计原则:1:封装变化2:多用组合,少用继承3:针对接口编程,不针对实现编程4:为对象之间的松耦合设计而努力5 ...
- Security » Authorization » 基于声明的授权
Claims-Based Authorization¶ 基于声明的授权 142 of 162 people found this helpful When an identity is created ...
- laravel 加中间件的方法 防止直接打开后台
路由 routes.php Route::group(['middleware' => ['web','admin.login.login']], function () { //后台首页路由 ...
- 安装mongodb
安装mongodb的时候遇到一些麻烦 首先将安装包下下来 安装的是windows版本的 将bin文件夹加入环境变量后通过mongod和mongo指令就可以进行操作,很方便 用指令mongod --db ...
- Js获取后台集合List的值并操作html
功能:将后台传到前端JSP的List中的float型数值转换为百分比显示 HTML代码: <s:iterator value="colorConfigList" status ...
- ASP.NET MVC 4 RC的JS/CSS打包压缩功能 Scripts.Render和Styles.Render
打包(Bundling)及压缩(Minification)指的是将多个js文件或css文件打包成单一文件并压缩的做法,如此可减少浏览器需下载多个文件案才能完成网页显示的延迟感,同时通过移除JS/CSS ...
- HDU 1231:最大连续子序列 解题报告
第一次写博客, 自己总结写出了一道题感觉值得保存. 自己总结的规律:求最大连续子序列, 可以先求包括第N项在内的前N项最大值, (因为每一项都求过后, 前N项最大值最大的那一个元素所连续的序列即为最大 ...
- php数据库封装与引用方法
1.做封装类 <?php class DBDA { //成员变量 数据库的四个条件 public $host="localhost"; public $uid = " ...
- git push (第一次) (转)
原地址 http://blog.csdn.net/kazeik/article/details/9113891 下图是github在创建仓库后给的提示:按它一步步操作下去就可以了. 下图是在git命 ...
- UIView及其子类
一.UI概述 UI(User Interface):用户界⾯,用户能看到的各种各样的⻚面元素. iOS App = 各种各样的UI控件 + 业务逻辑和算法 二.UIView 在手机上显示的内容都是UI ...