C++回顾之开篇(bool, const限定符,#define, 结构内存对齐)
2014-01-25 09:45
295 查看
C++知识点很多,要问它的坑有多深,试一试便知。为了不使自己掌握的技能随时光流逝逐渐褪色,还是需要多多回顾以前的知识点,留下学习的痕迹,方便后期有需要进行回溯.
这一节是开篇,主要讲述以下内容:
1 bool类型
2 const限定符的使用
3 const限定符与#define的区别
4 结构体内存对齐原则
先谈bool型,bool型是C++在C的基础上新增的逻辑类型,它的值为true or false,它的存储字节在不同的编译器可能不同,在vc++中占1字节,可以通过sizeof()来查看不同编译器下具体的数值。它也可以表示数值,非0时为1,其它为0,如下:
const限定符的使用:
顾名思义,const是用于修饰标识变量的, 被const修饰的变量其值将不能被更改,所以可以称为标识符常量或者称为常变量,它的定义格式有以下两种:
const 数据类型 常量名 = 常量值;
数据类型 const 常量名 = 常量值;
注意事项:常变量在声明时必须初始化,且在初始化后,不允许再赋值。见如下例子:
const与#define宏的区别
共同点是两者均可以用于定义常量,这里着重看二者之间的区别:
(1) 数据类型
const定义的常量是有数据类型的,而#define定义的常量是没有数据类型之分的,所以编译器对二者的处理不相同,编译器对const定义的常量会进行类型的检查,对#define只作简单的替换。
(2) 内存管理
const定义的常量是在编译时分配内存,#define定义的常量是在预编译时进行替换,不进行内存的分配
(3) 作用域
const定义的常量其作用域就是该变量本身的作用域,而#define所定义的常量作用域是由#define定义的起始点至程序结束,也可以在某个地方用#undef取消。
在C++中,定义常量除了使用const,外,还可以使用枚举enum, 在C++中提供尽量使用const和enum来代替C的#define
最后,来看看结构体的内存对齐原则。
关于为什么结构体要进行内存对齐,原因只在于性能上的原因,CPU在对齐的地址上访问数据更快。
(1) 结构体第一个成员与结构体的偏移量为0
(2) 其它成员要对齐到某个数字(对齐数)的整数倍地址
(3) 对齐数取编译器预设的一个对齐数与该成员大小的较小者
(4) 结构体总大小为最大对齐数的整数倍
#include <iostream>
#include <stdio.h>
using namespace std;
//这里是对齐数的设定,对齐数的值与编译器有关,可以设定,默认是4,这里改成2。
//在linux g++中,编译器对齐整数只能设到1,2,4,设到8是没有用的,还是4
#pragma pack(2)
struct Test
{
char a;
double b;
char c;
};
#pragma pack()
int main(void)
{
Test test;
//&test = &test.a
char *p = (char *)&test;
// cout << p <<endl;
printf("p = %p\n",p);
p = &test.a;
// cout << p << endl;
printf("p = %p\n",p);
cout << sizeof(Test) << endl; //output:12bytes.
return 0;
}
总结:关于bool类型、const限定符使用、const与#define定义常变量的区别、结构体内存对齐的规则。
这一节是开篇,主要讲述以下内容:
1 bool类型
2 const限定符的使用
3 const限定符与#define的区别
4 结构体内存对齐原则
先谈bool型,bool型是C++在C的基础上新增的逻辑类型,它的值为true or false,它的存储字节在不同的编译器可能不同,在vc++中占1字节,可以通过sizeof()来查看不同编译器下具体的数值。它也可以表示数值,非0时为1,其它为0,如下:
bool a; a = 100; //编译器将int型 --> bool型,要进行截断,因为bool只占1字节 cout << a << endl; //output: 1 bool a; a = 100; cout << a << endl; //output: 1 a = -1; cout << a << endl; //output: 1 a = 0; cout << a << endl; //output :0
const限定符的使用:
顾名思义,const是用于修饰标识变量的, 被const修饰的变量其值将不能被更改,所以可以称为标识符常量或者称为常变量,它的定义格式有以下两种:
const 数据类型 常量名 = 常量值;
数据类型 const 常量名 = 常量值;
注意事项:常变量在声明时必须初始化,且在初始化后,不允许再赋值。见如下例子:
//const int a; //Error, a没有被初始化 const int a = 100; //right //a = 2; //Error,a不允许再赋值 int b = 22; const int *p; //right,*p是常量,const在*号左边,表示*p为常量, 经由*p不能更改p指针所指向的内容。 p = &b; //允许,因为p不是常量 //*p = 200; //Error, *p是常量,常量不允许重新赋值 //int *const p2;// Error, p2是常量,没初始化 int *const p2 = &b; //right. int c = 100; //p2 = &c; //Error, p2是常量,不允许修改 *p2 = 200; //允许,p2是常量,*p2是变量,可以经由p2修改指针所指向的值
const与#define宏的区别
共同点是两者均可以用于定义常量,这里着重看二者之间的区别:
(1) 数据类型
const定义的常量是有数据类型的,而#define定义的常量是没有数据类型之分的,所以编译器对二者的处理不相同,编译器对const定义的常量会进行类型的检查,对#define只作简单的替换。
(2) 内存管理
const定义的常量是在编译时分配内存,#define定义的常量是在预编译时进行替换,不进行内存的分配
(3) 作用域
const定义的常量其作用域就是该变量本身的作用域,而#define所定义的常量作用域是由#define定义的起始点至程序结束,也可以在某个地方用#undef取消。
在C++中,定义常量除了使用const,外,还可以使用枚举enum, 在C++中提供尽量使用const和enum来代替C的#define
最后,来看看结构体的内存对齐原则。
关于为什么结构体要进行内存对齐,原因只在于性能上的原因,CPU在对齐的地址上访问数据更快。
(1) 结构体第一个成员与结构体的偏移量为0
(2) 其它成员要对齐到某个数字(对齐数)的整数倍地址
(3) 对齐数取编译器预设的一个对齐数与该成员大小的较小者
(4) 结构体总大小为最大对齐数的整数倍
#include <iostream>
#include <stdio.h>
using namespace std;
//这里是对齐数的设定,对齐数的值与编译器有关,可以设定,默认是4,这里改成2。
//在linux g++中,编译器对齐整数只能设到1,2,4,设到8是没有用的,还是4
#pragma pack(2)
struct Test
{
char a;
double b;
char c;
};
#pragma pack()
int main(void)
{
Test test;
//&test = &test.a
char *p = (char *)&test;
// cout << p <<endl;
printf("p = %p\n",p);
p = &test.a;
// cout << p << endl;
printf("p = %p\n",p);
cout << sizeof(Test) << endl; //output:12bytes.
return 0;
}
总结:关于bool类型、const限定符使用、const与#define定义常变量的区别、结构体内存对齐的规则。
相关文章推荐
- C++回顾之开篇(bool, const限定符,#define, 结构内存对齐)
- C++学习笔记(二) bool const 和 #define 结构体内存对齐
- C++学习笔记2--函数重载 复杂的数据 内存对齐 指针数组 结构与指针 传值传址传引用 联合枚举类型别名
- 64位和32位平台下C/C++结构内存对齐
- c++内存中字节对齐问题详解
- C++对象内存分布详解(包括字节对齐和虚函数表)
- C/C++:内存字节对齐详解
- (转)c/c++内存对齐问题
- 回顾内存区:C语言C++的内存区是一样的。
- C++对象内存分布(包括字节对齐和虚函数表)
- C++中的内存对齐
- C\C++ 内存对齐
- C++ class实例的内存结构
- C++结构变量数据对齐问题
- C++ 内存对齐
- [C++]字节对齐与结构体大小
- [C++]字节对齐与结构体大小
- 结构体成员在内存中分配与对齐
- C/C++ 内存对齐规则
- 关于C++中的大小端、位段(惑位域)和内存对齐