C语言#pragma使用方法

C语言#pragma使用方法

一、总结

       1、#pragma用于指示编译器完成一些特定的动作

       2、#pragma所定义的很多指示字是编译器特有的(每种编译可能都不一样)

              (1) #pragma message 用于自定义编译信息

              (2)#pragma once 用于保证头文件只被编译一次

              (3)#pragama pack用于指定内存对齐(一般用在结构体)

                        struct占用内存大小

                            1)第一个成员起始于0偏移处

                            2)每个成员按其类型大小和pack参数中较小的一个进行对齐

                                     ——偏移地址必须能被对齐参数整除

                                     ——结构体成员的对齐参数(注意是对齐参数,而不是结构体长度)取其内部长度最大的数据成员作为其大小

                            3)结构体总长度必须为所有对齐参数的整数倍

编译器在默认情况下按照4字节对齐

       3、#pragma在不同的编译器间是不可移植的

              (1)预处理器将忽略它不认识#pragma指令

              (2)不同的编译器可能以不同的方式解释同一条#pragma指令

二、代码测试

       1、#pragma message:自定义编译信息输出到终端(一般和#if配合使用,用在控制版本号)
#include 
#define ANDROID20

#if defined ANDROID20
   #pragma message "Compile Android SDK 2.0..."
   #define VERSION "Android 2.0"
#elif defined ANDROID30
   #pragma message "Compile Android SDK 3.0..."
   #define VERSION "Android 3.0"
#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 0;
}

终端输出:

   C语言#pragma使用方法_第1张图片

看见没,编译的时候输出#pragma message信息,运行的时候根本看不见,你们可以通过预处理命令,看下是否在预处理阶段处理了,gcc -E test.c -o test.i  然后找到test.i文件,双击用gedit打开

C语言#pragma使用方法_第2张图片

看见没,预处理根本没处理#pragma message指令,所以#pragma message指令是在编译器处理的

 2、#pragma once:指示编译器头文件被编译一次
#include 
#include "test.h"
#include "test.h"

int main()
{
    printf("g_value = %d\n",g_value);
    return 0;
}

test.h文件内容:

#pragma once

int g_value = 10; 

看下终端输出:

C语言#pragma使用方法_第3张图片

        3、#pragma pack:指定内存对齐
#include 

#pragma pack(2)
struct test1
{                 //对齐参数  偏移地址   大小  
    char c1;      //1          0       1
    char c2;      //1          1       1
    short s;      //2          2       2
    int i;        //2          4       4
};
#pragma pack()

#pragma pack(4)
struct test2
{                 //对齐参数  偏移地址   大小
    char c1;      //1          0       1
    short s;      //2          2       2
    char c2;      //1          4       1
    int i;        //4          8       4
};
#pragma pack()

#pragma pack(8)
struct S1
{                 //对齐参数  偏移地址   大小 
    short s;      //2          0       2
    long l;       //4          4       4
};
struct S2
{                 //对齐参数  偏移地址   大小    
    char c;       //1          0       1
    struct S1 d;  //4          4       8        
    double e;//理论//8         16       8    这里实际是错误的,gcc不支持8字节对齐,所以这里默认是4字节对齐           //实际//4         12       8    所以整个占用内存是20字节 
};
#pragma pack()

int main()
{
    printf("sizeof(struct test1) = %d\n",sizeof(struct test1));  //输出8 
    printf("sizeof(struct test2) = %d\n",sizeof(struct test2));  //输出12
    
    printf("sizeof(struct S1) = %d\n",sizeof(struct S1));        //输出8
    printf("sizeof(struct S2) = %d\n",sizeof(struct S2));        //理论计算应该输出24  但是实际打印输出是20   这是因为gcc不支持8字节内存对齐,所以这里是默认4字节对齐,
    return 0;
}

看下终端打印输出:

C语言#pragma使用方法_第4张图片

程序里面都有注释,所以不讲了

参考资料《狄泰软件C语言进阶》

你可能感兴趣的:(C/C++语言,嵌入式开发,vi和vim编辑器,gcc编译器学习)