- 浏览: 37179 次
- 性别:
- 来自: 上海
最近访客 更多访客>>
最新评论
-
shi5jin:
呵呵,我看的是Effective C++第三版,第一个item ...
站在巨人肩上的思考[连载] (5) -
bigpanda:
欢迎讨论远程数据库和rpc的编程。
“《Effective ...
站在巨人肩上的思考[连载] (5) -
spinach:
读完这两节,我基本就一个字,“基本帅呆了”。
站在巨人肩上的思考 [连载] (3) -
spinach:
终于等到了,慢慢看。
站在巨人肩上的思考 [连载] (2) -
spinach:
期待下文
站在巨人肩上的思考 [连载] (1)
第4章 类型和声明
4.3 字符类型
“由8bits表示的256个值可以解释为0~255,或者解释为-128~127,不幸的是,普通char类型选择那种解释是由具体实现决定的”[1]<o:p></o:p>
所以,不要做过多的假设。如果你必须这样做,请使用显式的signed char或者unsigned char来声明变量。
4.4整数类型
“unsigned整数类型对于存储二进制bit数组的使用方式非常理想。但是,如果用unsigned而不用int仅仅因为想多一个bit来表示正整数,就不是什么好主意。”[2]<o:p></o:p>
这句话轻描淡写的一笔带过,但是含义颇深。它再一次提醒我们,不要指望一种并没有看起来那么可靠的措施,来为我们提供安全保险。
举例来说,当我们声明一个如下的函数:
int func(unsigned arg);
的时候,其实我们的潜台词是:“哦,我要的参数的值都应该是大于零的。”不幸的是,事实的确如此。对于函数内部,arg肯定是大于0。那为什么危险?因为我们认为这种声明方式会给我带来某种类型安全,却恰恰相反。C++为int到unsigned提供了隐式转换,这意味着一个负整数可以悄无声息的在需要的时候变为一个正整数。假设程序由于某种异常调用了func(-1),此时在func()内部arg的值就可能是4294967295(在我的32位PC上)或者是一个其他的正整数值,函数将正常执行,甚至返回一个表示成功的值,但是其实际结果可能完全不是那么回事!程序将由此“驶上通往崩溃的快车道”。另一方面,正是由于声明时的潜台词,我们通常忽略了接口输入参数的安全检查,而交给unsigned类型这个脆弱的保护措施,况且,当我们使用了unsigned做声明的时候,我们也根本无法进行必要的安全检查,应为arg在函数内部一定为正!或者有些人依然会狡辩说,可以针对特定应用,来收紧检查条件,如月份我们可以检查if(arg>0 && arg<13)。请相信我,即使是说这话的人本身也会底气不足的,因为调用者完全可以传递一个负数,使得在函数内部的参数值落在安全范围之内。虽然概率很小,但是对于一个健壮的程序来说,这是不允许的。想想坐在屏幕前看着一些充满了magic number的调试信息,用整个下午的时间猜测每个数字是怎么来的情景,那种痛苦真是会令人崩溃。如果你不想成为这样可怜的程序员,请注意这个细节:大多数时候尽量使用signed而不是unsigned类型,尤其是作为函数接口的时候,并且做好每一次接口安全检查。终有一天你会发现,花费这点力气是值得的。
4.6 类型的大小
很多时候,清楚地知道每种类型的大小是有实际意义的。这点对于固定平台的程序员来说可能不是那么明显,但是对于那些经常更换目标平台的嵌入式程序员来说,就很实际了。况且,即便是前者,也应该意识到,任何一个成功的软件,几乎都面临着跨平台的考验。一个有远见的程序员,应该从开始就注重这些细节。
“C++对象的大小,使用char的大小的整数倍来表示的”。有些平台对char的实现并不一定用8位bit,还有些实现int也不一定是32位bit。不要对类型大小以及相互之间的关系做某种过多的假设。书上第四段列出了一些“肯定”的关系,除次之外的其他结论都是不稳固的。另外,C++也提供了专门研究类型大小、边界的库,可通过标准头文件 <limits></limits> 来调用。具体内容可参见库使用说明,这里提供一个很丑的示范程序,你可以直接拷贝到你的平台上,编译,运行,“挑战一下极限”。
- #include <iostream>
- #include <cstdlib>
- #include <limits> // numeric_limits
- #include <string>
- using namespace std;
- void isSpecialized(void);
- void hasInfinity(void);
- void getMaxValue(void);
- void getMinValue(void);
- void getEpsilon(void);
- void howManyDigits10(void);
- void howManyDigits2(void);
- int main()
- {
- ///whether the internal type has a max or min value:
- isSpecialized();
- ///whether has a infinite value;
- hasInfinity();
- ///what's the max value of a type;
- getMaxValue();
- ///what's a min value of a type;
- getMinValue();
- //what's the min value of a float type.
- getEpsilon();
- //how many decimal digits can a type express;
- howManyDigits10();
- //how many binary digits can a type express;
- howManyDigits2();
- return 0;
- }
- void
- isSpecialized(void) {
- cout << boolalpha;
- cout << "specialized(char): " << numeric_limits<char>::is_specialized << endl;
- cout << "specialized(wchar_t): " << numeric_limits<wchar_t>::is_specialized << endl;
- cout << "specialized(string): " << numeric_limits<string>::is_specialized << endl;
- cout<< noboolalpha;
- return;
- }
- void
- hasInfinity(void) {
- cout << boolalpha;
- cout << "has infinity char: " << numeric_limits<char>::has_infinity << endl;
- cout << "has infinity long double: " << numeric_limits<long double>::has_infinity << endl;
- cout << "has infinity string: " << numeric_limits<string>::has_infinity<< endl;
- cout << noboolalpha << endl;
- return ;
- }
- void
- getMaxValue(void) {
- cout << "max(int): "
- << numeric_limits<int>::max()
- << "\nmax(char): "
- << static_cast<int>(numeric_limits<char>::max())
- << "\nmax(short): "
- << numeric_limits<short>::max()
- << "\nmax(unsigned int): "
- << numeric_limits<unsigned int>::max()
- << "\nmax(unsigned short): "
- << numeric_limits<unsigned short>::max()
- << "\nmax(unsigned long): "
- << numeric_limits<unsigned long>::max()
- << "\nmax(long): "
- << numeric_limits<long>::max()
- << "\nmax(long long): "
- << numeric_limits<long long>::max()
- << "\nmax(float): "
- << numeric_limits<float>::max()
- << "\nmax(double): "
- << numeric_limits<double>::max()
- << "\nmax(long double): "
- << numeric_limits<long double>::max()
- << endl;
- return ;
- }
- void
- getMinValue(void) {
- cout << "min(int): "
- << numeric_limits<int>::min()
- << "\nmin(char): "
- << static_cast<int>(numeric_limits<char>::min())
- << "\nmin(short): "
- << numeric_limits<short>::min()
- << "\nmin(unsigned int): "
- << numeric_limits<unsigned int>::min()
- << "\nmin(unsigned short): "
- << numeric_limits<unsigned short>::min()
- << "\nmin(unsigned long): "
- << numeric_limits<unsigned long>::min()
- << "\nmin(long): "
- << numeric_limits<long>::min()
- << "\nmin(long long): "
- << numeric_limits<long long>::min()
- << "\nmin(float): "
- << numeric_limits<float>::min()
- << "\nmin(double): "
- << numeric_limits<double>::min()
- << "\nmin(long double): "
- << numeric_limits<long double>::min()
- << endl;
- return ;
- }
- void
- getEpsilon(void) {
- cout << "\ndouble epsilon: "
- << numeric_limits<double>::epsilon()
- << "\nfloat epsilon: "
- << numeric_limits<float>::epsilon()
- << "\nlong double epsilon: "
- << numeric_limits<long double>::epsilon()
- << endl;
- }
- void
- howManyDigits10(void) {
- cout << "\ndouble dec digits number: "
- << numeric_limits<double>::digits10
- << "\nfloat dec digits number: "
- << numeric_limits<float>::digits10
- << "\nlong double dec digits number: "
- << numeric_limits<long double>::digits10
- << "\nlong long dec digits number: "
- << numeric_limits<long long>::digits10
- << "\nint dec digits number: "
- << numeric_limits<int>::digits10
- << "\nshort dec digits number: "
- << numeric_limits<short>::digits10
- << "\nchar dec digits number: "
- << numeric_limits<unsigned char>::digits10
- <<endl;
- return ;
- }
- void
- howManyDigits2(void) {
- cout << "\ndouble dec digits number: "
- << numeric_limits<double>::digits
- << "\nfloat dec digits number: "
- << numeric_limits<float>::digits
- << "\nlong double dec digits number: "
- << numeric_limits<long double>::digits
- << "\nlong long dec digits number: "
- << numeric_limits<long long>::digits
- << "\nint dec digits number: "
- << numeric_limits<int>::digits
- << "\nshort dec digits number: "
- << numeric_limits<short>::digits
- << "\nchar dec digits number: "
- << numeric_limits<unsigned char>::digits
- <<endl;
- return ;
- }
[1] 《The C++ Programming Language》-- Chapter 4.3, paragraph 4
[2] 《The C++ Programming Language》-- Chapter 4.4, paragraph 2
发表评论
-
站在巨人肩上的思考[连载] (8)
2007-12-03 14:58 11265.2 数组 5.2.2 字符串文字量 ... -
站在巨人肩上的思考[连载] (7)
2007-12-03 14:56 11104.8 枚举 枚举是表示具有共同属性的整 ... -
一种“标准”的虚函数机制简介
2007-11-09 11:07 1245编译器是如何针对虚函数产生可以再运行时刻确定被调用函数 ... -
A Generic Ostream Iterator
2007-09-07 08:37 1326by Christopher Diggins November ... -
我能从构造函数调用虚函数吗?
2007-09-06 11:18 2745可以。不过你得悠着点 ... -
为何我的构造函数不太对劲?
2007-09-06 10:57 1149类似这样的问题千奇百怪。例如: ... -
如何在类中定义常量?
2007-09-06 10:51 2500如果你想得到一个可用 ... -
为何空类的大小不是零?
2007-09-06 10:46 1859为了确保两个不同对象的地址不同,必须如此。也正因为如此,new ... -
我应该怎样处理内存泄漏?
2007-09-06 10:43 944很 简单,只要写“不漏 ... -
您可以推荐一种编写代码的标准吗?
2007-09-06 10:36 1297C++ 代码编写标准的要点是:根据使用 C++ 的具体的 ... -
如何使用异常?
2007-09-05 09:34 984请参考 TC++PL 章节 8.3、第十四章,以及附录 E。附 ... -
为何C++既有指针也有引用?
2007-09-05 09:28 867C++ 的指针继承于 C,若要移除指针,势必造成严重的兼容性 ... -
可以在构造函数里抛出异常吗?析构函数里呢?
2007-09-05 09:24 2320可以:当你不能正常地初始化(构造)对象时,你应该在 ... -
站在巨人肩上的思考[连载] (5)
2007-04-23 19:40 2331最近做个小项目,有点忙。事情倒是不难,就是有点杂, ... -
站在巨人肩上的思考[连载] (4)
2007-04-10 11:13 1792首先感谢 spinach 的鼓励与支持。你给了我很大的动力, ... -
站在巨人肩上的思考 [连载] (3)
2007-04-09 08:36 2163上一篇中,主要是对C++类设计的一个概览。如果 ... -
站在巨人肩上的思考 [连载] (2)
2007-04-07 11:23 2106<st1:chmetcnv tcsc=" ... -
站在巨人肩上的思考 [连载] (1)
2007-04-06 08:20 2142[原创。欢迎复制。转载请您注明出处 -- Gavin] Tip ...
相关推荐
20210531-华金证券-卓越商企服务-6989.HK-站在巨人肩膀上的商务物管领军企业.pdf
八年级物理全册1.3站在巨人的肩膀上我国的四大发明素材新版沪科.doc
绿洲APP产品分析报告:站在巨人肩膀上能否看得更远?.pdf
家用电器行业深度:小米集团:站在 “巨人们”的肩膀上看世界.pdf
站在巨人的肩膀上,_迁移学习_Transfer_Learning
站在巨人的肩膀上-scrollView联动
读完本书,受益匪浅,与大家共享!!! 让我们站在巨人的肩膀上。
前辈对错误的总结,让你站在巨人的肩膀上走的更远
使用Java语言开发,站在巨人肩膀上制作了异步非阻塞的IM,采用官方协议适配器解决一台服务器可解决http、websocket、tcp(可以私有定制)的多协议通讯.zip
巨人肩上新巨人.doc
站在巨人的肩上——XX借势营销策划.doc
站在巨人的肩上泛德林恩借势营销策划.docx
站在巨人的肩膀上的项目,感谢zhile大佬的Pandora-Next项目.zip
站在巨人的肩上--泛德林恩借势营销策划.doc
使用Java语言开发,站在巨人肩膀上制作了异步非阻塞的IM,采用官方协议适配器解决一台服务器可解决http、websocket、tcp(可以私有定制)的多协议通讯.zip
八年级物理全册第一章第三节站在巨人的肩膀上教学课件新版沪科版
站在巨人的肩膀上:分层设计在 Nervos 生态系统中的 layer 2区块链上的实际应用-SACC2021年中国系统架构师大会
背靠开放平台 如何在巨人肩膀上把握市场机.docx
20210706-浦银国际-宝胜国际-3813.HK-站在巨人的肩膀上;利润率改善空间大.pdf
八年级物理全册 1.3 站在巨人的肩膀上 我国的四大发明素材 (新版)沪科版(通用).doc