欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言#pragma使用方法

程序员文章站 2022-05-05 12:52:52
...

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 <stdio.h>
#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使用方法

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

C语言#pragma使用方法

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

 2、#pragma once:指示编译器头文件被编译一次
#include <stdio.h>
#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、#pragma pack:指定内存对齐
#include <stdio.h>

#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使用方法

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

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

相关标签: C语言#pragma pack