L19#pragma
来源:互联网 发布:sql注入攻击1r1 编辑:程序博客网 时间:2024/06/06 04:17
L18: #pragma
- #pragma是编译器指示字,用于指示编译器完成一些特定的工作
- #pragma所定义的很多指示字是编译器和操作系统特有的
- #pragma在不同的编译器之间是不可移植的
#
- 预处指令理器将忽略它不认识的#pragma
- 两个不同的编译器可能以不同的方式解释同一条#pragma指令
- 一般用法:
#pragma parameter
- 不同parameter参数语法和意义各不相同
##
#include <stdio.h> #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; }
输出相应的信息,在VC中可以输出信息
gcc下编译时没有输出信息
#pragma pack 内存对齐
不同类型的数据在内存中按照一定的规则排列
需要内存对齐的原因
- cpu对内存的读取不是连续的,是分块的,块的大小是1,2,4,8,16字节
- 读取数据未对齐时需要两次总线周期访问内存,性能降低
- 导致一些硬件问题
规则:
- 第一个成员起始于0偏移处
- 每个成员按其类型对齐参数(char:1 short 2等)和指定对齐参数n(默认4)中较小的一个进行对齐
- 偏移地址和成员占用大小均需对齐
- 结构体成员的对齐参数为其所有成员使用的对齐参数的最大值
- 数据存放的起始地址能够除尽对齐参数
- 结构体总长度必须为所有对齐参数的整数倍
//默认4字节对齐时 VC linux下是一样的 #include<stdio.h> struct test { char c1; short s; char c2; int i; }; int main() { printf("%d\n",sizeof(struct test)); //输出12 VC编译环境 return 0; }
|数据对齐参数|指定对其参数| 变量 |起始地址|大小|实际存储| |1 | 4 | C1 | 0 |1 |X* | |2 | 4 | S | 2 |2 |XX | |1 | 4 | C2 | 4 |1 |X*** | |4 | 4 | i | 8 |4 |XXXX | *代表填空,X代表具体数据
面试题
#include <stdio.h> #pragma pack(8)//gcc 下直接无视 还是按照4字节对齐 struct S1 { short a; //2 long b; //4 }; struct S2 { char c; struct S1 d; double e; }; #pragma pack() int main() { struct S2 s2; printf("%d\n", sizeof(struct S1)); //8(vc) //8(gcc) printf("%d\n", sizeof(struct S2)); //24(vc) //20(gcc) printf("%d\n", (int)&(s2.d) - (int)&(s2.c));//4(vc) //4(gcc) return 0; }
分析:
- S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
S2 中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是 按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空(要能整除对齐参数),从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节.
S1:8字节|数据对齐参数|指定对其参数| 变量 |起始地址|大小|实际存储 ||2 | 8 |short a | 0 |2 |XX** ||4 | 8 |long b | 4 |4 |XXXX |S2:24字节|1 | 8 |char c | 8 |1 |X*** ||4 | 8 | s1 d | 12 |8 |XXXXXXXX**** | |8 | 8 |double e | 24 |8 |XXXXXXXX | a bS1的内存布局:11**,1111, c S1.a S1.b dS2的内存布局:1***,11**,1111,****11111111
0 0
- L19#pragma
- #pragma
- Pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- #pragma
- SDCC Linux编译
- 使用委托(或匿名函数)求一个未知类型的数组最大值
- Thinking in Java 第二章
- 判断字符串中是否包含中文
- 安卓获得通讯录联系人
- L19#pragma
- poj 3250 Bad Hair Day (单调栈)
- 15HD_OJ——母牛的故事
- 5.2-2
- L20#和##使用
- 《战略管理》第一章<什么是战略管理>读书笔记
- L21指针基础
- 【资源分享】好用的网站
- L22数组基础