《C和指针》第一章课后

此博客作为本人读书记录,写下书本后面的课后习题,也欢迎大家交流

第一章课后问题

1.C是一种自由形式的语言,也就是说并没有规则规定它的外观究竟应该怎样。但本章的例子程序遵循了一定的空白使用规则。你对此有何想法?

C是一种自由形式的语言,也就是说并没有规则规定什么地方可以书写语句,一行中可以出现多少语句,什么地方应该留下空白以及应该出现多少空白等(预处理指令是个例外)。唯一的规则就是相邻的标记之间必须出现一至多个空白字符(或注释),不然它们可能被解释为单个标记,因此,下列语句是等价的。

y=x+1;
y = x + 1;
y = x
+
1;

至于下面这组语句,前三条是等价的,但是第四条语句却是非法的;

int
x;
int     x;
int/*comment*/x;
intx;

这种代码书写的极度自由有利有弊。很快你就就将听到一些关于这个话题的肥皂盒哲学。

肥皂盒哲学:有一家日本最大的化妆品公司,收到了用户的投诉.用户抱怨买来的肥皂盒是空的。这家公司为了防止再发生这样的事故,很辛苦地发明了一台X光检查器,能够透视每一个出货的肥皂盒。同样的事故,发生在一家小公司。他们的解决方法是买一台强力的工业电扇,对着肥皂盒猛吹,被吹走的就是空肥皂盒。其实也就是简单原则,keep it simple,stupid.


2.把声明(如函数原型的声明)放在头文件中,并在需要时用#include指令把它们包含与源文件中,这样做法有什么好处?

如果你有一些声明需要用于几个不同的源文件,你可以在头文件中编写这些声明,然后用#include指令把这个文件包含到需要使用这些声明的源文件中,这样,你就只需要这些声明的一份拷贝,用不着在许多不同的地方进行复制,避免了在维护这些代码时出现错误的可能性,也有利于代码的清晰度与复用率。


3.使用#define指令给字面值常量取名有什么好处?

用#define把名字MAX_COLS定义为20,当这个名字以后出现在源文件的任何地方时,它会被替换为定义的值。由于它们被定义为字面值常量,所以这些名字不能出现在于有些普通变量可以出现的地方(比如赋值符的左边)。这些名字一般都大写,用于提醒它们并非普通的变量。#define指令和其他语言中符号常量的作用类似,其出发点也想通,如果以后你觉得20列不够,你可以简单的修改MAX_COLS的定义,这样你就用不着在正哥程序中到处寻找兵修改所有表示列范围的20,你有可能漏掉一个,也可能把并非用于表示列范围的20也修改了。


4.依次打印一个十进制整数、字符串和浮点值,你应该在printf函数中分别使用什么格式代码?试编一例,让这些打印值以空格分隔,并在输出行的末尾添加一个换行符。

十进制整数使用 %d , 字符串使用 %s ,浮点值使用 %f 。

    int number = 10;
    char c_char[] = "abc";
    float f_float = 1.126;
    printf("%d %s %f\n", number,c_char,f_float);

5.编写一条scanf语句,它需要读取两个整数,分别保存于quantity和price变量,然后再读取一个字符串,保存在一个名叫department的字符数组中。

    int quantity, price;
    char department[100];
    scanf("%d %d %s", &quantity, &price, &department);

6.C语言并不执行数组下标的有效性检查。你觉得为什么这个明显的安全手段会从语言中省略?

C语言这种不加检查数组下标的行为有好处也有坏处。好处是不需要浪费时间对有些已知是正确的数组下标进行检查。坏处是这样做将使得将无效的下标引用无法被检测出来。
从技术上说,让编译器准确的检查下标值时候有效是做得到的,但这样做将带来极大的额外负担。有些后期的编译器,如Borland C++ 5.0,把下标检查作为一种调试工具,你可以选择是否启用它。


7.本章描述的rearrange程序包含下面的语句
strncpy( output + output_col,
input + columns[col], nchars );

strcpy函数只接受两个参数,所以它实际上所复制的字符数由第2个参数指定。在本程序中,如果用strcpy函数取代strncpy函数会出现什么结果?

在本程序中,用strcpy函数取代strncpy后并没有异常错误,程序运行正常。但是这仍然是一个不安全的操作。
函数原型:extern char *strcpy(char *dest,char *src)
strcpy是从src地址开始,一直到NULL,也就是“\0”结束的字符串赋值到以dest地址开始的空间。strcpy函数并不对src字符串与dest字符串空间进行判断buffer大小,如果dest的空间过小,将会引起buffer overflow(缓冲区溢出)。

函数原型:char * strncpy(char *dest, char *src, size_tn);
strncpy函数是strcpy函数的安全版,第三个参数可指定拷贝范围的大小,并不一定到NULL结束,使用strncpy可以有效避免buffer overflow的出现

8.rearrange程序包含下面的语句

while( gets( input ) != NULL ) {
你认为这段代码可能会出现什么问题?
由于没有对输入的字符串进行规定,输入的字符串很可能超过input的大小,从而导致overflow。


第一章课后练习

1.“Hello world!”程序常常是C编程新手所编写的第1个程序。它在标准输出中打印Hello world!,并在后面添加一个换行符。当你希望摸索出如何在自己的系统中运行C编译器时,这个小程序往往是一个很好的测试例。

非常简单

#include <stdio.h>
void main()
{
    printf("Hello Word!\n");
    return ;
}

2.编写一个程序,从标准输入读取几行输入。每行输入都要打印到标准输出上,前面要加上行号。在编写这个程序时要试图让程序能够处理的输入行的长度没有限制。

简单理解题意,输入行的长度没有限制,应该指一个while循环无限循环输入字符串,代码如下。

#include "stdafx.h"

void main()
{
    char ar[1000];
    int i = 0;
    while(gets(ar)!=NULL)
    {
        printf("第%d行:%s\n",i,ar);
        i++;
    }
    return ;
}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值