美文网首页
c++ #Pragma

c++ #Pragma

作者: AArman | 来源:发表于2023-01-30 09:53 被阅读0次
    //定义了_X86 宏以后,应用程序在编译时就会在编译输出窗口里显示message
    #ifdef _X86
       #Pragma message(“_X86 macro activated!”);  // 当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来
    #endif
    
    
    #pragma code_seg( ["section-name"[,"section-class"] ] ); //它可以设置程序中函数代码存放的代码段
    
    #pragma once;     //只要在头文件的最开始加入这条指令就可以保证头文件被编译一次
    
    #pragma hdrstop;  //表示预编译头文件到此为止,后面的头文件不进行预编译。BCB 能够预编译头文件以加快连接的速度,但若是全部头文件都进行预编译又可能占太多磁盘空间,因此使用这个选项排除一些头文件。
    
    
    #pragma comment(lib, "user32.lib"); //将user32.lib 库文件加入到本工程
    
    
    
    #pragma warning(disable:4507 34);    // 不显示4507 和34 号警告信息
    #pragma warning(once:4385);         // 4385 号警告信息仅报告一次
    #pragma warning(error:164);         // 把164 号警告信息做为一个错误
    
    #pragma warning(push);        //保存全部警告信息的现有的警告状态
    #pragma warning(push, n);      //保存全部警告信息的现有的警告状态,而且把全局警告等级设定为n
    #pragma warning(pop);         //向栈中弹出最后一个警告信息,在入栈和出栈之间所做的一切改动取消
    

    #pragma once 和 #ifndef _x_h 区别

    1. ifndef _x_h

      1. ifndef 的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含

      2. ifndef受C/C++语言标准的支持,不受编译器的任何限制;

      3. 缺点:如果宏名称一样时,编译器会提示找不到声明
    2. pragma once

      1. 由编译器提供支持,同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。
      2. 不必担心宏名冲突问题
      3. 缺点:如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含

    pragma pack

    1. 机器的位数
      1. 计算机一次能处理数据的最大位数称为该机器的位数,位数跟电脑的CPU有关。
        1. 64位的机器一次最多从内存中读取8字节
        2. 32位的机器一次最多从内存中读取4字节
    2. 对齐系数
      1. 每个特定平台上的编译器都有自己的默认“对齐系数”
      2. 默认的结构体对齐系数,取决于成员中最大的变量所占的字节数,按照最大变量所占的字节数进行对齐,(sizeof(struct))

    Q : 默认的对齐方式,可能造成CPU读取变量效率低,或者内存浪费。因为64位机器一次最多读取8位, 在c++中可以通过预编译命令,来调整对齐系数数。进而调整结构体的存储方式

    1. pragma pack(n)

      1. n=1,2,4,8,16来改变这一系数,其中的n就是要指定的“对齐系数”
    2. 对齐规则:
      1. 数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack 指定的数值和这个数据成员自身长度中,比较小的那个进行
      2. 结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行
      3. 如果 n 大于等于该变量所占用的字 节数,那么偏移量必须满足默认的对齐方式
      4. 如果 n 小于该变量的类型所占用 的字节数,那么偏移量为 n 的倍数,不用满足默认的对齐方式
      5. 结构的约束条件:
        1. 如果 n 大于所有成员变量类型所占用的字节数,那么结 构的总大小必须为占用空间最大的变量占用的空间数的倍数; 否则必须为 n 的倍数
        2. 如果 #pramga pack(n) 中的n大于结构体成员中任何一个成员所占用的字节数,则该n值无效。编译器会选取结构体中最大数据成员的字节数为基准
    #pragma pack(n); //作用:C编译器将按照n个字节对齐
    #pragma pack()  //作用:取消自定义字节对齐方式
    
    #pragma pack(push, n); //作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为n个字节对齐
    #pragma pack(pop);     //作用:恢复对齐状态
    
    • 在网络协议编程的作用
      • 在网络协议编程中,经常会处理不同协议的数据报文
      • 一种方法是通过指针偏移的方法来得到各种信息,但这样做不仅编程复杂,而且一旦协议有变化,程序修改起来也比较麻烦
      • 利用pragma pack特性,通过访问结构的成员来获取各种信息。这样做,不仅简化了编程,而且即使协议发生变化,我们也只需修改协议结构的定义即可,其它程序无需修改,省时省力。避免通讯两边因设备原因造成对齐系数不同。如果已知两边的对齐方式相同,加不加没有影响
    #pragma pack(1) // 按照1字节方式进行对齐
    struct TCPHEADER 
    {
         short SrcPort; // 16位源端口号
         short DstPort; // 16位目的端口号
         int SerialNo; // 32位序列号
         int AckNo; // 32位确认号
         unsigned char HaderLen : 4; // 4位首部长度
         unsigned char Reserved1 : 4; // 保留6位中的4位
         unsigned char Reserved2 : 2; // 保留6位中的2位
         unsigned char URG : 1;
         unsigned char ACK : 1;
         unsigned char PSH : 1;
         unsigned char RST : 1;
         unsigned char SYN : 1;
         unsigned char FIN : 1;
         short WindowSize; // 16位窗口大小
         short TcpChkSum; // 16位TCP检验和
         short UrgentPointer; // 16位紧急指针
    }; 
    #pragma pack()
    
    

    相关文章

      网友评论

          本文标题:c++ #Pragma

          本文链接:https://www.haomeiwen.com/subject/xejmhdtx.html