2015-11-25 #pragma预处理分析听课笔记

1、#pragma是编译器指示字,用于指示编译器完成一些特定的动作。

2、#pragma定义的很多指示字都是编译器和系统特有的。

3、#pragma在不同的编译器之间是不可移植的。

3.1  预处理器将忽略它所不认识的#pragma指令

3.2两个不同的编译器可能会以两种不同的方式解释同一条#pragma指令,这是由编译器厂商决定的。

4、一般用法: #pragma   parameter  //不同的parameter参数语法和意义各不相同。

4.1   #pragma  message

4.1.1  message参数在大多数的编译器中都有相似的实现。//注意:message参数是VC编译器特有的,GCC是没有的。

4.1.2  message参数在编译时输出消息到编译输出窗口中。

4.1.3  message参数可以用于版本控制。

4.1.4 使用实例:

 1 #include <stdio.h>
 2
 3 #define ANDROID20
 4
 5 #if defined(ANDROID20)
 6     #pragma message("Compile Android SDK 2.0...")
 7     #define VERSION "Android 2.0"
 8 #elif defined(ANDROID23)
 9     #pragma message("Compile Android SDK 2.3...")
10     #define VERSION "Android 2.3"
11 #elif defined(ANDROID40)
12     #pragma message("Compile Android SDK 4.0...")
13     #define VERSION "Android 4.0"
14 #else
15     #error Compile Version is not provided!
16 #endif
17
18 int main()
19 {
20     printf("%s\n", VERSION);
21
22     return 0;
23 }

在VC的环境下,编译时在输出窗口将显示我们设定的版本信息。

4.2 #pragma  pack

4.2.1  关于内存对齐

不同类型的数据在内存中按照一定的规则排列,而不是顺序的一个接一个的排放,这就是内存对齐。

struct  T1

{

char c1;

short s1;

char c2;

int i1;

};

struct  T2

{

char c1;

char c2;

short s1;

int i1;

}

两者所占的空间大小一样吗?我们在VS下写了一个测试代码如下:

 1 #include<stdio.h>
 2
 3 struct  T1
 4
 5 {
 6
 7 char c1;
 8
 9 short s1;
10
11 char c2;
12
13 int i1;
14
15 };
16
17
18 struct  T2
19
20 {
21
22 char c1;
23
24 char c2;
25
26 short s1;
27
28 int i1;
29
30 };
31
32
33 void main()
34 {
35 printf("%d,%d",sizeof(struct T1),sizeof(struct T2));
36 getchar();
37 }

测试结果为:12,8

4.2.2  为什么要内存对齐?

a,CPU读取内存时不是连续读取的而是分块读取的,而块的大小只能是1,2,4,8,16字节。

b,当读取操作的数据未对齐的时候,则需要两次总线周期来访问内存,因此性能会大打折扣。

eg:

struct  T

{

char c;

short s;

}

假如不进行内存对齐的话,则需要先读出c,然后读s,假如进行了4字节内存对齐的话,则可以一次性的将c和s读取出来,这样将大大节省读写时间。

c,某些硬件平台只能从规定的地址处取某些特定类型的数据,否则将抛出硬件异常。例如某些硬件只能进行偶地址访问。

4.2.3#pragma  pack能够改变编译器默认的对齐方式。

实例程序如下:

 1 #include <stdio.h>
 2
 3 #pragma pack(4)
 4
 5 struct S1
 6 {
 7     short a;
 8     long b;
 9 };
10 #pragma pack()
11
12
13 #pragma pack(8)
14 struct S2
15 {
16     char c;
17     struct S1 d;
18     double e;
19 };
20
21 #pragma pack()
22
23 int main()
24 {
25     struct S2 s2;
26
27     printf("%d\n", sizeof(struct S1));
28     printf("%d\n", sizeof(struct S2));
29     printf("%d\n", (int)&(s2.d) - (int)&(s2.c));
30     getchar();
31
32     return 0;
33 }

运行结果是8,24,4
第三行用于告诉编译器以下内容,进行4字节对齐,

第十三行用于告诉编译器以下内容,进行8字节对齐。编译器默认的对齐方式一般是4字节对齐方式。

具体结果为什么是这样,我们先不说。

4.2.4 关于struct所占用的内存大小的计算:

个人总结的几点:

1、结构体的第一个成员的地址偏移量(offset)为0;

2、在没有用#pragma pack(n)指令指定对齐参数n时,对齐参数n=结构体中占用内存最大的那个成员变量所占内存的大小m;在用#pragma pack(n)指令指定对齐参数n后,系统将min(n,m)作为对齐参数。

3、每个成员变量都要对齐,如果对齐参数为n,该成员变量所占字节数为p,则该成员变量的偏移地址%min(n,p)=0。也就是最小化长度规则。

4、结构体总大小: 对齐后的长度必须是对齐参数n的整数倍。

5、补充:如果结构体A中还有结构体B,那么B的对齐方式是选它里面最长的成员的对齐方式
所以计算结构体大小要走三步,首先确定是当前程序按照几对齐,接着计算每个结构体变量的大小和偏移,最后计算结构体总大小。

