#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. 39XML文档类

    Xml源代码 domxml.h #ifndef DOMXML_H #define DOMXML_H #include <QString> #include <QStringList& ...

  2. ACM-ICPC 2018 沈阳赛区网络预赛 Solution

    A. Gudako and Ritsuka 留坑. B. Call of Accepted 题意:定义了一种新的运算符$x d y$ 然后给出中缀表达式,求值 思路:先中缀转后缀,然后考虑如何最大如何 ...

  3. 使用Linux重定向解决nohup.out无写权限问题

    ■场景 执行nohup命令的时候,经常会出现下面这种没有写入权限的错误. nohup: ignoring input and appending output to `nohup.out'nohup: ...

  4. Python面试题目之列表取值超出范围

    # 下面列表取值超出范围,会报错还是有返回值: L1 = [',]print(L1[10]) print(L1[10:]) 第一个打印会报错: 第二个打印会返回一个空列表

  5. 20145204 《Java程序设计》第9周学习总结

    20145204 <Java程序设计>第9周学习总结 教材学习内容总结 JDBC Java语言访问数据库的一种规范,是一套API.JDBC (Java Database Connectiv ...

  6. 在linux上安装Drupal

    前言:国内用drupal的并不太多,网上资料也很少.要注意的是drupal尽量别使用apt来安装,特别是ubuntu平台的drupal做出了一定的更改,会妨碍后期的学习和使用.在安装drupal前要先 ...

  7. append 注意事项

    >>> t1 = [, ] >>> t2 = t1.append() >>> t1 [, , ] >>> t2 None

  8. python 字典元素值的乘积

    my_dict = {,,} result= for key in my_dict: result=result * my_dict[key] print(result)

  9. angular的 表单

    一般来讲表单可能遇到的问题:1.如何数据绑定.2.验证表单.3.显示出错信息.4.整个form的验证.5.避免提交没有验证通过的表单.6.防止多系提交. input属性:nameng-modelng- ...

  10. Learn Rails5.2 Routes。( 很少用到的参数:constraints和redirect)

    Naming a Route get 'home/index', as: "different_name" 会得到prefix: different_name代替home_inde ...