10. 优化结构体中元素的布局

结构体变量所占空间大小并不是其所含类型所占字节数之和,其所占内存字节数涉及到字节对齐。

字节对齐 :变量在内存中储存都是以字节数为单位,每一个字节都有自己的地址,逻辑上变量的首地址(第一个字节的地址)可以是任意位置,但实际不同类型变量其首地址是有一定规则的,这是为了更快的查找便于存取(牺牲空间来换取效率)。

结构体变量中的各个类型在内存中存放时也按照一定的规则,并不是简简单单的用连续的内存 挨边存放。

其遵循的规则有:

(1)结构体变量的首地址可以被其所含最宽的基本类型的大小所整除。

(2)其结构体变量所含各个基本类型的首地址相对于结构体变量的首地址来说的偏移量应为自身大小的整数倍。(如有需要,编译器会在两个基本类型存储的中间填充字节以满足要求)

(3)其结构体变量总的宽度应为其所包含的最宽基本类型大小的整数倍。(如有所需,编译器会在其尾部填充字节以满足要求)

在编程中可以利用上述规则来合理的安排定义数据的顺序减少占用的空间(即减少填充的字节)

,也可以自己显式的填充字节(其实显式填充和编译器自动填充一样,这些填充的内存单元都对程序每有意义)------------空间换取时间

在编程中如果对时间效率要求不高,而空间资源紧张的话可以利用编译器的pack()指令显式的调整结构体的对齐方式。

#pragma pack{ n }     //n为字节数,其取值为1,2,4,8,16,默认是8

struct  A
{
int a;
char b;
short c;
};

如果不用编译器的pack()指令的话则sizeof(A)为8.

如果利用pack()指令并让n为1的话,其结构体对齐方式为1字节对齐,则sizeof(A)为7

-----------时间换取空间

11. 尽量少用强制类型转换

c++保留了C风格的强制类型转换,而且具有自己新风格的强制转换

(1)c风格的强制类型转换

形式为:

类型标识符(待转换变量)或(类型标识符)待转换变量

这种强制类型转换比较危险,其会产生一些难以发现的问题,例如

int a=65536;
int i=unsigned short(a);

i的值为0;

因为在32位的机器中int型的数据占4个字节范围为-2147483648~2147483647

而unsigned short类型的数据占2个字节范围为

0~65535

当把一个大于65535的int类型数据强制转换为unsigned short类型数据时发生内存截断(4个字节截取后两个字节)。相同如果把unsigned类型的数据转换为int类型则会发生内存扩张

(2)c++新式风格的强制类型转换

① const_cast<T*>(a)

其可以去除类中的const ,volatile,和__unaligned属性。

