C语言笔记 第二十四课 #pragma使用分析

本文详细解析了C/C++中#pragma指令的应用,包括消息输出、防止头文件重复包含及内存对齐控制。通过具体示例,阐述了不同编译器下#pragma的特性与限制,为程序员提供了实用的代码优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第二十四课 #pragma使用分析

#pragma简介

#pragma用于指示编译器完成一些特定的动作
#pragma所定义的很多指示字是编译器特有的
#pragma在不同的编译器间是不可移植的
预处理器将忽略它不认识的#pragma指令
不同的编译器可能以不同的方式解释同一条#pragma指令
一般用法:#pragma parameter
注:不同的parameter参数语法和意义各不相同

#pragma message

message参数在大多数的编译器中都有相似的实现
message参数在编译时输出消息到编译输出窗口中
message用于条件编译中可提示代码的版本信息
#if defined (ANDROID20)
#pragma message(“Compile Andriod SDK2.0…”)
#define VERSION”Android 2.0”
#endif
与#error和#warning不同,#pragma message仅仅代表一条编译消息,不代表程序错误。
24-1 #pragma message使用示例

#pragma once

#pragma once用于保证头文件只被编译一次
#pragma once是编译器相关的,不一定被支持
在这里插入图片描述
这两种方式有什么区别?
24-2 #pragma once使用分析

#pragma pack

什么是内存对齐?
不同类型的数据在内存中按照一定的规则排列
而不一定是顺序的一个接一个的排列
在这里插入图片描述
在这里插入图片描述
Test1和Test2所占的内存空间是否相同?不相同,Test1是12,Test2是8
在这里插入图片描述

为什么需要内存对齐?

CPU对内存的读取不是连续的,而是分成块读取的,块的大小只能是1、2、4、8、16…字节
当读取操作的数据未对齐,则需要两次总线周期来访问内存,因此性能会大打折扣
某些硬件平台只能从规定的相对地址处读取特定类型的数据,否则产生硬件异常
#pragma pack用于指定内存对齐方式
#pragma pack能够改变编译器的默认对齐方式
在这里插入图片描述

struct占用的内存大小

第一个成员起始于0偏移处
每个成员按类型大小和pack参数中较小的一个进行对齐
偏移地址必须能被对齐参数整除
结构体成员的大小取其内部长度最大的数据成员作为其大小
结构体总长度必须为所有对齐参数的整数倍
编译器在默认情况下按照4字节对齐 #pragma pack(4)
24-3 24-4 结构体大小计算

24-4微软面试题

#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 0;
}

所用编译器 老师编译器 VC2010
在这里插入图片描述
gcc编译器的#pragma pack(8)的作用
gcc编译器不支持8字节对齐参数,根据默认4字节对齐参数
8字节 4字节
在这里插入图片描述
小结:
#pragma用于指示编译器完成一些特定的动作
#pragma所定义的很多指示字是编译器特有的
#pragma message用于自定义编译消息
#pragma once用于保证头文件只被编译一次
#pragma pack用于指定内存对齐方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值