19-#pragma
来源:互联网 发布:ip地址和端口是什么 编辑:程序博客网 时间:2024/05/16 08:29
#pragma预处理
#pragma是编译器指示字,用于指示编译器完成一些特定的动作
#pragma所定义的很多指示字是编译器和操作系统所独有的
#pragma在不同的编译器间是不可移植的
预处理器将忽略它不认识的#pragma指令
两个不同的编译器可能以两种不同的方式解释同一条#pragma指令
一般用法:
#pragma parameter
注:不同的parameter参数语法和意义各不相同
#pragma message
message参数在大多数的编译器中都有相似的实现
message参数在编译时输出消息到编译输出窗口中
message可用于代码的版本控制
注意:message是VC特有的编译器指示字,GCC中将其忽略;
#include <stdio.h>
/* #define ANDROID23 1 */
#if defined(ANDROID20)
#pragma message("Compile Android SDK 2.0...")
#define VERSION "Android 2.0"
#elif defined(ANDROID23)
#pragma message("Compile Android SDK 2.3...")
#define VERSION "Android 2.3"
#elif defined(ANDROID40)
#pragma message("Compile Android SDK 4.0...")
#define VERSION "Android 4.0"
#else
#error Compile Version is not provided!
#endif
int main() {
printf("%s\n", VERSION);
return 0;
}
#pragma pack
内存对齐
什么是内存对齐?
不同类型的数据在内存中按照一定的规则排列;而不是顺序的一个挨一个的排放,这就是对齐;
任何变量的地址必须是P的整数倍.这个规则叫做//数据对齐.
P取:#pragma pack(n) 指定的字节数(2/4/8/...)和这个变量自身大小二者中的最小值;
数据对齐会造成结构体内部不同子变量之间有空隙.
一个结构体变量的大小必须是P的整数倍).这个规则叫//数据补齐.
P取:#pragma pack(n) 指定的字节数(2/4/8/...)和结构体中最大的子变量二者中的最小值;
#pragma pack() 默认是4字节
这种补齐可能造成结构体在最后多占用一些浪费的字节.
"结构体中子变量的顺序会影响结构体的大小.
占用空间小的子变量写前边可以节约内存空间.
struct test1{
char c1; // 1
short s; // 2
char c2; // 1
int i; // 4
}
struct test2{
char c1; // 1
char c2; // 1
short s; // 2
int i; // 4
}
test1和test2两种类型所占用的内存空间是否相同?
为什么需要内存对齐?
CPU对内存的读取是不连续的,而是分成块读取的,块的大小值能是1,2,4,8,16字节;
当读取操作的数据未对齐,则需要两次总线周期来访问内存,因此性能会大打折扣;
某些硬件平台只能从规定的地址处取某些特定类型的数据,否则抛出硬件异常;
#pragma pack能够改变编译器的默认对齐方式
#pragma pack(2) //指定以2字节对齐
#pragma pack(4) //指定以4字节对齐
#pragma pack() //指定以默认字节(4)对齐
#include <stdio.h>
struct test1{
char c1;
short s;
char c2;
int i;
}; //12
struct test2{
char c1;
char c2;
short s;
int i;
}; //8
int main() {
printf("%d, %d\n", sizeof(struct test1), sizeof(struct test2)); //12, 8
return 0;
}
#include <stdio.h>
#pragma pack(2)
struct test1{
char c1;
short s;
char c2;
int i;
}; // 10
struct test2{
char c1;
char c2;
short s;
int i;
}; // 8
#pragma pack()
int main() {
printf("%d, %d\n", sizeof(struct test1), sizeof(struct test2)); // 10, 8
return 0;
}
struct占用内存大小
每一个成员起始与0偏移处;
每一个成员按其类型大小和指定对齐参数n中较小的一个进行对齐;
偏移地址和成员占用大小均需对齐;
结构体成员的对齐参数为其所有成员使用的对齐参数最大值;
结构体总长度必须为所有对齐参数的整数倍;
#include <stdio.h>
#pragma pack(8)
#pragma pack(4)
/* #pragma pack(2) */
struct S1 {
short a; // 2
long b; // 8
};
struct S2 {
char c; // 1
struct S1 d; // 2+8
double e; // 8
};
#pragma pack()
int main() {
struct S1 s1;
struct S2 s2;
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
printf("%p, %p\n", &(s1.a), &(s1.b));
printf("%p, %p, %p\n", &(s2.c), &(s2.d), &(s2.e));
printf("%p, %p\n", &(s2.d.a), &(s2.d.b));
return 0;
}
#pragma是编译器指示字,用于指示编译器完成一些特定的动作
#pragma所定义的很多指示字是编译器和操作系统所独有的
#pragma在不同的编译器间是不可移植的
预处理器将忽略它不认识的#pragma指令
两个不同的编译器可能以两种不同的方式解释同一条#pragma指令
一般用法:
#pragma parameter
注:不同的parameter参数语法和意义各不相同
#pragma message
message参数在大多数的编译器中都有相似的实现
message参数在编译时输出消息到编译输出窗口中
message可用于代码的版本控制
注意:message是VC特有的编译器指示字,GCC中将其忽略;
#include <stdio.h>
/* #define ANDROID23 1 */
#if defined(ANDROID20)
#pragma message("Compile Android SDK 2.0...")
#define VERSION "Android 2.0"
#elif defined(ANDROID23)
#pragma message("Compile Android SDK 2.3...")
#define VERSION "Android 2.3"
#elif defined(ANDROID40)
#pragma message("Compile Android SDK 4.0...")
#define VERSION "Android 4.0"
#else
#error Compile Version is not provided!
#endif
int main() {
printf("%s\n", VERSION);
return 0;
}
#pragma pack
内存对齐
什么是内存对齐?
不同类型的数据在内存中按照一定的规则排列;而不是顺序的一个挨一个的排放,这就是对齐;
任何变量的地址必须是P的整数倍.这个规则叫做//数据对齐.
P取:#pragma pack(n) 指定的字节数(2/4/8/...)和这个变量自身大小二者中的最小值;
数据对齐会造成结构体内部不同子变量之间有空隙.
一个结构体变量的大小必须是P的整数倍).这个规则叫//数据补齐.
P取:#pragma pack(n) 指定的字节数(2/4/8/...)和结构体中最大的子变量二者中的最小值;
#pragma pack() 默认是4字节
这种补齐可能造成结构体在最后多占用一些浪费的字节.
"结构体中子变量的顺序会影响结构体的大小.
占用空间小的子变量写前边可以节约内存空间.
struct test1{
char c1; // 1
short s; // 2
char c2; // 1
int i; // 4
}
struct test2{
char c1; // 1
char c2; // 1
short s; // 2
int i; // 4
}
test1和test2两种类型所占用的内存空间是否相同?
为什么需要内存对齐?
CPU对内存的读取是不连续的,而是分成块读取的,块的大小值能是1,2,4,8,16字节;
当读取操作的数据未对齐,则需要两次总线周期来访问内存,因此性能会大打折扣;
某些硬件平台只能从规定的地址处取某些特定类型的数据,否则抛出硬件异常;
#pragma pack能够改变编译器的默认对齐方式
#pragma pack(2) //指定以2字节对齐
#pragma pack(4) //指定以4字节对齐
#pragma pack() //指定以默认字节(4)对齐
#include <stdio.h>
struct test1{
char c1;
short s;
char c2;
int i;
}; //12
struct test2{
char c1;
char c2;
short s;
int i;
}; //8
int main() {
printf("%d, %d\n", sizeof(struct test1), sizeof(struct test2)); //12, 8
return 0;
}
#include <stdio.h>
#pragma pack(2)
struct test1{
char c1;
short s;
char c2;
int i;
}; // 10
struct test2{
char c1;
char c2;
short s;
int i;
}; // 8
#pragma pack()
int main() {
printf("%d, %d\n", sizeof(struct test1), sizeof(struct test2)); // 10, 8
return 0;
}
struct占用内存大小
每一个成员起始与0偏移处;
每一个成员按其类型大小和指定对齐参数n中较小的一个进行对齐;
偏移地址和成员占用大小均需对齐;
结构体成员的对齐参数为其所有成员使用的对齐参数最大值;
结构体总长度必须为所有对齐参数的整数倍;
#include <stdio.h>
#pragma pack(8)
#pragma pack(4)
/* #pragma pack(2) */
struct S1 {
short a; // 2
long b; // 8
};
struct S2 {
char c; // 1
struct S1 d; // 2+8
double e; // 8
};
#pragma pack()
int main() {
struct S1 s1;
struct S2 s2;
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
printf("%p, %p\n", &(s1.a), &(s1.b));
printf("%p, %p, %p\n", &(s2.c), &(s2.d), &(s2.e));
printf("%p, %p\n", &(s2.d.a), &(s2.d.b));
return 0;
}
0 0
- 19-#pragma
- #pragma
- Pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- ActivityManagerService的启动和ActivityManagerService对Activity堆栈的管理
- Struts2验证框架个性配置都正确但是不校验
- Android子线程中更新UI的3种方法
- http协议
- MySQL数据库查询数据库及各个表所占磁盘空间大小的方法
- 19-#pragma
- 错误代码: 2013 Lost connection to MySQL server during query
- Office 开发版本号与版本对应关系
- Java TCP socket 判断对方是否在线的方法
- linux入门基础——linux系统常用命令
- js返回日期串(如:yyyyMMddHHmmSS)
- 20-#_##
- hdu 1157 (1.3.7) Who's in the Middle
- Makefile交叉编译