#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使用分析的更多相关文章

  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. smart基础

    主要是libs里面的smarty类,和init.inc.php配置文件 剩下的是php文件夹.模板文件夹,临时文件夹.缓存文件夹.配置文件夹.插件文件夹 调用main文件夹中的php文件,通过libs ...

  2. 《大话设计模式》ruby版代码:建造者模式

    需求: 画一个小人,有头,有身体,两手两脚即可. 初始代码: # -*- encoding: utf-8 -*- #小人一 puts '这是第一个小人' puts '小人一:头' puts '小人一: ...

  3. Entity Framework 复杂类型(转)

    为了说明什么是复杂属性,先举一个例子. public class CompanyAddress { public int ID { get; set; } public string CompanyN ...

  4. 20165207 学习基础与C语言基础调查反馈

    文章阅读体会与学习调查反馈 文章阅读体会 我在娄老师的文章里了解到了"做中学"的概念.并且通过娄老师慷慨地分享的相关经验,我对于它有了进一步的理解以及体会.以下是我收获以及我的感想 ...

  5. excel文件与txt文件互转,并且把excel里的数据导入到oracle中

    一.excel文件转换成txt文件的步骤 a.首先要把excel文件转换成txt文件 1.Excel另存为中已经包含了TXT格式,所以我们可以直接将Excel表格另存为TXT格式,但是最后的效果好像不 ...

  6. 2018-2019-1 20189215 《Linux内核原理与分析》第六周作业

    <庖丁解牛>第五章书本知识总结 system_call并不是一个普通的函数,只是一段汇编代码的起点,且内部没有严格遵守函数调用堆栈机制. 通过set_system_trap_gate函数绑 ...

  7. 20145204 《Java程序设计》第2周学习总结

    20145204 <Java程序设计>第2周学习总结 教材学习内容总结 在第三章主要学习了Java语言中的类型及其变量主要类型为:整数(1字节的byte,2字节的short,4字节的int ...

  8. 双击不能运行可执行的jar文件

    1.首先在命令行下运行jar包看文件是否报错(java -jar jar文件名称.jar)          如果程序中有System.out.println()语句,不想让其输出到控制台而保存到文件 ...

  9. Shell脚本之无限循环的两种方法

    for #!/bin/bash ;i<;)) do let "j=j+1" echo "-------------j is $j ----------------- ...

  10. Adapter Class/Object(适配器)

    意图: 将一个类的接口转换成客户希望的另外一个接口.Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适用性: 你想使用一个已经存在的类,而它的接口不符合你的需求. 你想 ...