了解#pragma pack(n)

    早上看书,看到#pragma pack(n),不甚了解,果断学习之,留点心得体会,大家一起讨论讨论

 

例子,一般的题目主要是问sizeof(S1)是多少:

 

1.当n大于结构体最长的数据类型的长度时(如例子当中的int),这个n就宣布没有任何影响了

2.计算大小和补字节时从前往后计算,对齐按数据类型和n值当中的小的值进行,如char是1,如果n是4的话,那么以1做对齐,当加入一个新的成员时,这个成员的起始偏移必须是其对齐值的整数倍.好吧,比较抽象,举例来说,假设n=4,如S1,算大小时这么算,首先是m1,m1是char,一个字节,用1个字节对齐,加上m2时,m2是short,两个字节,那么此时,m2的起始偏移是2,偏移是从0算起的.此时就需要补一个字节[m1,00,(m2,m2)],进而加入m4,刚好是4个字节,同时起始偏移是4,很好,接下来3个char,最后由于以4对齐,所以还要补多一个字节,总的结构体的长度是12.如果n=8,那么8>int的长度,所以结构体以4个字节进行对齐.如果n=1,就是要求不做对齐处理,结构体长度为10.

3.当结构体当中存在结构体成员,那么结构体成员按他的长度参与对齐,比如我现在有个S2的结构,里面有个S1结构的成员,如果我声明S1的时候n=1,那么在S2里面S1以10的长度参与对齐,如果声明S1的n=4,那么S2里面,S1以长度12对齐.需要注意的是,S1结构体的成员以几个字节的形式对齐要看n值与S1的int谁比较小.这个注意点主要是在判断内部成员内存位置的时候需要用到.

 

有个题目我觉得分析的不错,附上给大家

-----------------------------------------------我是分割线--------------------------------------------------


1.sizeof(s2) = ?
2.s2的c后面空了几个字节接着是d?

 

sizeof(S2)结果为24.
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节.
                          a    b
S1的内存布局:11**,1111,
                          c    S1.a S1.b     d
S2的内存布局:1***,11**,1111,****11111111

这里有三点很重要:
1.每个成员分别按自己的方式对齐,并能最小化长度
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐

补充一下,对于数组,比如:
char a[3];这种,它的对齐方式和分别写3个char是一样的.也就是说它还是按1个字节对齐.
如果写: typedef char Array3[3];
Array3这种类型的对齐方式还是按1个字节对齐,而不是按它的长度.
不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个.

### 回答1: Pragma 是一个指令,可以用来控制编译器的行为。在 DSP 开发中,可以使用 Pragma 指令来指定编译器在编译时应该采取哪些措施。它可以用来设置编译器的优化等级,也可以让编译器忽略某些警告,或者指定编译器对特定代码段采用特定的编译模式。 ### 回答2: 在DSP开发中,`pragma`用于指导编译器进行优化,以便更好地利用硬件特性和提高代码性能。`pragma`是一种编译指令,用于在编译过程中影响编译器的行为。下面将介绍一些常见的`pragma`用法。 1. `#pragma once`:这是一种头文件保护指令,用于确保头文件只被编译一次。这可以避免重复定义并提高编译速度。 2. `#pragma pack(n)`:该指令用于设定内存对齐的字节数。`n`表示所需的字节数,通常是2的幂次,例如1、2、4、8等。通过调整内存对齐方式,可以提高内存利用率和数据访问效率。 3. `#pragma optimize(level)`:该指令用于设置代码的优化级别。`level`可以是0、1、2或3,其中0表示不进行优化,3表示最大优化。通过调整优化级别,可以在代码效率和编译速度之间进行权衡。 4. `#pragma vectorize`:该指令用于启用向量化优化。向量化可以将循环等操作转换为SIMD指令来并行处理多个数据,从而提高运行速度。 5. `#pragma unroll`:该指令用于循环展开优化。循环展开可以减少循环执行的次数,从而提高代码执行速度。 6. `#pragma section`:该指令用于将函数或数据放置在指定的内存区域中。可以根据需要将代码或数据放置在不同的存储单元中,以实现更好的访问速度或存储条件。 总之,`pragma`是一种在DSP开发中常用的编译指令,用于优化代码和控制编译过程。通过合理使用`pragma`指令,可以提高代码性能和系统效率。 ### 回答3: 在DSP(数字信号处理)开发中,pragma是指编译器的指令,用于控制代码的优化和调整编译器的行为。pragma指令通常以#pragma开头,后面跟着特定的命令。 在DSP开发中,pragma的主要用途有以下几个方面: 1. 优化指令集:通过使用优化指令集的pragma,可以告诉编译器如何使用DSP处理器的指令集,以实现更高效的代码生成。例如,可以使用#pragma CODE_SECTION将关键代码放置在特定的内存区域,以减少指令访问延迟。 2. 内存管理:pragma可以用于内存管理,包括定义变量存储的位置、地址对齐等。通过使用#pragma DATA_SECTION和#pragma DATA_ALIGN等指令,可以在开发过程中对变量进行精确的内存布局和对齐设置,以减小存储空间和提高数据访问效率。 3. 循环优化:通过使用循环优化相关的pragma,可以告诉编译器如何进行循环的并行化、循环展开和向量化等,从而提高循环的执行效率和性能。 4. 编译器警告和错误处理:pragma还可以用于控制编译器的警告和错误信息的显示。通过使用#pragma WARNING和#pragma ERROR等指令,可以在编译过程中指定警告和错误的处理方式,从而更好地进行代码调试和分析。 需要注意的是,不同的编译器可能对pragma的支持和语法有所不同,因此在使用时需查阅相应DSP开发工具的编译器手册或文档,了解具体的使用方法和语法规则。正确使用pragma指令可以帮助开发者实现更高效、可靠的DSP程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值