第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命 ...
随机推荐
- C# 使用BackgroundWorker实现WinForm异步
写了一个基于BackgorundWorker演示异步操作的例子.由于这个理基本上实现了BackgorundWorker的大部分功能:异步操作的启动.操作结束后的回调.异步操作的撤销和进度报告等等.尽管 ...
- node核心:异步流程控制
Node.js的异步是整个学习Node.js过程中重中之重. 1)异步流程控制学习重点 2)Api写法:Error-first Callback 和 EventEmitter 3)中流砥柱:Promi ...
- idea中使用插件lombok简化java bean的getter/setter/log等常用功能
一.安装. 1. 2. 3. 4. . 二.使用 1. 2. 3. 结果分析,如果没有添加@Setter注解,则LombokTest中的student示例无法使用setAge()等方法.使用lombo ...
- node学习笔记第一天
ES6---* JavaScript语言随着使用的人越来越多,ECMA语法规范:if/else* 为了让js语言更适应大型应用的开发.旨在消除一些怪异的行为 ### 包含内容(strict严格模式)- ...
- Linux 笔记 #01# 搭建 Python 环境 & vim 代码高亮
日常收集 vim editor: How do I enable and disable vim syntax highlighting? 搭建 Python 环境 vim editor: How d ...
- Vue学习笔记之Vue组件
0x00 前言 vue的核心基础就是组件的使用,玩好了组件才能将前面学的基础更好的运用起来.组件的使用更使我们的项目解耦合.更加符合vue的设计思想MVVM. 那接下来就跟我看一下如何在一个Vue实例 ...
- Javaworkers团队第四周项目总结
本周项目进展 本周是我们的项目开发的第四周,在之前的一周,我们小组在合作的情况下基本完成了项目代码的框架编写,我们组的项目课题,小游戏--贪吃蛇以及可以运行,可以进行简单的游戏,但是我们在思考之后发现 ...
- tcpdump 的正确食用方法
目录 tcpdump 使用笔记 重要报文头 字段表 ip header tcp header 基础使用 高级版本 指定ttl(通过ttl能够确定系统的类型) tcpdump 使用笔记 重要报文头 字段 ...
- HDU 3339 In Action(最短路+背包)题解
思路:最短路求出到每个点的最小代价,然后01背包,求出某一代价所能拿到的最大价值,然后搜索最后结果. 代码: #include<cstdio> #include<set> #i ...
- 【查看内存】Linux查看内存使用情况(二)
Linux查看CPU和内存使用情况:http://www.cnblogs.com/xd502djj/archive/2011/03/01/1968041.html 在做Linux系统优化的时候,物理内 ...