码迷,mamicode.com
首页 > 编程语言 > 详细

C++ Primer 学习笔记_15_从C到C++(1)--bool类型、const限定符、const与#define、结构体内存对齐

时间:2015-09-30 16:34:20      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:c++ primer   c++   c语言   

欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢技术分享


一、bool类型(C语言没有)
1、逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC++中为1个字节。
2、声明方式:bool result;
    result=true;
3、可以当作整数用(true一般为1false0
4、把其它类型的值转换为布尔值时,非零值转换为true,零值转换为false
5、示例
#include <iostream>
using namespace std;
int main(void)
{
 bool result;
 //result = true;
 result = 100;
 cout << result << endl;
 return 0;
}
运行结果:
1


二、const限定符
1、const给字面常量起个名字(标识符),这个标识符就称为标识符常量;因为标识符常量的声明和使用形式很像变量,所以也称常变量

2、定义的一般形式
(1)const 数据类型 常量名=常量值;
(2)数据类型 const 常量名=常量值;

3、注意事项:
(1)常变量在定义时必须初始化
(2)常变量初始化之后,不允许再被赋值

4、示例
#include <iostream>
using namespace std;
int main(void)
{
 //const int a;	 Error,常量必须初始化
 const int a = 100;
 //a = 200;	 Error,常量不能重新被赋值
 int b = 22;
 const int * p;	 //const在*左边,表示*p为常量,经由*p不能更改指针所指向的内容
 p = &b;
 //*p = 200;	 Error,常量不能重新被赋值
 //int * const p2;	 Error,p2为常量,常量必须初始化
 int * const p2 = &b;	//const在*右边,表示p2为常量
 //int c =100;
 //p2 = &c;	 Error,常量不能重新被赋值
 *p2 = 200;
 cout << b << endl;
 return 0;
}
运行结果:
200


三、const(C++)与#define(C语言)
1、const定义的常量与#define定义的符号常量的区别
(1)const定义的常量有类型,而#define定义的没有类型,编译可以对前者进行类型安全检查,而后者仅仅只是做简单替换
(2)const定义的常量在编译时分配内存,而#define定义的常量是在预编译时进行替换,不分配内存。
(3)作用域不同,const定义的常变量的作用域为该变量的作用域范围。而#define定义的常量作用域为它的定义点到程序结束当然可以在某个地方用#undef取消

2、定义常量还可以用enum,C++推荐尽量用constenum替换#define定义常量
    此外,定义常量还可以用enum,在c++ 中尽量用const、enum替换#define定义常量,用inline 替换带参数的宏定义;但 #define 在底层编程中是必不可少的,下面举个例子:
#include<iostream>
using namespace std;

#define STR(a) #a
#define CAT(a,b) a##b

int main(void)
{
    int xy = 100;
    cout << STR(ABCD) << endl; // #ABCD => "ABCD"  //表示对a加上双引号,一个#表示那个位置用宏参数作为字符串代替
    cout << CAT(x, y) << endl; // x##y => xy  //表示x连接y,两个##意思就是将##两端的字符串拼接起来

    return 0;
}

3、#define定义的常量,容易产生副作用。

//Effective C++ 3rd的一个例子。
#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))
int a = 5;
int b = 0;
CALL_WITH_MAX(++a, b);  //a被累加二次
CALL_WITH_MAX(++a, b+10);  //a被累加一次

在这里,调用f之前,a的递增次数竟然取决于“它被拿来和谁比较


4、定义常量还可以用enum,尽量用constenum替换#define定义常量。



四、结构体内存对齐

首先重新回顾一下关于类/对象大小的计算原则:

        32位      64位
char      1       1
int       4      大多数4,少数8
long      4       8
float     4       4
double    8       8
指针       4       8(和long一样)
注意:指针不管是任何类型都是和long一样,double *也是4。

1、什么是内存对齐
(1)编译器为每个“数据单元”按排在某个合适的位置上。
(2)CC++语言非常灵活,它允许你干涉“内存对齐”

2、为什么要对齐
  性能原因:在对齐的地址上访问数据快。

3、如何对齐——对齐规则
(1)第一个数据成员放在offset为0的位置第一个成员存放的地址就是结构体的地址)
(2)默认其它成员对齐至min(sizeof(member),#pragma pack所指定的值)的整数倍。(右键属性可以看到
win32 可选的有1, 2, 4, 8, 16
linux 32 可选的有1, 2, 4
大于最大值则为默认,在win中默认值为8,linux默认值为4
(3)整个结构体也要对齐,结构体总大小对齐至各个成员中最大对齐数的整数倍

4、示例
(1)在win中默认值为8
#include <iostream>
using namespace std;
#include <stdio.h>

struct Test
{
 char a;
 double b;
};

int main(void)
{
 cout<<sizeof(Test)<<endl;
 return 0;
}
运行结果:
16

(2)
#include <iostream>
using namespace std;
#include <stdio.h>

#pragma pack(2)
struct Test
{
 char a;
 double b;
 char c;
};
#pragma pack()

//第一个成员与结构体变量的偏移量为0
//其它成员要对齐到某个数字(对齐数)的整倍数的地址
//对齐数取编译器预设的一个对齐整数与该成员大小的较小值
//结构体总大小为最大对齐数的整数倍

int main(void)
{
 Test test;
 //&test == &test.a;
 char *p= (char*)&test;
 //cout<<p<<endl;
 printf("p=%p\n", p);
 p = &test.a;
 printf("p=%p\n", p);

 cout<<sizeof(Test)<<endl;
 return 0;
}
运行结果:
p=0019568
p=0019568
12

(3)在linux下面默认是4
修改代码部分:
#pragma pack(4)
运行结果:
16

(4)
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

struct A
{
    long a1;
    short a2;
    int a3;
    int* a4;
};

int main()
{
    cout << sizeof(A) << endl;
}

(5)
#include <stdint.h>
#include <stdio.h>

union X
{
    int32_t a;
    struct
    {
        int16_t b;
        int16_t c;
    };
};

int main()
{
    X x;
    x.a = 0x20150810;
    printf("%x,%x\n", x.b, x.c);
    return 0;
}



参考:

C++ primer 第四版

C++ primer 第五版



版权声明:本文为博主原创文章,未经博主允许不得转载。

C++ Primer 学习笔记_15_从C到C++(1)--bool类型、const限定符、const与#define、结构体内存对齐

标签:c++ primer   c++   c语言   

原文地址:http://blog.csdn.net/keyyuanxin/article/details/48829087

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!