1.bool
bool result = true;
bool flag = false;
bool r = 100;
cout<<"value of result is : " <<result<<endl;
cout<<"value of flag is : " <<flag<<endl;
cout<<"value of r is : " <<r<<endl;
输出:1,0,1
总结: true为1,false为0,非0值为true,0为false
2.cons *问题
<p>//常量在定义时必须初始化,在初始化之后不允许被赋值
const int year = 2015;
//常量不能重新被赋值
//year = 2014; //错误</p><p> int a = 100;
int b = 200;
//const 在*左代表指针指向的变量(*p)是常量
const int *p; //第一种情形
p = &a;
//常量不能重新赋值
//*p = 200;</p><p> //const在*右边表示q为常量,q必须赋初值
int *const q = &b; //第二种情形
//不能给const的指针变量赋值
//q = &a;
cout<<*q<<endl;
//但是可以给q指向的内容赋值
*q = 300;
cout<<*q<<endl;</p><p> //这种和const int *s 一样的,即第一种情形
int const *s;
//*s = 400;
s = &b;</p>
3.宏定义
#include <iostream>
using namespace std;
#define STR(a) #a
#define CAT(a,b) a##b
#define M(a,b) a*b
void main()
{
int xy = 100;
cout<<STR(ABCD)<<endl;
cout<<CAT(x,y)<<endl;
cout<<M(3,4)<<endl;
}
输出ABCD,100,12
总结:
1) #表示转化为字符串,##表示连接,输出是字符串。
2)注意宏定义是有副作用的
关于宏定义的副作用,见下面的例子
#include <iostream>
using namespace std;
#define STR(a) #a
#define CAT(a,b) a##b
#define M(a,b) a*b
#define CALL_MAX(a,b) ((a) > (b) ? (a) : (b))
#define MAX(A,B) A>B ? 2*A : 2*B
void main()
{
int xy = 100;
cout<<STR(ABCD)<<endl;
cout<<CAT(x,y)<<endl;
cout<<M(3,4)<<endl;
int p = 5;
int q = 0;
cout<<"p = "<<p<<",q = "<<q<<endl;
cout<<"result of CALL_MAX is "<<CALL_MAX(++p,q)<<endl;
cout<<"p = "<<p<<",q = "<<q<<endl;
cout<<"result of CALL_MAX is "<<CALL_MAX(++p,q+10)<<endl;
cout<<"p = "<<p<<",q = "<<q<<endl;
int a=1,b=2,c=3,d=4,t;
t = MAX(a+b,c+d);
printf("%d\n",t);
}
CALL_MAX 这个宏定义一个函数来计算较大的数,但是我们来看运行结果!
第一次:开始p=5,p++之后,p的值为6,与0比取较大值为6,返回p++,则返回7,这个过程中p被加了2次
第二次:开始p=7,p++之后,p的值为8,与10(q+10)取较大值,返回10(q+10),这个过程中p只被加了1次!
问题来了,p被加的次数是不确定的,要看具体和谁来比较,这就是宏的副作用!
注意:宏是整体替换,MAX这个宏返回的是2*c+d的结果,所以等于10,不是我们认为的2(c+d)!
4.内存对齐
1)为什么要对齐
- 性能上的需要,在对齐的地址上访问数据比较快!
先来看看例子
<p>#include <iostream>
using namespace std;</p><p>struct TestStruct1
{
char ch; //内存位置: [0]
double d;//内存位置: [8]...[15]
};</p><p>struct TestStruct2
{
char ch1; //内存位置: [0]
char ch2; //内存位置: [2]
int i; //内存位置: [4]...[7]
};// 内存大小:sizeof(TestStruct2) = (1+1) + (1+1) + 4 = 8, (1+1)为1补齐1位
void main()
{
cout<<sizeof(TestStruct1)<<endl;
cout<<sizeof(TestStruct2)<<endl;
}</p>
输出:16,8
注意:这里的不是8+1和4+1+1,而是8和4的两倍.
结构体的大小是结构体中长度最大的数据类型的整数倍!
对齐规则:
1.数据成员对齐规则:struct, union的数据成员,第一个数据成员放在offset为0的地方,之后的数据成员的存储起始位置都是放在该数据成员大小的整数倍位置。如在32bit的机器上,int的大小为4,因此int存储的位置都是4的整数倍的位置开始存储。
2.结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小的整数倍开始存储。如 struct A 中包含 struct B, struct B 中包含数据成员 char, int, double,则 struct B 应该以sizeof(double)=8的整数倍为起始地址。
3.收尾工作的对齐规则:整个struct的大小,应该为最大数据成员大小的整数倍。
对齐数的设置:
工程->属性->C/C++->代码生成->结构体成员对齐:
修改为4之后,运行结果如下:
可以在运行时指定结构体的对齐数,如:pragma pack(4) 指定对齐数为4
这样结构体TestStruct1的长度就是12字节了!