时间: 2024-10-02 02:04:40

2015-11-25 #pragma预处理分析听课笔记的相关文章

http://blog.rainy.im/2015/11/25/extract-color-themes-from-images/

许多从自然场景中拍摄的图像,其色彩分布上会给人一种和谐.一致的感觉:反过来,在许多界面设计应用中,我们也希望选择的颜色可以达到这样的效果,但对一般人来说却并不那么容易,这属于色彩心理学的范畴(当然不是指某些伪神棍所谓的那种).从彩色图像中提取其中的主题颜色,不仅可以用于色彩设计(参考网站:Design Seeds),也可用于图像分类.搜索.识别等,本文分别总结并实现图像主题颜色提取的几种算法,包括颜色量化法(Color Quantization).聚类(Clustering)和颜色建模的方法(颜

0801-----C++Primer听课笔记----------C++11新特性 function 和 bind 的简单使用

1.function 和 函数指针 1.1 function有函数指针的功能,但是使用起来明显比函数指针更加灵活和方便. 1.2 函数指针和function的用法实例. 1.2.1 函数指针首先要清楚函数指针的类型,如void (*)(int, char)等,然后声明一函数指针变量直接调用即可. #include <iostream> using namespace std; /* * 函数指针的用法 */ void test(int i,double j){ cout << i

老男孩培训视频听课笔记一(在51cto上听的)

学习Linux的系统环境准备     1.系统选择centos 5.8/centos 6.4     2.环境:VMware workstation win7 vim 8.0 虚拟机软件选择与实践安装VMware软件    安装VMware workstation 8.0 win7-VMware上新建虚拟机及涉及技术讲解    创建虚拟机:     名字:mode vim-cs5.8     CPU:1-1 内存 128M--5.8 6.4-256M     硬盘:虚拟的硬盘 6G 获得cent

听课笔记1:等价类划分

听课笔记1:等价类划分 等价类可以分为两类 有效等价类和无效等价类. 无效的等价类是指不合理,无意义或者不符合规格说明书的输入构成的集合.有效等价类反之. 等价类划分原则 一般的划分原则有 按区间划分 按数值划分 按数值集合划分 按限制条件或规则划分 细分等价类 等价类的划分就是对可能的输入的分类过程,至于分类的标准,就是根据可能的输入来确定.1)如果规格说明对输入有明确的说明则按照规格的说明来分类:2)对于数值的输入,按照区间划分是最自然的分类方法:3)对于非数值的输入,可以按照关注的特点来分

cs231n spring 2017 lecture9 听课笔记

参考<deeplearning.ai 卷积神经网络 Week 2 听课笔记>. 1. AlexNet(Krizhevsky et al. 2012),8层网络. 学会计算每一层的输出的shape:对于卷积层,输出的边长 =(输入的边长 - filter的边长)/ 步长 + 1,输出的通道数等于filter的数量.每个filter的通道数等于输入的通道数.卷积层的参数 = filter的长 * filter的宽 * 输入的通道数 * filter的数量.池化层没有需要学习的参数. 图中分成两个通

#pragma预处理命令

#pragma预处理命令 #pragma可以说是C++中最复杂的预处理指令了,下面是最常用的几个#pragma指令: #pragma comment(lib,"XXX.lib") 表示链接XXX.lib这个库,和在工程设置里写上XXX.lib的效果一样. #pragma comment(linker,"/ENTRY:main_function") 表示指定链接器选项/ENTRY:main_function #pragma once 表示这个文件只被包含一次 #pra

关于C++代码中的#pragma预处理指令

预处理指令是指在编译器编译代码时,提供按条件跳过源文件中的代码段(节).报告错误(错误信息以及行号)和警告条件,以及描绘源代码的不同区域的能力. 总是占用源代码中的单独一行,并且总是以 # 字符和预处理指令名称开头.# 字符的前面以及 # 字符与指令名称之间可以出现空白符. 下面是可用的预处理指令: #define 和 #undef,分别用于定义和取消定义条件编译符号. #if.#elif.#else 和 #endif,用于按条件跳过源代码中的节. #line,用于控制行号(在发布错误和警告信息

老男孩培训视频听课笔记九(在51cto上听的)--5.8 64bit 基础优化

定时清理clientmqueue目录垃圾文件防止占满磁盘空间: /var/spool/clientmqueue  --这个目录会自动创建很多的文件,可以用下面的命令来清理 find /var/spool/clientmqueue/ –type  f | xargs rm –fr mkdir /server/scripts –p vim del.sh: find /var/spool/clientmqueue/ –type  f | xargs rm –fr crontab -e */5 * *

PCB设计软件CadSoft Eagle Professional v7.5 Multilingual +DownStream Products 2015.11

PCB设计软件CadSoft Eagle Professional v7.5 Multilingual Win64 1CDCadSoft Eagle Professiona是一款简单易用的印刷电路板设计软件,其中包含原理图编辑器.PCB编辑 器和自动布线器三个模块,方便设计者更方便操作.CadSoft Eagle Professiona支持中文版 DownStream Products 2015.11 1CD业界领先的PCB后处理解决方案CadSoft.Eagle.Professional.v7