C++中的一些反直觉逻辑记录

条件判断

函数往往对唯一情况的处理是return 0

例如strncmp函数,如果字符串str1与str2相同,那么return 0。但是0代表的是假,那么配合 if 语句的编程手法是将判断语句写成

!strncmp(buf,"quit",4) 

【!0】为真,从而通过 if 可以去处理这个唯一情况。

指针中的*

C语言的命名从后往前读: 遇到*解释为:point to ,对于指针的定义和使用也是如此!

结构体

在C语言中,结构体(struct)的内存布局遵循内存对齐规则。这种对齐机制是为了提高CPU访问内存的效率,但会导致结构体的实际大小可能大于各成员变量大小的简单相加。

每个数据类型都有自己的对齐要求(alignment),通常等于其自身大小。例如:

char:1字节对齐
int:4字节对齐(32位系统)
double:8字节对齐
指针:4字节(32位系统)或8字节(64位系统)

计算方式为:成员字节数 + 成员间填充字节数 + 结构体末尾填充字节数。其中:填充字节数由成员之间的对齐要求决定。最终大小需满足结构体整体对齐要求。,在成员相互之间或结构体末尾,可插入**填充字节(padding)**以满足对齐要求

示例:

struct ListNode {
    int val;
    char s[12];
    struct ListNode *next;
 };

分析:
现在,我们一步步计算:

  • int val;

从偏移量 0 开始。
val 占用 4 字节。其对齐要求为 4 字节。
偏移量 0 是 4 的倍数,所以不需要填充。
val 占据内存范围:[0, 3]。
当前偏移量:4。

  • char s[12];

当前偏移量为 4。
s 数组占用 12 字节。char 的对齐要求是 1 字节。
偏移量 4 是 1 的倍数,无需填充。
s 占据内存范围:[4, 15]。
当前偏移量:16。

  • struct ListNode *next;

当前偏移量为 16。
next 是一个指针,在64位系统上占用 8 字节。其对齐要求为 8 字节。
偏移量 16 是 8 的倍数,无需填充。
next 占据内存范围:[16, 23]。
当前偏移量:24。
至此,所有成员都已放置完毕,结构体的“原始”总大小为 24 字节。

内存布局:
[val(4)][s(12)][next(8)]

val 和 s 之间无需填充(4 + 12 = 16,已对齐到4字节)。
next 需从8字节边界开始,当前地址为16(4 + 12),无需填充。
总大小:4 + 12 + 8 = 24字节。

最大成员对齐为8字节(next),因此结构体总大小需是8的倍数。24本身是8的倍数,无需额外填充。


C++中的一些反直觉逻辑记录
https://k3ppf0r.pages.dev/2022/06/03/心得/C++中的一些反直觉逻辑记录/
作者
k3ppf0r
发布于
2022年6月3日
许可协议