#pragma分析

本文介绍了编译器指令#pragma的三个实用参数:message、once和pack。message用于编译时输出信息;once确保头文件仅被包含一次,提高编译效率;pack则用于设置结构体成员的内存对齐方式,优化内存使用。

#pragma用于指示编译器完成特定的操作。并且,#pragma很多指示字是编译器特有的。在不同的编译器间不可实现移植。
先来讲一个比较常用的pragma参数字------message。这个指示字在大多数的编译器中都有实现。它是在编译时输出消息到编译输出窗口。在条件编译中,可以提示代码的版本信息。那么,通过一个代码实例来理解一下。

#include <stdio.h>
#include <stdlib.h>

#if defined ( ROBOT10 )
#pragma message ( "compile Robot SDK 1.0" )
#define VERSION "ROBOT 1.0"
#elif defined ( ROBOT 2.0 )
#pragma message ( "compile Robot SDK 2.0" )
#define VERSION "ROBOT 2.0"
#elif defined ( ROBOT30)
#pragma message ( "compile Robot SDK 3.0" )
#define VERSION "ROTOT 3.0"

#else
    #error Compile Version is not provided!

int main(){

    printf ( "%s\n", VERSION );

system ( "pause" );
    return 0;
}

接下来介绍第二个参数字once。该参数用来保证头文件只被编译一次。
用法:
比如有一个头文件,fruit.h。然后,在这个文件中,

#pragma once

int apple = 2;

这样就保证,该头文件只在其他文件中包含一次。
once和#ifndef都能保证头文件只包含一次,这两者有区别吗?答案是肯定的。
使用#ifndef来保证头文件只包含一次,这样做的效率较低,为什么呢?事实上,使用#ifndef并非头文件只包含了一次,而是,包含了调用头文件的所有次数,只不过是都被过滤掉了,留下了一次。而使用once确确实实只包含了一次。但是,由于once这个参数并不是所有编译器都有的,那么怎样才能我既想效率高又想不会出现编译器不支持once的问题呢。只要这样做,

#ifndef _GLOBAL_H_
#deifne _GLOBAL_H_

#pragma once 
int apple = 2;

#endif

然后是第三个,也是最重要的一个参数,pack。这个是设置内存对齐方式的。由于CPU读取内存时是按照块来读取的,所以,在结构体中定义结构体成员的方式不同,最终占用的内存空间就不同。如果没有进行相应的设置,那么CPU默认按照4字节来访问内存空间。举例说明:

struct type{

    char c;
    int a;
    int b;
    float d;
};

这段代码在内存中占用的空间是多少呢?答案是16个字节。由于变量c为char型,偏移地址从0开始,然后,变量a为int型,当CPU访问时已经从偏移地址为4开始访问。当遇到变量b时,偏移地址从8开始,最后float占4个地址空间,当CPU访问时从12开始,所以,最终,该结构体占了16个字节的内存空间。那么pack的作用就是让结构体成员合理分布,尽可能占用较少的内存空间。用法,比如:

#pragma pack ( 1 )
struct type{
char c;
int a;
int b;
float d;
};
#pragma pack()

转载于:https://blog.51cto.com/chen0547/2044801

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值