| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 308697 人关注过本帖, 10 人收藏
标题:关于C标准
取消只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
13.18 为什么大家都说不要使用 scanf()?那我该用什么来代替呢?

scanf() 有很多问题 --- 参见问题 13.15, 13.16 和  13.17。而且, 它的 %s 格式有着和 gets() 一样的问题 (参见问题  13.20) --- 很难保证接收缓冲不溢出。

更一般地讲, scanf() 的设计使用于相对结构化的, 格式整齐的输入。设计上, 它的名称就是来自于 ``scan formatted"。如果你注意到, 它会告诉你成功或 失败, 但它只能提供失败的大略位置, 至于失败的原因, 就无从得知了。 对 scanf() 多得体的错误恢复几乎是不可能的; 通常先用类似 fgets() 的函数 读入整行, 然后再用 sscanf() 或其它技术解释。strtol(), strtok() 和 atoi()  等函数通常有用; 参见问题 14.4。如果你真的要用任何 scanf 的变体, 你要确保检查返回值, 以确定找到了期待的值。而使用 %s 格式的时候, 一定要 小心缓冲区溢出。

参考资料: [K&R2, Sec. 7.4 p. 159]。

授人以渔,不授人以鱼。
2013-08-11 12:26
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
13.24 既然 fflush() 不能, 那么怎样才能清除输入呢?

这取决于你要做什么。如果你希望丢掉调用 scanf() (参见问题 12.16 - 12.17) 之后所剩下的换行符和未预知的输入, 你可能需要重写你的  scanf() 或者换掉它, 参见问题 13.18。或者你可以用下边这样 的代码吃掉一行中多余的字符
     while((c = getchar()) != '\n' && c != EOF)
        /* 丢弃 */ ;

你也可以使用 curses 的 flushinp() 函数。

没有什么标准的办法可以丢弃标准输入流的未读取字符, 即使有, 那也不够, 因为未读取字符也可能来自其它的操作系统级的输入缓冲区。如果你希望严格 丢弃多输入的字符 (可能是预测发出临界提示), 你可能需要使用系统相关的 技术; 参加问题 20.1 和 20.2。

参考资料: [ISO, Sec. 7.9.5.2]; [H&S, Sec. 15.2]。

授人以渔,不授人以鱼。
2013-08-11 12:30
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
14.18 我不断得到库函数未定义错误, 但是我已经 #inlude 了所有用到的头文件了。
 
通常, 头文件只包含外部说明。某些情况下, 特别是如果是非标准函数, 当你 连接程序时, 需要指定正确的函数库以得到函数的定义。#include 头文件 并不能给出定义。参见问题 11.10, 12.29, 14.19, 15.3 和 20.39。

授人以渔,不授人以鱼。
2013-08-11 12:36
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
11.10 我在编译一个程序, 看起来我好像缺少需要的一个或多个头文件。 谁能发给我一份?

根据 ``缺少的" 头文件的种类, 有几种情况。

如果缺少的头文件是标准头文件, 那么你的编译器有问题。你得向你的供货商 或者精通你的编译器的人求助。

对于非标准的头文件问题更复杂一些。有些完全是系统或编译器相关的。 某些 是完全没有必要的, 而且应该用它们的标准等价物代替。 例如, 用  <stdlib.h> 代替 <malloc.h>。 其它的头文件, 如跟流行的附加库相关的, 可能有相当的可移植性。

标准头文件存在的部分原因就是提供适合你的编译器, 操作系统和处理器的定义。 你不能从别人那里随便拷贝一份就指望它能工作, 除非别人跟你使用的是同样的 环境. 你可能事实上有移植性问题 (参见第 20 章) 或者编译器问题。 否则, 参见问题 19.18。

授人以渔,不授人以鱼。
2013-08-11 12:37
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
20.43 我不能使用这些非标准、依赖系统的函数, 程序需要兼容 ANSI!

你很不走运。要么你误解了要求, 要么这不可能做到。 ANSI/ISO C 标准 没有定义做这些事的方法; 它是个语言的标准, 不是操作系统的标准。 国际标准 POSIX (IEEE 1003.1, ISO/IEC 9945-1) 倒是定义了许多这方面 的方法, 而许多系统 (不只是 Unix) 都有兼容 POSIX 的编程接口。

