C语言进阶课程学习记录-第24课 - #pragma 使用分析
- #pragma
- 实验-#pragma message
- cmd窗口运行
- 实验-pragma once
- bcc编译报错
- gcc编译成功
- global.h代码优化
- #pragma pack
- 实验
- BCC编译器输出
- 小结
本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程,图片全部来源于课程PPT,仅用于个人学习记录
#pragma
实验-#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 0;
}
cmd窗口运行
D:\Users\cy\Cxuexi\gccLearn\24-1>gcc 24-1.c
24-1.c:13:6: error: #error Compile Version is not provided!
#error Compile Version is not provided!
^~~~~
24-1.c: In function 'main':
24-1.c:18:20: error: 'VERSION' undeclared (first use in this function)
printf("%s\n", VERSION);
^~~~~~~
24-1.c:18:20: note: each undeclared identifier is reported only once for each function it appears in
D:\Users\cy\Cxuexi\gccLearn\24-1>gcc -DANDROID20 24-1.c
24-1.c:4:13: note: #pragma message: Compile Android SDK 2.0...
#pragma message("Compile Android SDK 2.0...")
^~~~~~~
D:\Users\cy\Cxuexi\gccLearn\24-1>gcc -DANDROID23 24-1.c
24-1.c:7:13: note: #pragma message: Compile Android SDK 2.3...
#pragma message("Compile Android SDK 2.3...")
^~~~~~~
D:\Users\cyz1994\Cxuexi\gccLearn\24-1>a.exe
Android 2.3
实验-pragma once
//global.h
#pragma once//不是所有编译器都支持此命令
int g_value = 1;
#include <stdio.h>
#include "global.h"
#include "global.h"
int main()
{
printf("g_value = %d\n", g_value);
return 0;
}
bcc编译报错
gcc编译成功
D:\Users\cy\Cxuexi\gccLearn\test>gcc test.c
D:\Users\cy\Cxuexi\gccLearn\test>a.exe
g_value = 1
global.h代码优化
//global.h
#ifndef _GLOBAL_H_//防止编译器不支持,添加条件编译
#def _GLOBAL_H_
#pragma once//
int g_value = 1;
#endif
#pragma pack
#pragma pack(4)
struct Test1
{ //对齐参数 偏移地址 大小
char c1; //1 0 1
short s; //2 2 2
char c2; //1 4 1
int i; //4 8 4
};
#pragma pack()
对齐参数 =min(pack内部数字,数据类型字节数)
偏移地址必须是对齐参数的整数倍
大小=数据类型字节数
实验
#include <stdio.h>
#pragma pack(2)
struct Test1
{ //对齐参数 偏移地址 大小
char c1; //1 0 1
short s; //2 2 2
char c2; //1 4 1
int i; //2 6 4
};
#pragma pack()
#pragma pack(4)
struct Test2
{ //对齐参数 偏移地址 大小
char c1; //1 0 1
char c2; //1 1 1
short s; //2 2 2
int i; //4 4 4
};
#pragma pack()
int main()
{
printf("sizeof(Test1) = %d\n", sizeof(struct Test1));
printf("sizeof(Test2) = %d\n", sizeof(struct Test2));
return 0;
}
/*
output:
sizeof(Test1) = 10
sizeof(Test2) = 8
*/
#include <stdio.h>
#pragma pack(8)//有些编译器不支持,采取默认字节对齐
struct S1
{ //对齐参数 偏移地址 大小
short a;//2 0 2
long b; //4 4 4
};
struct S2
{
char c; //1 0 1
struct S1 d;// 8 8 8
double e; //8 16 8
};
#pragma pack()
int main()
{
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
return 0;
}
/*output:
8
24
*/
BCC编译器输出
小结
#pragma用于指示编译器完成一些特定的动作
#pragma所定义的很多指示字是编译器特有的
- #pragma message用于自定义编译消息
- #pragma once用于保证头文件只被编译一次
- #pragma pack用于指定内存对齐方式