6.assert()
断言,是宏,而非函数。assert 宏的原型定义在 <assert.h>
(C)、<cassert>
(C++)中,其作用是如果它的条件返回错误,则终止程序执行。可以通过定义 NDEBUG
来关闭 assert,但是需要在源代码的开头,include <assert.h>
之前。
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
用法总结与注意事项:
- 在函数开始处检验传入参数的合法性;
- 每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败;
- 不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题,错误: assert(i++ < 100);
- assert和后面的语句应空一行,以形成逻辑和视觉上的一致感;
- 有的地方,assert不能代替条件过滤;
7.sizeof()
- sizeof 对数组,得到整个数组所占空间大小。
- sizeof 对指针,得到指针本身所占空间大小。
- sizeof对对象,得到对象所占空间大小。
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<float > v1;
for(int i = 0;i < 3;i++)
{
v1.push_back(i);
}
cout<<sizeof(v1.front())<<endl;
cout<<sizeof(v1)<<endl;
return 0;
}
输出结果:
4
12
8.位域
Bit mode: 2; // mode 占 2 位
类可以将其(非静态)数据成员定义为位域(bit-field),在一个位域中含有一定数量的二进制位。当一个程序需要向其他程序或硬件设备传递二进制数据时,通常会用到位域。位域的作用主要是节省内存资源,使数据结构更紧凑。
- 位域在内存中的布局是与机器有关的
- 位域的类型必须是整型或枚举类型,带符号类型中的位域的行为将因具体实现而定
- 取地址运算符(&)不能作用于位域,任何指针都无法指向类的位域
- 一个位域必须存储在同一个字节中,不能跨两个字节,故位域的长度不能大于一个字节的长度。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:
struct BitField { unsigned int a:4; //占用4个二进制位; unsigned int :0; //空位域,自动置0; unsigned int b:4; //占用4个二进制位,从下一个存储单元开始存放; unsigned int c:4; //占用4个二进制位; unsigned int d:5; //占用5个二进制位,剩余的4个bit不够存储4个bit的数据,从下一个存储单元开始存放; unsigned int :0; //空位域,自动置0; unsigned int e:4; //占用4个二进制位,从这个存储单元开始存放; };
- 取地址操作符&不能应用在位域字段上;
- 位域字段不能是类的静态成员;
- 位域字段在内存中的位置是按照从低位向高位的顺序放置的;
struct BitField { unsigned char a:2; //最低位; unsigned char b:3; unsigned char c:3; //最高位; }; union Union { struct BitField bf; unsigned int n; }; union Union ubf; ubf.n = 0; //初始化; ubf.bf.a = 0; //二进制为: 000 ubf.bf.b = 0; //二进制为: 000 ubf.bf.c = 1; //二进制为: 001 printf("ubf.bf.n = %u\n", ubf.n);
关于位域更多内容,参考博客:https://www.cnblogs.com/pure/archive/2013/04/22/3034818.html
关于assert()、sizeof()、位域的定义参考博客:https://github.com/huihut/interview