1.结构体中的位字段(位域)
允许指定占用特定位数的结构成员
官方说法:
类和结构可包含比整型类型占用更少存储空间的成员,这些成员被指定为位域
语法:
declarator : constant-expression
注意:
1.其中declarator 是在程序中访问的成员的名称,它必须是整型类型(包括枚举类型)
2.常数表达式指定结构中成员所占据的位数,位数为 0 的未命名位域强制将下一个位域与下一个type 边界对齐,其中type 是成员的类型
拿了msdn上两个例子如下(->__->):
struct Date {
unsigned short nWeekDay : 3; // 0..7 (3 bits)
unsigned short nMonthDay : 6; // 0..31 (6 bits)
unsigned short nMonth : 5; // 0..12 (5 bits)
unsigned short nYear : 8; // 0..100 (8 bits)
};
这个Date结构在内存中的存储形式如下图所示:
基本数据类型是unsigned short,以2个字节为倍数对齐。像Date中的nMonth,在遇到两个字节剩余的字节无法容纳它时,给其分配一块新的2字节内存区域。
遇上包含长度为0的未命名字段,如下所示:
struct Date {
unsigned nWeekDay : 3; // 0..7 (3 bits)
unsigned nMonthDay : 6; // 0..31 (6 bits)
unsigned : 0; // Force alignment to next boundary.
unsigned nMonth : 5; // 0..12 (5 bits)
unsigned nYear : 8; // 0..100 (8 bits)
};
上面的注意中提到过:遇上这种既无名,长度也为0的字段,就是一个标识,强制你下一个元素开始的位域与一个新的基本类型边界对齐,这里基本数据类型是unsigned 4个字节,无符号的整形,所以这个Date在内存中的排布方式如下图所示
这里就是从左往右申请新的内存,并将数据沿边界对齐
引用下面这篇博客中的一个例子:
http://blog.csdn.net/zhangboyj/article/details/6201856
union{
struct{
unsigned short s1:3;
unsigned short s2:3;
unsigned short s3:3;
}x;
char c;
}v;
v.c=100;
cout<<v.x.s1<<endl;
cout<<v.x.s2<<endl;
cout<<v.x.s3<<endl;
/*
4
4
1(或者5)
*/
分析一下上面这个代码段:
咱们这个计算机是小端字节序,高位数据在低位内存位置,100 存储格式就是s1:01 s2:100 s3:100,其实可以把这看作自然存储。
本人机器输出是1(有时是5,那是因为前面那一位不确定,为1或0,101或者001),看你内存中驻留的是0还是1
总结一下:
位域的存在是基于比特位的,将一个字节中的bit位划分为几个不同的区域。
因为在计算机的存储中,有些信息没必要用到字节范畴的容量,比如说创建与某个硬件设备上的寄存器对应的数据结构,很可能需要的功能就是一个开关,只需要0和1两种状态,为了处理效率和节省内存,使用位域声明占1个bit位。这样可以使得几个不同的对象可以使用一个字节的二进制位域来表示
2.指针相关
这里只记录一些书上提到的需要注意的内容:
1.堆和栈:
堆(heap): 指的是自由存储区域,供分配内存用
栈(stack): 指的是已分配的值存储的区域,如运行中程序中的变量
2.new和delete必须合理使用
new和delete必须成对出现,申请过的内存没有经过delete释放,会导致内存泄露,即已分配的内存没被释放再也没法使用了,严重的会导致内存耗尽
不要尝试释放已经释放的内存块,会导致不确定的后果。(这种情况常常发生在你创建了两个2个指向同一个内存块的指针,然后没注意delete这两个相同的指针……就相当于释放已经释放的内存块)
3.C和C++内部都使用指针来处理数组
数组和指针基本等价
数组名被解释为其第一个元素的地址,对数组进行++,- -操作时候均是以数组基本元素类型为单位进行运算
4.使用标准库
我们一般在实际运用中,都是使用vector或array(C++11)来替代数组,应该熟悉使用他们的成员函数
有错误还请指出,谢谢