calss a
{
//code
};
int main()
{
const a *p1 =new a; //p1为一个指向常对象的指针变量
a *p2=p1; //错误,const指针不能赋值给非const指针
a *p3=const_cast<a*>(p1) //正确,

利用const_cast<T*>(a)对p1常指针进行强制类型转换去除其const属性,使其可以赋值给非const指针

②dynamic_cast<T*>(a)

其与c++的动态多态性有关。

c++中通过把基类函数设置为虚函数来实现动态多态性,即可以通过定义基类指针指向不同继承类对象来调用其相关方法,前提是这种继承类对象的相关方法得在基类中声明为虚函数,否则用基类指针无法直接调用。 这时候就需要获得这种继承类对象的类型,通过dynamic_cast<T*>(a)来强制转换其指针类型从而调用其特有方法

calss A
{
//code
};
class B:public A
{
//code
};
class C:public B
{
//code
};
int main()
{
A *p1=new C;
C *p2=dynamic_cast<C*>(p1); //正确,安全p2为C类型的指针
B *p3=dynamic_cast<B*>(p1); //错误,不安全p3为空指针
return 0;
}

通过p2指针就可以调用c类型特有的方法。

dynamic_cast<T*>(a)其是通过对类名称通过字符串比较来实现的,其在继承中所处的层次越深,其字符串比较的次数就越多(为了找到对应类名称),需要花费很大时间,不如不用直接定义对应类型的指针;

③reinterpret_cast<T*>(a)

它用于不同类类型指针之间的转换;

class A
{
.....
}
class B
{
......
}
int main()
{
A *p1=new A;
B *p2=reinterpret_cast<B*>(A);
return 0;
}

因为A与B是不同的两个类型,其具有不同的内存储存形式,强行对其转换可能会发生内存扩张或内存截断。

④static_cast<*T>(a)

**总结:**由上述可得在程序中使用强制类型转换会带来一系列安全问题,且不易发觉因此在程序中尽量少使用强制类型转换。

改善c++程序的150个建议(读后总结)-------10-11的更多相关文章

  1. 编写高质量代码_改善C++程序的150个建议 读书笔记

    这几天看了下这本书<编写高质量代码_改善C++程序的150个建议>,觉的蛮有收获的,再次记录下自己以前不清晰的知识点,以供学习. 编写符合标准的main函数 C语言标准规定了main函数的 ...

  2. 改善c++程序的150个建议(读后总结)-------19-26

    19. 明白在c++中如何使用c c++可以兼容c的绝大部分代码,但是还是有一部分不能兼容. c语言的编译器在调用函数时会把函数翻译成 : "_函数名",例如: int nasa( ...

  3. 改善c++程序的150个建议(读后总结)-------12-18

    12.优先使用前置操作符 #include <iostream> using namespace std; class A { private: int num; public: A op ...

  4. 改善c++程序的150个建议(读后总结)-------0-9

    0. 不要让main 函数返回 void 入口函数main()返回类型应该为 int, 即程序结束时return 0 表示程序正常返回,函数结束时 return -1 值表示程序异常返回, 如果不显式 ...

  5. 改善c++程序的150个建议(读后总结)-------27-35

    27. 区分内存分配的方式 c++中内存分为5个不同的区 ①栈区 栈是一种特殊的数据结构,其存取数据特点为(先进后出,后进先出).栈区中主要用于存储一些函数的入口地址,函数调用时的实参值以及局部变量. ...

  6. 改善C++ 程序的150个建议学习之建议7:时刻提防内存溢出

    作为一个程序员,对内存溢出问题肯定不陌生,它已经是软件开发历史上存在了近40年的大难题.在内存空间中,当要表示的数据超出了计算机为该数据分配的空 间范围时,就产生了溢出,而溢出的多余数据则可以作为指令 ...

  7. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

  8. 改善java程序的151个建议

    <编写高质量代码-改善java程序的151个建议> --秦小波 第一章.开发中通用的方法和准则 1.不要在常量和变量中出现易混淆的字母 long a=0l; --> long a=0 ...

  9. 编写高质量代码改善java程序的151个建议——导航开篇

    2014-05-16 09:08 by Jeff Li 前言 系列文章:[传送门] 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,慘不忍睹是吧.确实 ...

随机推荐

  1. Python深入:setuptools进阶

    作者:gqtcgq 来源:CSDN 原文:https://blog.csdn.net/gqtcgq/article/details/49519685 Setuptools是Python Distuti ...

  2. Spring(一):Spring概述及相关概念

    Spring简介 Spring主要作用是用来解耦,降低代码之间的耦合度.根据功能的不同,可以将系统的代码分为主业务逻辑与系统服务逻辑. 主业务逻辑之间代码联系紧密,相互调用较多,复用性相对较低: 系统 ...

  3. P1423_小玉在游泳(JAVA语言)

    题目描述 小玉开心的在游泳,可是她很快难过的发现,自己的力气不够,游泳好累哦. 已知小玉第一步能游2米,可是随着越来越累,力气越来越小, 她接下来的每一步都只能游出上一步距离的98%. 现在小玉想知道 ...

  4. 前端-CS-04

    一:DOM(文档对象模型) document 简写DOM 1.DOM中定义变量用 var  如下截图中:定义demo变量 2.取一个input输入框中的值的方法: 1)先如1中,在dom中顶一个一个变 ...

  5. Android Studio 之 CheckBox

    •任务 •基本用法 CheckBox,复选框,即可以同时选中多个选项. 从网上找了三个图标,分别命名为 apple.jpg , banana.jpg , oranges.jpg 放置在了 drawab ...

  6. Nacos 2.0 正式发布,性能提升了 10 倍!!

    前不久,在3月20号,Nacos 2.0.0 正式发布了!我简单看了下官方的介绍,可能nacos未来逐渐会成为各大公司作为服务治理和配置中心的主要中间件. Nacos 简介:一个更易于构建云原生应用的 ...

  7. 一文带你剖析LiteOS互斥锁Mutex源代码

    摘要:多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的临界资源,只能被独占使用.LiteOS使用互斥锁来避免这种冲突,互斥锁是一种特殊的二值性信号量,用于实现对临界资源的独占 ...

  8. 【近取 key】NABCD分析

    项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-NABCD分析 我在这个课程的目标是 提升工程能力和团队意识,熟悉软件开发的流程 这个作 ...

  9. Markdown 数学公式一览

    Typora--数学公式 1. 分数\平方\下标 算式 markdown \(\frac{7x_1}{1+y_{3}^2}\) \frac{7x_1}{1+y_{3}^2} 2. 省略号 省略号 ma ...

  10. Json文件转换为Excel文件!涉及读文件,时间戳转化,写文档

    一. 思路 今天接到个小任务,让把json文件转换成excel文件,按照列展开. 思路:既然json已经都已经是现成的,那直接将json文件做读操作,在通过不同的key,找到对应的信息,在存到单元格中 ...