`
runfeel
  • 浏览: 935632 次
文章分类
社区版块
存档分类
最新评论

C/C++ 一些细节问题 (1)

 
阅读更多

一、无符号,有符号数的比较问题。

C/C++中规定,两种类型比较,如果两种类型的内存占用一致的话。则默认转型至无符号数,如果两种类型内存占用不移植,则默认转型至内存占用更大的类型。

例如:

Code:
  1. #include<stdio.h>
  2. intmain(intargc,char**argv)
  3. {
  4. inti=-1;
  5. unsignedintj=2;
  6. if(i<=j)printf("Hello");
  7. elseprintf("world");
  8. return0;
  9. }

这样子的话,理论上会输出world。因为unsigned int 和int 的内存占用一致(都是4B),所以会转型至unsigned,-1的二进制表示为0xFFFFFFFF,所以如果无符号的话是一个非常非常大正数,自然会输出world

然而下面一个例子,不一样了

Code:
  1. #include<stdio.h>
  2. intmain(intargc,char**argv)
  3. {
  4. longlongi=-1;
  5. unsignedintj=2;
  6. if(i<=j)printf("Hello");
  7. elseprintf("world");
  8. return0;
  9. }

这样就会输出Hello,因为会转型到long long。

当然,这只是C/C++的标准,至于遵守不遵守标准,那是编译器的问题。以上代码用GCC和VC都编译过,和标准符合。

这么繁杂的问题,如何解决呢?

我个人的想法是,可以由两种解决办法:

1、尽量少的使用无符号数。或者不要因为没有负数就是用无符号数。有的时候,潜在的风险未必值得你这么做。尤其当代码量超多的时候。

2、比较时尽量类型转换。。我是个懒人,这种做法。。。。实在是不现实。。每次都要多打多少字啊。呵呵

二、union的扯淡用法

如何将一个int的中间16位的末8位左移三位,其他的位不变呢?

其实这个问题什么算法也不需要,只需要使用union这个类型;

Code:
  1. #include<iostream>
  2. usingnamespacestd;
  3. unionint_
  4. {
  5. unsignedintwhole;
  6. struct{
  7. unsignedchara;
  8. unsignedcharb;//这里的abcd顺序也许和计算机的地址排列有关系,大端派,小端派。呵呵。不过
  9. //X86下这样没错
  10. unsignedcharc;
  11. unsignedchard;
  12. }bytes;
  13. };
  14. intmain()
  15. {
  16. int_t;
  17. t.whole=257;
  18. t.bytes.b<<=3;
  19. cout<<t.whole<<endl;
  20. return0;
  21. }

就是像这里的代码一样。union的实际作用,是将其中声明的变量的地址,对齐到同一地点,这样正常情况下,就达到了同一时刻只有一种变量的效果。不过,如果只是地址一致的话,两种变量实际上同时都存在,所以对一个union中的变量进行操作就会影响到另一个变量的值,于是就有了这种效果。

值得注意的是:1、这样做,必须小心字符填充(字对齐?我对专业名词一向记不住)。不一定你声明是什么,内存占用就是多大。

2、有些编译器为了避免误操作,将每次取另一种union的类型是,都会将内存置零。

这样做,可能应用作用并不大,不过至少理解了union的实际意义,至于嵌入式方面也许确实有一些应用,毕竟对位的精确操作是嵌入式的需求。而这种方法,实际运行上并没有消耗,也符合嵌入式对性能的要求。

另:还有一种方法实现这个效果,那就是用 引用 。具体方法,我就不多写了,引用的类型强制转换。

三、构造函数时值的初始化

前几天,有个同学刚学C++,我一看就帮他写了个作业(...主要是他们学过C,老师留的是预习作业,而他写的代码基本没问题,但是就是没有C++的感觉)。其中有一点写下来:

首先,什么是构造函数时成员变量的初始化:

有的人说,在构造函数体里写,什么this->math= XXX;啊,是初始化。我想,这是完全错误的。初始化的写法应该是在构造函数实现时,后面跟着:,然后再在后面依次写 变量名(初始化值)。如果没有指定初始化的值,则编译器为其初始化一个值(这个是个悲剧,因为有时候成员变量忘了初始化,使用时就会出现垃圾)。而在函数体内的“初始化”,实际上是对变量的第二次赋值(第一次是初始化的时候)。所以速度上会慢下来。

其次,初始化顺序。

其实,我想说的是,永远不要顺序相关的初始化。例如

Code:
  1. SomeClass:SomeClass(intr,intv):m_r(r),m_v(v),m_total(m_r+m_v)
  2. {
  3. }

这样的初始化,m_total的值依赖于m_r和m_v的值。有的人说了,我明明在之前已经初始化m_r和m_v了啊?其实不然。实际初始化的顺序,和这里的顺序,一点关系也没有。真的。真正有关系的,是变量在类里声明的顺序。

Code:
  1. SomeClass
  2. {
  3. intm_r; //这是第一个被初始化的变量
  4. intm_v;//这是第二个
  5. intm_total; //这是第三个
  6. };

如果这样的代码,确实没有问题,但是如果把m_total向上提一个位置,那这个初始化就是没有意义的了。。(也许你会奋斗一晚上,然后说,我编译器有问题。。恩。呵呵)

解决的办法,尽量不要做循序相关的初始化。即使你知道这个原理,也说不定哪天心血来潮修改下.h文件(更多的情况是更新了UML文件,然后输出变量的顺序变了。。。)。那这就绝对的悲剧了。

再次,是我一个困惑的问题。

首先我们知道,初始化比在函数体内部赋值速度快,

但是,愿望是美好的,现实是残酷的,有的时候,初始化那仅有一句的statement不足以解决问题。。这可咋整。

有一个折中的方法:

Code:
  1. structStudent{
  2. longlongstudentNumber;
  3. stringname;
  4. floatmath;
  5. floatenglish;
  6. floatscore;
  7. Student(longlongsn,stringn,floatm,floate)
  8. :studentNumber(sn),name(n),math(m),english(e),score(getScore(m,e))
  9. {
  10. }
  11. private:
  12. staticfloatgetScore(floatm,floate)
  13. {
  14. if(m<50)m=50;
  15. if(e<50)e=50;
  16. return(6*(m-50)/10+4*(e-50)/10)/10;
  17. }
  18. };

这里声明一个private static函数,来计算绩点,返回值来进行初始化。这样既是在初始化内部完成的,又可以无限制代码的长度。

问题也来了。这样的值传递,应该也是消耗的,究竟是这么初始化消耗的多,还是在函数体内的消耗多呢?

不过至少一点,这种在返回指针的情况下;肯定是比在函数体内“初始化”快,而且,这样写出的代码更有条理。

差不多就写到这了,最后一个问题真心求解

分享到:
评论

相关推荐

    IAR C/C++ Development Guide

    《IAR C/C++开发指南》是一本针对使用IAR集成开发环境(IDE)进行嵌入式系统开发的开发者编写的详细指导书籍。该指南详细介绍了如何使用IAR IDE进行编译和链接,以及如何对开发环境进行优化和配置。这本书适合使用C/...

    C/C++ 标准库函数 (中文版)

    综上所述,C/C++标准库函数手册是一份极其宝贵的资源,它帮助程序员们高效地利用C/C++语言提供的强大功能,同时也要求程序员有较高的编程素养和对语言细节的准确把握。掌握这些基础知识点和库函数的使用,是编写高...

    C/C++ 数据结构

    C和C++作为两种强大的编程语言,提供了丰富的工具来实现各种数据结构。在这个“C/C++ 数据结构”项目中,包含了作者自己编写的C工程源码,涵盖了链表、队列、栈和树等基本数据结构。 首先,我们来看看链表。链表是...

    林锐-高质量c/c++编程指南

    《林锐-高质量C/C++编程指南》不仅为C/C++开发者提供了一套全面而细致的编程规范,还深入讲解了许多核心概念和技术细节,对于提升编程水平和编写高质量的C/C++程序具有重要的指导意义。无论是初学者还是有一定经验的...

    编程及C/C++初学者 FAQ

    虽然Python以其简洁易学的语法受到很多初学者的喜爱,但对于希望深入了解计算机工作原理和编程底层细节的人来说,学习C/C++仍然是一个更好的选择。Python更适合于数据科学、机器学习等领域。 ##### 9. 学习C/C++...

    从缺陷中学习C/C++初稿

    C/C++是一种广泛应用于系统与应用软件开发的编程语言,它既强大又富有挑战性,尤其是C++经过20多年的发展,已经变得相当复杂。在这门语言中编写出稳定可靠的生产系统,并非易事。软件开发的道路上,充满了各种陷阱和...

    邮件库 IMAP/STMP/POP3 Email Library C/C++

    邮件库IMAP/STMP/POP3 Email Library C/C++是一个专为C/C++开发者设计的工具,旨在简化邮件处理任务,使得开发者能够在VC++环境下高效地实现邮件收发功能。这个库集成了Internet邮件访问协议(IMAP)、简单邮件传输...

    C/C++源程序去注释工具

    "TC源代码"意味着我们可以查看并学习到工具的实现细节,这对于学习C/C++编程或者了解去注释算法的人来说是一个宝贵资源。 标签中的"C"和"TC"进一步确认了这个工具与C语言和 Turbo C 编译器有关。"文件"标签可能意味...

    C/C++常见细节性笔试题

    如array(数组), tree(二叉树)等 另外包含一些常见C/C++考题的验证性实现,如Util,virtual 其中以Util.cpp, Virtual.cpp最有价值, Util包含一些细节性的笔试题目; Virtual则包含常见和虚函数相关...

    Financial Applications Using Excel Add-in Development in C/C++

    ### 金融应用中的Excel插件开发(C/C++) #### 一、背景与目标 《金融应用中的Excel插件开发(C/C++)》这本书旨在为读者提供一个全面且深入的指南,帮助他们掌握如何利用C/C++创建高效可靠的Excel插件(add-ins)。...

    C/C++高质量编程

    《C/C++高质量编程》由林锐博士撰写,是一份详尽且专业的指南,旨在提升C/C++程序员的编码质量,被广泛认为是C/C++程序员必读的经典之作。此书不仅涵盖了C/C++编程的基础知识,更深入探讨了如何编写高效、可维护的...

    Android Binder C/C++层实现示例

    本示例"Android Binder C/C++层实现示例"着重展示了如何在C/C++层面进行Binder通信的实现,这对于深入理解Android系统的底层工作原理至关重要。 一、Binder架构 Binder架构包括Client、Server、Service Manager和...

    C/C++深层探索.rar

    《C&C++深层探索》还可能涵盖异常处理、链接器的工作方式、C++的命名空间、namespace的细节以及预处理器宏的使用技巧等。这些内容将帮助读者全面提升对C++语言的理解,为解决复杂问题提供理论支持。 通过阅读《C/...

    C/C++ 参考手册

    《C/C++参考手册》是一本非常实用的编程资源,主要针对C和C++的开发者。手册详尽地解析了这两种语言的库函数,并且涵盖了C++标准模板库(STL)的使用,尽管它不包括模板库的算法部分。在深入探讨这个主题之前,我们...

    c/c++编译器c-free适合初学者

    C-Free 是一款专为初学者设计的C语言和C++编译器,它融合了这两种编程语言的编译功能,提供了一个易于上手、功能全面的开发环境。这款软件的出现,使得初学者在学习编程的过程中可以更专注于代码本身,而不用过于...

    C/C++程序设计员应聘常见面试试题深入剖析

    本文将对一些常见的C/C++面试题进行深入剖析,以帮助应聘者提升对C/C++语言的理解和应用。 首先,我们来看一些典型的找错题。试题1中,面试者被要求复制一个超过目标数组长度的字符串,这会导致缓冲区溢出,是C/C++...

    C语言/C++雷霆战机代码(终极版)

    【C语言/C++雷霆战机代码(终极版)】 在编程世界中,C语言和C++是两种非常重要的编程语言,尤其在游戏开发领域,它们因其高效性和灵活性而被广泛使用。"雷霆战机"是一个典型的2D飞行射击游戏,其源代码能够帮助...

    高级C C++编译技术_[美]斯特瓦诺维奇著

    本书的核心内容涵盖了C/C++编程语言的底层细节,尤其是关于编译器的工作原理、库的加载机制以及程序打包技术等方面的知识。 在C/C++编程中,编译器扮演着至关重要的角色。它将程序员编写的源代码转化为机器可执行的...

    《C/C++编写跨平台程序:实践篇》

    本书《C/C++编写跨平台程序:实践篇》主要面向已经具备一定C/C++基础的读者群体,旨在教授如何使用C/C++这一强大的编程语言来编写可以在多个操作系统上运行的跨平台程序。跨平台编程不仅需要对语言有深入理解,还要...

    Microtec C/C++ Compiler Toolkit For PowerPC

    ### Microtec C/C++ Compiler Toolkit for PowerPC:深入解析与应用 #### 概述 Microtec C/C++ Compiler Toolkit for PowerPC(版本3.4)是专为嵌入式开发人员设计的一套全面且高效的交叉编译解决方案。该工具集...

Global site tag (gtag.js) - Google Analytics