#pragma是C语言留给编译器厂商进行扩展用的。

这个关键字在不同的编译器之间也许是不能够移植的。

#pragma简介

#pragma message

#pragma message打印的消息并不代表代码有什么问题。

示例:

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

编译命令如下:

可见,在编译期间,预处理器处理#pragma message,并输出信息。

将上述程序用vc编译器进行编译,结果如下:

输出和gcc只有略微的差别。

bcc32的编译输出如下:

#pragma once

左边是通过判断宏是否已经定义的方式保证代码只被嵌入一次,预处理器还是处理了这个文件。而#pragma once 保证只处理这个要包含的文件一次。所有pragma once的效率会高一点。

工程中用的比较多的是ifndef方式,而不是pragma方式,因为并不是所有的编译器都支持pragma once。而ifndef是C语言支持的。

pragma once使用示例:

test.c

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "global.h"
  4.  
  5. int main()
  6. {
  7. printf("g_value = %d\n", g_value);
  8.  
  9. return ;
  10. }

global.h

  1. #pragma once
  2.  
  3. int g_value = ;

gcc编译运行结果如下:

注释掉pragma once后,gcc就会报重定义错误。

vc2010编译运行结果如下:

bcc32的编译如下:

可见bcc并不支持pragma once。预处理器不支持的pragma参数,会直接删除pragma once这一行。

工程中可以使用以下的解决方案:

这样可以保证只包含一次,又保证效率。在不支持pragma once的编译器中,还有ifndef做保证。在支持pragma once 的编译器中,它就起作用了,保证文件只被包含一次,也只被处理一次。

pragma pack:

示例程序:

运行结果如下:

两个结构体的成员是一样的,顺序不一样,占用的空间大小就不一样,这就是内存对齐的结果。

内存排列的结果:

内存对齐:

将上述程序加上pragma pack对齐,如下:

再次编译运行,结果如下:

现在两个结构体占用的内存大小就是一样的了。

再次给出一个示例程序:

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

手工分析的对齐结果如下:

运行结果如下:

和我们手工计算的结果并不一样。这是因为gcc编译器不支持8字节对齐,在遇到#pragma pack(8)的时候就直接给删除了。然后就按照默认的4字节对齐了。

在vc编译器下的编译运行结果如下:

这个运行结果和我们手工分析的一样,说明了不同的编译器对pack中的大小支持也是不一样的。

小结:

第24课 #pragma使用分析的更多相关文章

  1. 第24课 - #pragma 使用分析

    第24课 - #pragma 使用分析 1. #pragma简介 (1)#pragma 是一条预处理器指令 (2)#pragma 指令比较依赖于具体的编译器,在不同的编译器之间不具有可移植性,表现为两 ...

  2. 跟我一起学编程—《Scratch编程》第24课:幸运大转盘

    同学你好,欢迎来到<跟我一起学编程>,我是包老师.这是<Scratch3.0编程>课程的第24课,我这节课教你做一个抽奖游戏:幸运大转盘. 学习目标: 1. 能够熟练使用造型工 ...

  3. Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation

    原文:Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...

  4. 第50课 C++对象模型分析(上)

    1. 回归本质 (1)class是一种特殊的结构体 ①在内存中class依旧可以看作变量的集合 ②class与struct遵循相同的内存对齐规则 ③class中的成员函数与成员变量是分开存放的.即每个 ...

  5. #pragma使用分析

    #pragma简介 #pragma用于指示编译器完成一些特定的动作 #pragma所定义的很多指示字是编译器特有的 #pragma在不同的编译器间是不可移植的 预处理器将忽略它不认识的#pragma指 ...

  6. 第51课 C++对象模型分析(下)

    1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protec ...

  7. [转][Swust OJ 24]--Max Area(画图分析)

    转载自:http://www.cnblogs.com/hate13/p/4160751.html Max Area 题目描述:(链接:http://acm.swust.edu.cn/problem/2 ...

  8. JAVA_SE基础——24.面向对象的内存分析

    黑马程序员入学blog ... 接着上一章的代码: //车类 class Car{ //事物的公共属性使用成员变量描述. String name; //名字的属性 String color; //颜色 ...

  9. 24.Linux-Nand Flash驱动(分析MTD层并制作NAND驱动)

    1.本节使用的nand flash型号为K9F2G08U0M,它的命令如下: 1.1我们以上图的read id(读ID)为例,它的时序图如下: 首先需要使能CE片选 1)使能CLE 2)发送0X90命 ...

随机推荐

  1. C# 使用BackgroundWorker实现WinForm异步

    写了一个基于BackgorundWorker演示异步操作的例子.由于这个理基本上实现了BackgorundWorker的大部分功能:异步操作的启动.操作结束后的回调.异步操作的撤销和进度报告等等.尽管 ...

  2. node核心:异步流程控制

    Node.js的异步是整个学习Node.js过程中重中之重. 1)异步流程控制学习重点 2)Api写法:Error-first Callback 和 EventEmitter 3)中流砥柱:Promi ...

  3. idea中使用插件lombok简化java bean的getter/setter/log等常用功能

    一.安装. 1. 2. 3. 4. . 二.使用 1. 2. 3. 结果分析,如果没有添加@Setter注解,则LombokTest中的student示例无法使用setAge()等方法.使用lombo ...

  4. node学习笔记第一天

    ES6---* JavaScript语言随着使用的人越来越多,ECMA语法规范:if/else* 为了让js语言更适应大型应用的开发.旨在消除一些怪异的行为 ### 包含内容(strict严格模式)- ...

  5. Linux 笔记 #01# 搭建 Python 环境 & vim 代码高亮

    日常收集 vim editor: How do I enable and disable vim syntax highlighting? 搭建 Python 环境 vim editor: How d ...

  6. Vue学习笔记之Vue组件

    0x00 前言 vue的核心基础就是组件的使用,玩好了组件才能将前面学的基础更好的运用起来.组件的使用更使我们的项目解耦合.更加符合vue的设计思想MVVM. 那接下来就跟我看一下如何在一个Vue实例 ...

  7. Javaworkers团队第四周项目总结

    本周项目进展 本周是我们的项目开发的第四周,在之前的一周,我们小组在合作的情况下基本完成了项目代码的框架编写,我们组的项目课题,小游戏--贪吃蛇以及可以运行,可以进行简单的游戏,但是我们在思考之后发现 ...

  8. tcpdump 的正确食用方法

    目录 tcpdump 使用笔记 重要报文头 字段表 ip header tcp header 基础使用 高级版本 指定ttl(通过ttl能够确定系统的类型) tcpdump 使用笔记 重要报文头 字段 ...

  9. HDU 3339 In Action(最短路+背包)题解

    思路:最短路求出到每个点的最小代价,然后01背包,求出某一代价所能拿到的最大价值,然后搜索最后结果. 代码: #include<cstdio> #include<set> #i ...

  10. 【查看内存】Linux查看内存使用情况(二)

    Linux查看CPU和内存使用情况:http://www.cnblogs.com/xd502djj/archive/2011/03/01/1968041.html 在做Linux系统优化的时候,物理内 ...