可以做到, 也是可取的做法是使程序的大部分兼容 ANSI, 将依赖系统的功能 集中到少数的例程和文件中。这些例程或文件可以大量使用 #ifdef 或针对 每一个移植的系统重写。

授人以渔,不授人以鱼。
2013-08-11 12:42
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
8.21 我必须在程序退出之前释放分配的所有内存吗?

你不必这样做。一个真正的操作系统毫无疑问会在程序退出的时候回收所有的 内存和其它资源。 然而, 有些个人电脑据称不能可靠地释放内存, 从  ANSI/ISO C 的角度来看这不过是一个 ``实现的质量问题"。

参考资料: [ISO, Sec. 7.10.3.2]。

授人以渔,不授人以鱼。
2013-08-11 12:44
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
8.20 我在分配一些结构, 它们包含指向其它动态分配的对象的指针。 我在释放结构的时候, 还需要释放每一个下级指针吗?

是的。一般地, 你必须分别向 free() 传入 malloc() 返回的每一个指针, 仅仅一次 (如果它的确要被释放的话)。一个好的经验法则是对于程序中的每 一个 malloc() 调用, 你都可以找到一个对应的 free() 调用以释放  malloc() 分配的内存。

参见问题 8.21。

授人以渔,不授人以鱼。
2013-08-11 12:55
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
15.1 一个 float 变量赋值为 3.1 时, 为什么 printf 输出的值为 3.0999999?

大多数电脑都是用二进制来表示浮点和整数的。在十进制里, 0.1 是个简单、精确 的小数, 但是用二进制表示起来却是个循环小数 0.0001100110011 ...。 所以 3.1 在十进制内可以准确地表达, 而在二进制下不能。

在对一些二进制中无法精确表示的小数进行赋值或读入再输出时, 也就是从十进制 转成二进制再转回十进制, 你会观察到数值的 不一致. 这是由于编译器二进制/十进制转换例程的精确度引起的, 这些例程也用在  printf 中。 参见问题 15.6。

授人以渔,不授人以鱼。
2013-08-11 12:58
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
15.4 浮点计算程序表现奇怪, 在不同的机器上给出不同的结果。

首先阅读问题 15.2.

如果问题并不是那么简单, 那么回想一下, 电脑一般都是用一种浮点的格式来近似 的模拟实数的运算, 注意是近似, 不是完全。下溢、误差的累积和其它非常规性是 常遇到的麻烦。

不要假设浮点运算结果是精确的, 特别是别假设两个浮点值可以进行等价比较。也 不要随意的引入 ``模糊因素"; 参见问题 15.5。

这并不是 C 特有的问题, 其它电脑语言有一样的问题。浮点的某些方面被通常 定义为 ``中央处理器 (CPU) 是这样做的" (参见问题 12.34), 否则在一 个没有 ``正确" 浮点模型的处理器上, 编译器要被迫做代价非凡的仿真。

本文不打算列举在处理浮点运算上的潜在难点和合适的做法。一本好的有关数字 编程的书能涵盖基本的知识。参见下面的参考资料。

参考资料: [K&P, Sec. 6 pp. 115-8]; [Knuth, Volume 2 chapter 4]; [Goldberg]。

授人以渔,不授人以鱼。
2013-08-11 12:59
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
3.7 是否有自动比较结构的方法?

没有。编译器没有简单的好办法实现结构比较 (即, 支持结构的 == 操作符), 这也符合 C 的低层特性。 简单的按字节比较会由于结构中没有用到的 ``空洞'' 中的随机数据  (参见问题 2.10) 而失败; 而按域比较在处理大结构时需要难以接受的大量重复代码。

如果你需要比较两个结构, 你必须自己写函数按域比较。

参考资料: [K&R2, Sec. 6.2 p. 129]; [Rationale, Sec. 3.3.9]; [H&S, Sec. 5.6.2 p. 133]。

授人以渔,不授人以鱼。
2013-08-11 13:06
快速回复:关于C标准
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029638 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved