一、无符号,有符号数的比较问题。
C/C++中规定,两种类型比较,如果两种类型的内存占用一致的话。则默认转型至无符号数,如果两种类型内存占用不移植,则默认转型至内存占用更大的类型。
例如:
- #include<stdio.h>
-
intmain(intargc,char**argv)
- {
-
inti=-1;
-
unsignedintj=2;
-
if(i<=j)printf("Hello");
-
elseprintf("world");
-
return0;
- }
这样子的话,理论上会输出world。因为unsigned int 和int 的内存占用一致(都是4B),所以会转型至unsigned,-1的二进制表示为0xFFFFFFFF,所以如果无符号的话是一个非常非常大正数,自然会输出world
然而下面一个例子,不一样了
- #include<stdio.h>
-
intmain(intargc,char**argv)
- {
-
longlongi=-1;
-
unsignedintj=2;
-
if(i<=j)printf("Hello");
-
elseprintf("world");
-
return0;
- }
这样就会输出Hello,因为会转型到long long。
当然,这只是C/C++的标准,至于遵守不遵守标准,那是编译器的问题。以上代码用GCC和VC都编译过,和标准符合。
这么繁杂的问题,如何解决呢?
我个人的想法是,可以由两种解决办法:
1、尽量少的使用无符号数。或者不要因为没有负数就是用无符号数。有的时候,潜在的风险未必值得你这么做。尤其当代码量超多的时候。
2、比较时尽量类型转换。。我是个懒人,这种做法。。。。实在是不现实。。每次都要多打多少字啊。呵呵
二、union的扯淡用法
如何将一个int的中间16位的末8位左移三位,其他的位不变呢?
其实这个问题什么算法也不需要,只需要使用union这个类型;
- #include<iostream>
-
usingnamespacestd;
-
unionint_
- {
-
unsignedintwhole;
-
struct{
-
unsignedchara;
-
unsignedcharb;//这里的abcd顺序也许和计算机的地址排列有关系,大端派,小端派。呵呵。不过
- //X86下这样没错
-
unsignedcharc;
-
unsignedchard;
- }bytes;
- };
-
intmain()
- {
- int_t;
- t.whole=257;
- t.bytes.b<<=3;
- cout<<t.whole<<endl;
-
return0;
- }
就是像这里的代码一样。union的实际作用,是将其中声明的变量的地址,对齐到同一地点,这样正常情况下,就达到了同一时刻只有一种变量的效果。不过,如果只是地址一致的话,两种变量实际上同时都存在,所以对一个union中的变量进行操作就会影响到另一个变量的值,于是就有了这种效果。
值得注意的是:1、这样做,必须小心字符填充(字对齐?我对专业名词一向记不住)。不一定你声明是什么,内存占用就是多大。
2、有些编译器为了避免误操作,将每次取另一种union的类型是,都会将内存置零。
这样做,可能应用作用并不大,不过至少理解了union的实际意义,至于嵌入式方面也许确实有一些应用,毕竟对位的精确操作是嵌入式的需求。而这种方法,实际运行上并没有消耗,也符合嵌入式对性能的要求。
另:还有一种方法实现这个效果,那就是用 引用 。具体方法,我就不多写了,引用的类型强制转换。
三、构造函数时值的初始化
前几天,有个同学刚学C++,我一看就帮他写了个作业(...主要是他们学过C,老师留的是预习作业,而他写的代码基本没问题,但是就是没有C++的感觉)。其中有一点写下来:
首先,什么是构造函数时成员变量的初始化:
有的人说,在构造函数体里写,什么this->math= XXX;啊,是初始化。我想,这是完全错误的。初始化的写法应该是在构造函数实现时,后面跟着:,然后再在后面依次写 变量名(初始化值)。如果没有指定初始化的值,则编译器为其初始化一个值(这个是个悲剧,因为有时候成员变量忘了初始化,使用时就会出现垃圾)。而在函数体内的“初始化”,实际上是对变量的第二次赋值(第一次是初始化的时候)。所以速度上会慢下来。
其次,初始化顺序。
其实,我想说的是,永远不要顺序相关的初始化。例如
- SomeClass:SomeClass(intr,intv):m_r(r),m_v(v),m_total(m_r+m_v)
- {
- }
这样的初始化,m_total的值依赖于m_r和m_v的值。有的人说了,我明明在之前已经初始化m_r和m_v了啊?其实不然。实际初始化的顺序,和这里的顺序,一点关系也没有。真的。真正有关系的,是变量在类里声明的顺序。
- SomeClass
- {
-
intm_r; //这是第一个被初始化的变量
-
intm_v;//这是第二个
-
intm_total; //这是第三个
- };
如果这样的代码,确实没有问题,但是如果把m_total向上提一个位置,那这个初始化就是没有意义的了。。(也许你会奋斗一晚上,然后说,我编译器有问题。。恩。呵呵)
解决的办法,尽量不要做循序相关的初始化。即使你知道这个原理,也说不定哪天心血来潮修改下.h文件(更多的情况是更新了UML文件,然后输出变量的顺序变了。。。)。那这就绝对的悲剧了。
再次,是我一个困惑的问题。
首先我们知道,初始化比在函数体内部赋值速度快,
但是,愿望是美好的,现实是残酷的,有的时候,初始化那仅有一句的statement不足以解决问题。。这可咋整。
有一个折中的方法:
- structStudent{
-
longlongstudentNumber;
-
stringname;
-
floatmath;
-
floatenglish;
-
floatscore;
-
Student(longlongsn,stringn,floatm,floate)
- :studentNumber(sn),name(n),math(m),english(e),score(getScore(m,e))
- {
-
}
-
private:
-
staticfloatgetScore(floatm,floate)
- {
-
if(m<50)m=50;
-
if(e<50)e=50;
-
return(6*(m-50)/10+4*(e-50)/10)/10;
- }
- };
这里声明一个private static函数,来计算绩点,返回值来进行初始化。这样既是在初始化内部完成的,又可以无限制代码的长度。
问题也来了。这样的值传递,应该也是消耗的,究竟是这么初始化消耗的多,还是在函数体内的消耗多呢?
不过至少一点,这种在返回指针的情况下;肯定是比在函数体内“初始化”快,而且,这样写出的代码更有条理。
差不多就写到这了,最后一个问题真心求解
分享到:
相关推荐
如array(数组), tree(二叉树)等 另外包含一些常见C/C++考题的验证性实现,如Util,virtual 其中以Util.cpp, Virtual.cpp最有价值, Util包含一些细节性的笔试题目; Virtual则包含常见和虚函数相关...
c/c++有关编程细节,编程风格,很好的一本书!!
C/C++的高质量编程指南&在编程中需要注意的细节问题
高质量C/C++ 编程指南pdf,清晰,作者编码的一些心得,细节性的东西,还是比较不错的
gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户...
本书一方面对基本的理论进行了阐述,另一方面则聚焦于c/c++使用静态库和动态库的一些注意事项,并举例说明如何解决实际的链接与装载问题。此外,本书尽量使用通俗易懂的语言来阐述这些知识,并补充了大量示例,避免...
C/C++常见的分配释放内存操作过程需要注意的细节问题,以及一些关键字的用法意义
C/C++开发过程中的细节知识点,并非教学C/C++语法。
职场菜鸟需要注意的一些细节问题,一定会对你有所帮助!
有时候写代码想到C/C++里面有一个函数可以实现,但是突然又忘记了具体的调用细节,怎么办? 这里有两个文件,一个是C的一个是C++的,包括库文件和STL算法等,可以解决这个问题。
gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户...
1) 编写主菜单; 2) 可以查询该超市商品信息(注意:一般用户和管理员查到的信息是不一样的,例如管理员可查询到商品进货时价格,而一般用户不能); 3) 用户购买完成后,输出用户购物清单(购物小票); 4) ...
SQLite – C/C++ 安装 在 C/C++ 程序中使用 SQLite 之前,我们需要确保机器上已经有 SQLite 库。可以查看 SQLite 安装章节了解安装过程。 C/C++ 接口 API 以下是重要的 C&C++ / SQLite 接口程序,可以满足您在 C/C++...
同时学c语言的也可以使用,除了使用cout,cin一些很容易上手的c++代码,相当于printf,scanf,主要为了方便输入输出,不用写%d%c... 详细细节也可以访问,百度文库网址 使用注意事项 有着强大的报错功能。 1 全部采用...
首先请做附录B的C++/C试题(不要看答案),考查自己的编程质量究竟如何。然后参照答案严格打分。 (1)如果你只得了几十分,请不要声张,也不要太难过。编程质量差往往是由于不良习惯造成的,与人的智力、能力没有...
相关细节 • sizeof()是一个运算,而非函数 • ++运算不能用在实数上 • 判断一个整数是否是 2^n(2,4,6,8,16...) o !(x & (x - 1)) • 三目条件运算符代码更优 o 编译器能产生比 if...else...更优的代码
本PDF详细的讲解了C、c++中很多被人们忽视的小细节,讲解了如何提高程序的,可靠性、移植性、健壮性、可读性,详细的讲解了 内存管理的知识,本人读了之后,受益良多,希望造福他人
C/C++代码的编写规范,一些细节问题(指针,引用等等),对养成良好的编程风格很有帮助!
《计算机科学丛书:C++语言导学》作者是C++语言的设计者和最初实现者,...本书没有涉及太多C++语言的细节,非常适合想熟悉C++语言最新特性的C/C++程序设计人员以及精通其他高级语言而想了解C++语言特性和优点的人员。