3.1 ANSI C提供的getchar()函数与Turbo C提供的getche()函数有何不同?
答:最明显的区别在于:前后是带键盘缓冲区的,后者不是。因此,前者需等待键入回车符后才接收输入的一个字符,后者则当键入一个字符时立即接收该字符。
3.2输出结果是50%,为什么是执行语句
printf("%d%%\n",50)
而不是执行语句:
printf("%d\%\n",50);
答:因为反斜杠\是编译器的转义字符,而我们要解决的是printf的转义字符。
3.3执行语句
scanf("%d\n",&a);
为什么不是只需要输入一个数据而是两个才返回呢?
答:\n在scanf格式串中并不代表等待换行符,而是读取并放弃所有的空白字符。因此,当你输入一个数据后,如果回车,它读取并丢弃,等待你继续输入,直到遇到非空白字符。
3.4下列代码是否存在问题?
char ch;
while((ch = getchar())!= EOF)
…
答:必须用int型而不是char型变量保存getchar的返回值。因为该函数可能返回任何字符值(包括EOF),如果将该返回值截为char型,则非EOF字符可能被误为EOF,而EOF可能又被截为其它字符。
3.5你如何理解ANSI C将输入输出定义为“流”?
答:这是ANSI C对I/O概念的高度抽象。就C程序而言,所有的I/O操作只是简单地从程序移进或移出字符的事情。这些字节就像树叶落入溪流中,一个接一个排列着向前流动。因此,输出时,你只需要关心将数据放入“流”中,输入时,你关心的是正确解释读入的数据。
3.6 下列三个printf语句是否等价?
char *p = "Hello!";
printf("Hello!");
printf(p);
printf("%s",p);
答:等价。
3.7考察下面的程序段,你认为它可能存在什么问题?
char ch1 = ’A’,ch2 = ’B’;
scanf("%d",&ch1);
printf("ch1 = %c,ch2 = %c\n",ch1,ch2);
答:根据scanf格式串的要求,scanf需要一个指向整型的指针,但这里它实际得到的是一个字符(ch1)指针。问题在于scanf并不知道它没有得到它所需要的,于是它将&ch1看作是一个指向整型的指针并将一个整数存放在那里。设sizeof(char)==1,sizeof(int)==2,且设ch2占有ch1的右邻空间,于是无论你输入什么,都将覆盖掉ch2的空间,ch2的值被破坏了。
3.8在调用scanf或printf函数时,如果格式串中的格式符与对应的输入或输出项参数类型不匹配,编译器会指出其错误吗?后果如何?
答:编译器只检测参数的个数,至于参数的类型总假设是正确而不作检测,因此其后果是不可能预测的。
3.9当一个特定的值用格式符%.3f输出时,其结果为1.815,但若改用格式符%.2f输出时,结果为1.81。为什么?
答:%.3f格式输出的1.815中缀尾的5可能是四舍五入后得到的,它原来应为4,这样当用%.2f格式时,缀尾的4被舍弃。
3.10 a是一个整型变量,要实施正确输入,下面两个输入语句有什么不同?为什么?
scanf(" %d",&a);
scanf("%d",&a);
答:没有什么不同。因为输入数值数据时,scanf函数将自动忽略输入字符流中的前导空白类字符,所以在输入时,输入空格与否,其效果一样。见思考题3.3。
3.11 用一个scanf()调用实现:输入一个字符串,字符串由字母字符和空格字符组成,若遇其它任何字符,结束输入。
答:下面是该问题的一种解决方案:
scanf("%[a-zA-Z ]",ptr); /* ptr的类型是char* */
3.12 用一个scanf()调用实现:输入任意一个字符串,遇换行符结束输入。
答:下面是该问题的一种解决方案:
scanf("%[^\n]",ptr); /* ptr的类型是char* */
3.13 若有整型变量i = 11,j = 22,k = 23,u = 47215;实型变量x = 2.2,y = 3.4;字符型变量c1 = ’a’,c2 = ’b’。试按以下输出格式用函数printf()组织输出。
i = 11,j = 12,k = 33
u = 47215
x = 2.20000,y = 3.40000
x + y = 5.60
c1 = ’a’ or 97(ASCII) c2 = ’b’ or 98(ASCII)
答:下面各行语句分别实现上面对应行的输出:
printf("i = %d,j = %d,k = %d\n",i,j,k);
printf("u = %u\n",u);
printf("x = %7.5f,y = %7.5f\n",x,y);
printf("x + y = %4.2f\n",x+y);
printf("c1 = ’%c’ or 97(ASCII) c2 = ’%c’ or 98(ASCII)\n",c1,c2);
3.14 写出以下程序的输出结果。
#include<stdio.h>
int main()
{
int a = 8,b = 9;
float x = 127.895,y = -123.456;
char c = ’B’;
long n = 12345678L;
unsigned u = 65535u;
printf("%d,%d\n",a,b);
printf("%5d,%5d\n",a,b);
printf("%f,%f\n",x,y);
printf("%-12f,%-12f\n",x,y);
printf("%8.3f,%8.3f,%.3f,%.3f,%4f,%5f\n",x,y,x,y,x,y);
printf("%e,%10.4e\n",x,y);
printf("%c,%d,%o,%x\n",c,c,c,c);
printf("%ld,%lo,%lx\n",n,n,n);
printf("%u,%o,%x,%d\n",u,u,u,u);
printf("%s,%6.3s,%-10.5s\n","C","C++","JAVA");
}
答:本题读者可上机验证。
答:最明显的区别在于:前后是带键盘缓冲区的,后者不是。因此,前者需等待键入回车符后才接收输入的一个字符,后者则当键入一个字符时立即接收该字符。
3.2输出结果是50%,为什么是执行语句
printf("%d%%\n",50)
而不是执行语句:
printf("%d\%\n",50);
答:因为反斜杠\是编译器的转义字符,而我们要解决的是printf的转义字符。
3.3执行语句
scanf("%d\n",&a);
为什么不是只需要输入一个数据而是两个才返回呢?
答:\n在scanf格式串中并不代表等待换行符,而是读取并放弃所有的空白字符。因此,当你输入一个数据后,如果回车,它读取并丢弃,等待你继续输入,直到遇到非空白字符。
3.4下列代码是否存在问题?
char ch;
while((ch = getchar())!= EOF)
…
答:必须用int型而不是char型变量保存getchar的返回值。因为该函数可能返回任何字符值(包括EOF),如果将该返回值截为char型,则非EOF字符可能被误为EOF,而EOF可能又被截为其它字符。
3.5你如何理解ANSI C将输入输出定义为“流”?
答:这是ANSI C对I/O概念的高度抽象。就C程序而言,所有的I/O操作只是简单地从程序移进或移出字符的事情。这些字节就像树叶落入溪流中,一个接一个排列着向前流动。因此,输出时,你只需要关心将数据放入“流”中,输入时,你关心的是正确解释读入的数据。
3.6 下列三个printf语句是否等价?
char *p = "Hello!";
printf("Hello!");
printf(p);
printf("%s",p);
答:等价。
3.7考察下面的程序段,你认为它可能存在什么问题?
char ch1 = ’A’,ch2 = ’B’;
scanf("%d",&ch1);
printf("ch1 = %c,ch2 = %c\n",ch1,ch2);
答:根据scanf格式串的要求,scanf需要一个指向整型的指针,但这里它实际得到的是一个字符(ch1)指针。问题在于scanf并不知道它没有得到它所需要的,于是它将&ch1看作是一个指向整型的指针并将一个整数存放在那里。设sizeof(char)==1,sizeof(int)==2,且设ch2占有ch1的右邻空间,于是无论你输入什么,都将覆盖掉ch2的空间,ch2的值被破坏了。
3.8在调用scanf或printf函数时,如果格式串中的格式符与对应的输入或输出项参数类型不匹配,编译器会指出其错误吗?后果如何?
答:编译器只检测参数的个数,至于参数的类型总假设是正确而不作检测,因此其后果是不可能预测的。
3.9当一个特定的值用格式符%.3f输出时,其结果为1.815,但若改用格式符%.2f输出时,结果为1.81。为什么?
答:%.3f格式输出的1.815中缀尾的5可能是四舍五入后得到的,它原来应为4,这样当用%.2f格式时,缀尾的4被舍弃。
3.10 a是一个整型变量,要实施正确输入,下面两个输入语句有什么不同?为什么?
scanf(" %d",&a);
scanf("%d",&a);
答:没有什么不同。因为输入数值数据时,scanf函数将自动忽略输入字符流中的前导空白类字符,所以在输入时,输入空格与否,其效果一样。见思考题3.3。
3.11 用一个scanf()调用实现:输入一个字符串,字符串由字母字符和空格字符组成,若遇其它任何字符,结束输入。
答:下面是该问题的一种解决方案:
scanf("%[a-zA-Z ]",ptr); /* ptr的类型是char* */
3.12 用一个scanf()调用实现:输入任意一个字符串,遇换行符结束输入。
答:下面是该问题的一种解决方案:
scanf("%[^\n]",ptr); /* ptr的类型是char* */
3.13 若有整型变量i = 11,j = 22,k = 23,u = 47215;实型变量x = 2.2,y = 3.4;字符型变量c1 = ’a’,c2 = ’b’。试按以下输出格式用函数printf()组织输出。
i = 11,j = 12,k = 33
u = 47215
x = 2.20000,y = 3.40000
x + y = 5.60
c1 = ’a’ or 97(ASCII) c2 = ’b’ or 98(ASCII)
答:下面各行语句分别实现上面对应行的输出:
printf("i = %d,j = %d,k = %d\n",i,j,k);
printf("u = %u\n",u);
printf("x = %7.5f,y = %7.5f\n",x,y);
printf("x + y = %4.2f\n",x+y);
printf("c1 = ’%c’ or 97(ASCII) c2 = ’%c’ or 98(ASCII)\n",c1,c2);
3.14 写出以下程序的输出结果。
#include<stdio.h>
int main()
{
int a = 8,b = 9;
float x = 127.895,y = -123.456;
char c = ’B’;
long n = 12345678L;
unsigned u = 65535u;
printf("%d,%d\n",a,b);
printf("%5d,%5d\n",a,b);
printf("%f,%f\n",x,y);
printf("%-12f,%-12f\n",x,y);
printf("%8.3f,%8.3f,%.3f,%.3f,%4f,%5f\n",x,y,x,y,x,y);
printf("%e,%10.4e\n",x,y);
printf("%c,%d,%o,%x\n",c,c,c,c);
printf("%ld,%lo,%lx\n",n,n,n);
printf("%u,%o,%x,%d\n",u,u,u,u);
printf("%s,%6.3s,%-10.5s\n","C","C++","JAVA");
}
答:本题读者可上机验证。