《C与指针》第二章练习

时间:2021-12-22 12:15:14

本章问题

1.Comments in C do not nest(嵌套).What would be the result of "commenting out" the code in the example shown below?

(注释在C里面不能嵌套,下面“commenting out”注释的代码会产生什么结果?)

void
squares( int limit )
{
/* Comment out this entire function
int i; /*loop counter*/ /*
** Print table of squares
*/
for( i = ; i < limit; i += )
printf("%d %d0, i, i * i“);
End of commented-out code*/
}

answer : The outside(外侧的) comment ends at the end of the first enclosed(围绕的) comment. This make the variable i undefined in the rest of the function; the phrase End of comment-out code will be a syntax(句法) error,and the final closing */ will be illegal(非法的).

(外侧和围绕第一行的代码会使剩余函数没有定义i变量,最后一行”end of commented-out code将会出现句法错误,最后一个*/是非法的“)

2.What are the advantages of putting a large program into a single source file?What are the disadvantages?

(把一个大程序放在一个源文件中有什么优点?有什么缺点?)

answer :

Advantages:

a.When you want to modify a funcion,it is easy to determine(确定) which file it is in.

(当你要修改一个函数时,很容易确定它在文件的哪个文件)

b.You can safely user longer function names.Depending on the limits of your particular system,internal(内部) must be distinct from one another somewhere in the first 31 characters or more,whereas external names must be distinct from one another in the first six characters.

(你可以安全的使用长的函数名,取决于你的系统限制,前31个字符的内部名字必须不同,前六个字符的外部名字必须不同)

Disadvantages:

a.Depending on how powerful your editor is,it may be harder to locate(找出) a particular piece of code in large file than a small one.

(取决于你的编辑器,相比于一个小文件来说可能更难找出一个特殊的代码段)

b.Depending on your operating system,the type of editor you are using,and the size of the file,it may be more time consuming(消耗) to edit a large file than a small one.

(取决于你的操作系统和你所使用的编辑器的类型和文件的大小,相比于一个小文件可能需要花费更多的时间)

c.If you make a mistake in your editor,it is easy to lose the whole program.

(如果你在编辑器里犯了一个错误,可能更容易导致整个程序丢失)

d.Even if you change only one function,the entire program must be recompiled,which takes longer than recompiling only the modified function.

(即使你只是更改一个函数,整个程序都需要重新编译,这比只需要编译一个函数的时间要长)

e.It is harder to reuse general purpose functions from the program if they are buried in(埋在) with all the code that is specific(特别的) to that problem.

(会使得重用一个解决特殊问题的函数更难,因为这个函数跟所有的代码放在一起)

3.Show the string literal(逐字) that you would use with printf in order to print the following text,including the quotation(引用) marks.

(使用printf逐字打印出下列文本,包括双引号)

”Blunder??!??“

answer :

printf("\"Blunder\?\?!??\"");

4.What is the value of \40? of \100? of \x40? of \x100? of \0123? of \x0123?

(\40的值是多少?、\100 、\x40、\x100、\0123、\x0123的值分别是多少?)

answer : The character equivalences(相等) given assume that the implementation(实行) users ASCII.

(假定用户实行的是ASCII码,则给定字符与ASCII码对应相等)

\40  (Oct)     =        32(Dec)        =       the space character(空格)

\100  (Oct)  =        64(Dec)        =       '@'

\x40   (Hex)  =        64(Dec)        =       '@'

\x100   (Hex)is twelve bits (thouge the first three are zeros). On most machines this number is too big to be stored in a character , so the result is implementation dependent.

(\x100 占据十二位,尽管前三位为0,在绝大多数机器上,这个值过大,无法存储在一个字符内,所以它的结果要依赖于编译器)

\0123  (Oct)consists of two characters :'\012' and '3',The resulting value is implementation dependent.

(\0123由‘\012’ 和'3'两个字符串组成,它的结果依赖于编译器)

\x0123 (Hex)is too big to fit into a character, The resulting value is implementation dependent.

(\x0123的值对于一个字符来说太大了,它的结果依赖于编译器)

5.What is the result of this statement?

int x/*blah blah*/y;

answer : The preprocessor replaces the comment with a single space,which makes the resulting statement illegal.

(预编译器将会用一个空格取代注释,这将会使这个语句非法)

6.What (if anything) is wrong with the following declaration?

(下面这个声明有哪些错误?)

int Case,If,While,Stop,stop;

answer : Nothing,There are no confilcts with the C keywords or between the last two identifiers(标识符) because they are all differ in the case of their characters.

(没有错误,它们不与C中的关键字相同,并且最后两个标识符它们的字符不同)

对于内部名而言,至少前31个字符是有效的。函数名与外部变量名包含的字符数目可能小于31,这是因为汇编程序和加载程序可能会使用这些外部名,而语言本身是无法控制加载和汇编程序的。对于外部名,ANSI标准仅保证前6个字符的唯一性,并且不区分大小写。

A N S I标准规定,标识符可以为任意长度,但外部名必须至少能由前6个字符唯一地区分,并且不区分大小写。外部名指的是在链接过程中所涉及的标识符,其中包括文件间共享的函数名和全局变量名。

A N S I标准还规定内部名必须至少能由前31个字符唯一地区分。内部名指的是仅出现于定义该标识符的文件中的那些标识符。

转自:http://blog.163.com/magicblue_1_126@126/blog/static/3694974620116695738605/

7.True or False: Because C (excluding(不包括) the preprocessor directives(命令)) is a free-form language,the only rules that govern(支配) how programs are written are the syntax rules,so it doesn't matter how the program actually looks.

(对或不对:因为C是一门*形式的语言,唯一规定如何编程的规则是语法规则,所以程序实际看起来如何是不重要的)

answer : Both.

True: The language doesn't impose any rules regarding what a program ought to look like,except for preprocessor directives.

False: Programs written without style are difficult or impossible to maintain,so how the program looks is extremely important for all but the most trivial(琐碎的) of programs.

(有对的也有不对的,对的部分是语言不会强加任何规则说程序看起来应该怎么样,除了预编译器命令;不对的地方是没有规则的程序很难或几乎不可能维护,所以程序的风格及其重要除了及其简单的程序)

8.Is the loop in the following program correct?(下面这个程序的循环正确吗)

#include <stdio.h>

int
main(void)
{
int x, y;
x = ;
while(x < ){
y = x * x;
printf("%d\t%d",x, y);
x += ;
}

Is the loop in this program correct?(这个程序呢?)

#include <stdio.h>

int
main(void)
{
int x, y;
x = ;
while(x < ){
y = x * x;
printf("%d\t%d",x, y);
x += ;
}

Which program was easier to check?(哪一个程序更容易检查出来)

answer : Both programs are missing the closing brace to the while loop,however,it is easier to see in the second program than in the first,This example illustrates(表明) the value of indenting(缩写空白) the statements in a function.

(两个程序的while循环都缺了右括号边界,然而,第二个程序比第一个程序更容易看出来,这个例子说明在函数里面对语句使用缩写更有益)

9.Suppose you have a C program whose main function is in the file main.c and has other functions in the files list.c and report.c.What command(s) would you use on your system to compile and link this program?

(假设你有一个c程序,它的main函数在main.c文件中,并且还有其他函数在list.c和report.c文件中,在你的系统上应该用什么命令在编译和链接这个程序呢?)

answer :

gcc main.c list.c report.c

10.How would you modify the command for the previous qustion in order to link a library called parse with the program?

(在前一个问题中,如果你要给这个程序链接一个叫做parse的函数库,你将如何修改命令?)

answer :

gcc main.c list.c report.c -lparse

11.Suppose you have a C program composed of several separate files,and they include one another as shown below.Which files would have to be recompiled after you make a change to list.c?To list.h?To table.h?

(假定你有一个C程序由若干分开的文件组成,它们的包含关系如下表,在你对list.c文件做了一些更改后,哪些文件需要被重新编译,如果是list.h、table.h呢)

File Include Files
main.c stdio.h table.h
list.c list.h
symbol.c symbol.h
table.c table.h
table.h symbol.h list.h

answer : When a header is changed,every file that includes it must be recompiled.

(当一个头文件被更改时,所有包括这个源文件的文件全部要重新编译)

If This File Is Changed These Must Be Recompiled
list.c list.c
list.h list.c table.c main.c
table.h table.c main.c

The Borland C/C++ compiler's Windows Integrated Development Environment looks for these relationships among the files and automatically compiles only those that are needed,UNIX systems have a tool called make that performs the same job,thouge with this tool you must construct a makefile that describes the relationships among the files.

(windows下的Borland C/C++编译器会自动的编译需要的文件,同样在UNIX下也有一个相似的工具叫做make,这个工具要求你建立一个makefile文件来描述所有文件的关系)

本章练习

1.Write a program with three function in three separate source files,The function increment should take a single integer argument and return the value of that argument plus one,This function should be in the file increment.c. The second function is called negate.It also takes a single integer argument and return the vegated value of that argument(for example,If the argument is 25,the function should return -25;if the argument is -612,the function return 612). The final function is main, in the file main.c and it should call each of the other function with the values 10, 0,and -10, and print the results.

(写一个程序,包含三个函数分别位于不同的文件中,第一个函数increment接受一个整型参数并且返回这个参数加一后的值,这个函数位于文件increment.c中。第二个函数叫做negate,同样接受一个整型参数并且返回它的相反数,最后一个函数是main函数,需要调用其他两个函数并且用10,0,-10的值测试并打印出来)

answer :

//main.c
#include <stdio.h>
#include "increment.h"
#include "negate.h" int main(void)
{
printf("%d: increment:%d, negate:%d\n",,increment(),negate());
printf("%d: increment:%d, negate:%d\n",,increment(),negate());
printf("%d: increment:%d, negate:%d\n",-,increment(-),negate(-));
}
//increment.h
#ifndef _INCREMENT_H_
#define _INCREMENT_H_ int increment(int x);
#endif //increment.c
#include "increment.h"
int increment(int x)
{
return x+;
}
//negate.h
#ifndef _NEGATE_H_
#define _NEGATE_H_ int negate(int x);
#endif //negate.c
#include "negate.h" int negate(int x)
{
return -x;
}
gcc main.c increment.c increment.h negate.c negate.h
./a.out 

2.Write a program that will read C source code from the standard input and ensure that the braces are paired(配对) correctly.

note: you need not worry about braces that appear within comments,string literals,or character constants.

(写一个程序从标准输入中读取c源程序并且确定花括号是否正确的配对,提示:你不用担心括号出现在注释中,字符串中或者字符常量中)

/*这个题目很有意思,当你看完这个题目后,可能会像我一样笑一笑然后快速在你的编辑器里写出如下代码*/

#include <stdio.h>

int main(void)
{
int ch;
int left = ;
int right = ; while( (ch = getchar()) != EOF){
if( ch == '{')
left++;
if( ch == '}')
right++;
}
if(left > right)
printf("the left brace more than right brace!\n");
else if(left < right)
printf("the left brace less than right brace!\n");
else
printf("paired ok!"); return ;
} 然后随便输入输入就完事了,然而作者在答案里说了一句话:
The program is easy to implement with a counter,However,it is not as trivial as it first seems,
Try testing your solution with this input:}{
(这个程序看起来用一个计数器就能完成,然而它并不像第一眼看上去那么简单,用‘}{’测试你的代码)
好像作者一下子就能猜到这本书的读者会像我一样用上面的代码快速完成这个题目,并且不会考虑左括号和右括号出现的次序而只考虑出现的次数,所以,回去继续完成它吧...
#include <stdio.h>

int main(void)
{
int ch;
int count = ; while( (ch = getchar()) != EOF){
if( ch == '{')
count++;
if( ch == '}'){
count--;
if(count < )
break;
}
} if(count < )
printf("the right brace appears before the left brace or right brace more than left brace!\n");
if(count > )
printf("the left brace more than brace\n");
if(count == )
printf("paired ok!\n"); return ;
}