Linux C编程学习笔记(二)暨混乱弥补知识之pragma与字节对齐
Linux编程实战
前言
今天在学习Linux编程实战预处理命令这一块的时,产生了对编译器把#include<头文件>包含的头文件内容全部包括进来朝如到命令所在位置并取代原命令行这一方式是否与链接文件的操作有关的疑问(冗长了……),于是查阅资料,得知它是对程序进行预处理的一部分,此操作在链接之前。
然而在预处理之一块存在“保留编译器需要使用#pragma指令”这个操作,再次产生对#program的疑问,故查资料之……
接着在理解学习#pragma这一伪指令使又产生了对#pragma pack()这一指令用法的疑惑,故再次查资料……
在耗费了一个半小时后,终于大致理解了这些内容,故总结之,然而书本只看了一页……
字节对齐
先从疑问圈的最内层开始总结
相信大家应该都遇到过输出一个二位字符串数组时,当一次循环输出的数超过一行时,由于‘\0\’的定义位置问题,有可能会输出第二行的数据,字节对齐也和这个类似。
当我们定义结构体或类等数据时(以下统称类),类内成员的字节排放顺序并不一定是紧挨着的顺序排放,而是会按照某种规则在内存顺序排放,这种规则因不同的编译器而异。在空间上,这种排放可以理解为按n字节模的排放方法。排放出来和二维数组的形式很类似。
例如:
#include<iostream>
using namespace std;
class Fruits{
char name[10];
int n;
float ll;
double dou;
}
先另提一点:32bits和64bits的计算机定义不同数据类型的字节数有所出入,在这里我们选用64bits的计算机。
这段代码的类若按默认的4字节为模来排放的话,就会占用
((4+4+2+2)+4+4+8)个字节。
如果用2字节为模来排放则占用((2*5)+4+4+8)个字节
#pragma pack(n)就是对字节模数n的定义
#pragma pack()则是取消对字节模数的定义
简单总结pragma pack()的用法
格式:#pragma pack( [show] | [push | pop] [identifier], n );
- show:显示当前packing aligment的字节数,以warning message的形式显示
- push: 作用是保存当前默认的字节对齐方式
- pop:作用是恢复默认的字节对齐方式
- identifier:在编译一栏显示信息
- n:如上文所述
简单总结pragma的用法
- #pragma message(“消息”):在编译栏输出消息,一般为警示消息
- #pragma once:只编译该头文件一次
- #pragma hdrstop:编译该头文件到此为止
- #pragma pack():如上文所示
简单总结编译与链接
编译:
指令例:gcc -E file.c -o file.i
一、预处理
- 用空格代替注释
- 展开所有宏定义并删除#define
- 处理条件编译指令如:#if、#ifdef等
- 包含合并#include的头文件
- 保留经条件编译后有效的pragma指令
二、编译
指令例: gcc -S file.i -o file.s
- 语法分析、词法分析、语义分析
- 生成对印的汇编文件
三、汇编
指令例: gcc - c file.s -o file.o
- 将汇编文件代码转化为机器指令
- 每条汇编指令对应一条机器指令
链接
静态链接:由链接器在链接时将库的内容直接加入到可执行程序中
动态链接:
- 可执行程序在运行时才动态加载库进行连接
- 库的内容不会进入可执行程序
参考:
pragma的部分用法
pragma pack()的部分用法
编译和链接过程简介
本文地址:https://blog.csdn.net/qq_43670949/article/details/107233449
上一篇: 钮枯禄氏是怎么当上贵妃的?真相是什么
下一篇: 图像分类学习笔记