第24课 #pragma使用分析
#pragma是C语言留给编译器厂商进行扩展用的。
这个关键字在不同的编译器之间也许是不能够移植的。
#pragma简介
#pragma message
#pragma message打印的消息并不代表代码有什么问题。
示例:
#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 ;
}
编译命令如下:
可见,在编译期间,预处理器处理#pragma message,并输出信息。
将上述程序用vc编译器进行编译,结果如下:
输出和gcc只有略微的差别。
bcc32的编译输出如下:
#pragma once
左边是通过判断宏是否已经定义的方式保证代码只被嵌入一次,预处理器还是处理了这个文件。而#pragma once 保证只处理这个要包含的文件一次。所有pragma once的效率会高一点。
工程中用的比较多的是ifndef方式,而不是pragma方式,因为并不是所有的编译器都支持pragma once。而ifndef是C语言支持的。
pragma once使用示例:
test.c
#include <stdio.h>
#include "global.h"
#include "global.h" int main()
{
printf("g_value = %d\n", g_value); return ;
}
global.h
#pragma once int g_value = ;
gcc编译运行结果如下:
注释掉pragma once后,gcc就会报重定义错误。
vc2010编译运行结果如下:
bcc32的编译如下:
可见bcc并不支持pragma once。预处理器不支持的pragma参数,会直接删除pragma once这一行。
工程中可以使用以下的解决方案:
这样可以保证只包含一次,又保证效率。在不支持pragma once的编译器中,还有ifndef做保证。在支持pragma once 的编译器中,它就起作用了,保证文件只被包含一次,也只被处理一次。
pragma pack:
示例程序:
运行结果如下:
两个结构体的成员是一样的,顺序不一样,占用的空间大小就不一样,这就是内存对齐的结果。
内存排列的结果:
内存对齐:
将上述程序加上pragma pack对齐,如下:
再次编译运行,结果如下:
现在两个结构体占用的内存大小就是一样的了。
再次给出一个示例程序:
#include <stdio.h> #pragma pack(8) struct S1
{
short a;
long b;
}; struct S2
{
char c;
struct S1 d;
double e;
}; #pragma pack() int main()
{
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2)); return ;
}
手工分析的对齐结果如下:
运行结果如下:
和我们手工计算的结果并不一样。这是因为gcc编译器不支持8字节对齐,在遇到#pragma pack(8)的时候就直接给删除了。然后就按照默认的4字节对齐了。
在vc编译器下的编译运行结果如下:
这个运行结果和我们手工分析的一样,说明了不同的编译器对pack中的大小支持也是不一样的。
小结:
第24课 #pragma使用分析的更多相关文章
- 第24课 - #pragma 使用分析
第24课 - #pragma 使用分析 1. #pragma简介 (1)#pragma 是一条预处理器指令 (2)#pragma 指令比较依赖于具体的编译器,在不同的编译器之间不具有可移植性,表现为两 ...
- 跟我一起学编程—《Scratch编程》第24课:幸运大转盘
同学你好,欢迎来到<跟我一起学编程>,我是包老师.这是<Scratch3.0编程>课程的第24课,我这节课教你做一个抽奖游戏:幸运大转盘. 学习目标: 1. 能够熟练使用造型工 ...
- Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation
原文:Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...
- 第50课 C++对象模型分析(上)
1. 回归本质 (1)class是一种特殊的结构体 ①在内存中class依旧可以看作变量的集合 ②class与struct遵循相同的内存对齐规则 ③class中的成员函数与成员变量是分开存放的.即每个 ...
- #pragma使用分析
#pragma简介 #pragma用于指示编译器完成一些特定的动作 #pragma所定义的很多指示字是编译器特有的 #pragma在不同的编译器间是不可移植的 预处理器将忽略它不认识的#pragma指 ...
- 第51课 C++对象模型分析(下)
1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protec ...
- [转][Swust OJ 24]--Max Area(画图分析)
转载自:http://www.cnblogs.com/hate13/p/4160751.html Max Area 题目描述:(链接:http://acm.swust.edu.cn/problem/2 ...
- JAVA_SE基础——24.面向对象的内存分析
黑马程序员入学blog ... 接着上一章的代码: //车类 class Car{ //事物的公共属性使用成员变量描述. String name; //名字的属性 String color; //颜色 ...
- 24.Linux-Nand Flash驱动(分析MTD层并制作NAND驱动)
1.本节使用的nand flash型号为K9F2G08U0M,它的命令如下: 1.1我们以上图的read id(读ID)为例,它的时序图如下: 首先需要使能CE片选 1)使能CLE 2)发送0X90命 ...
随机推荐
- Selenium IDE的一些操作
1.运行速度过快时,可能出现找不到元素的情况,影响运行结果,将速度调慢慢一些,就可以运行成功. 如果为其他情况找不到元素,则需要另外找原因,有可能元素定位有问题,有可能无该元素. 2.导出录制的脚本为 ...
- cookie、session、sessionid ,jsessionid 的区别
本文是转载虫师博客的文章http://www.cnblogs.com/fnng/archive/2012/08/14/2637279.html cookie.session.sessionid 与js ...
- ubuntu-未信任的应用程序启动器-XX-Net.desktop
在安装启动xxnet时使用sudo命令,该软件打开后提示[未信任的应用程序启动器]如图所示,解决办法简介:(1)更换成root用户(2)更改权限 背景描述 xx-net中的启动程序有权限设置, ...
- hdu5012 圆环相交面积
题中给了 两个同心圆, 一个大圆一个小圆,然后再给了一个大圆一个小圆也是同心圆,求这两个圆环相交的面积,用两个大圆面积减去两倍大小圆面积交加上两个小圆面积交,就ok了 这里算是坑明白了 使用acos的 ...
- 【转载】package-info
本文是转载,原文地址:http://strong-life-126-com.iteye.com/blog/806246 package-info.java对于经常使用外部包的程序员来说应该是熟悉陌生人 ...
- Python3.x:open()文件操作
Python3.x:open()文件操作 open/文件操作: #open(路径+文件名,读写模式) #读写模式:r只读,r+读写,w新建(会覆盖原有文件),a追加,b二进制文件.常用模式 f=ope ...
- Git合并分支或者冲突
假设冲突文件是 test/TestCase.php 下面分5种情况讨论. 1.本地不变. 然后远程别人有更新. git pull 这种最简单,没有冲突,本地工作区直接更新 2.我本 ...
- [BZOJ1176]Mokia
Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000 ...
- UVa 1635 无关的元素(唯一分解定理+二项式定理)
https://vjudge.net/problem/UVA-1635 题意: 给定n个数a1,a2,...an,依次求出相邻两数之和,将得到一个新数列.重复上述操作,最后结果将变成一个数.问这个数除 ...
- 创建一个 SQLite 数据库
首先,我们学习如何创建一个SQLite 数据库.如果想要在data/example.sqlite 这个路径中创建一个示例数据库,就必须确保该路径存在.如果该路径不存在,就必须先创建路径:if (!di ...