您现在的位置是:主页 > news > 学做网站好做吗/最新网络推广平台

学做网站好做吗/最新网络推广平台

admin2025/5/5 21:03:08news

简介学做网站好做吗,最新网络推广平台,重庆网站建设帝维科技,静态网页毕业设计论文从 C 开始 边界对齐 看到下列结构体,使用 sizeof 可得该结构体大小为 24 个字节 typedef struct {char a; // 1 个字节double c; // 8 个字节int b; // 4 个字节 } AType;C 边界对齐规则 那为什么需要对齐呢?原因也很简单,即一次读写…

学做网站好做吗,最新网络推广平台,重庆网站建设帝维科技,静态网页毕业设计论文从 C 开始 边界对齐 看到下列结构体,使用 sizeof 可得该结构体大小为 24 个字节 typedef struct {char a; // 1 个字节double c; // 8 个字节int b; // 4 个字节 } AType;C 边界对齐规则 那为什么需要对齐呢?原因也很简单,即一次读写…

从 C 开始

边界对齐

看到下列结构体,使用 sizeof 可得该结构体大小为 24 个字节

typedef struct {char   a; // 1 个字节double c; // 8 个字节int    b; // 4 个字节
} AType;

C 边界对齐规则

那为什么需要对齐呢?原因也很简单,即一次读写就能把整个数给拿出来(众所周知内存的读写对于 CPU 来说开销是蛮大的)

对于 x86 对齐只是建议而不是强制,而对于 MIPS 必须强制对齐

优化结构体存储大小

由于对齐规则的存在,所以可以调整结构体内字段顺序来优化存储大小。如下面优化过的结构体大小为 16 个字节

typedef struct {double c; // 8 个字节int    b; // 4 个字节char   a; // 1 个字节
} BType;

此时我心里便有了一个小问号,调整字段顺序这么简单的事情应该交由编译器做,而不是交给程序员处理。

那为什么没有交由编译器做呢?

内存中按序存放

结构体中的字段在内存中是按序存放的

#include <stdio.h>typedef struct {double c; // 8 个字节int    b; // 4 个字节char   a; // 1 个字节
} BType;typedef char* ptr;void main() {BType b = {1.0, 2, 'a'};printf("%d\n", *(p + 8)); // 输出 2
}

看回 Java

字段重新排列

public class AlignDemo {public static void main(String[] args) {AClass o = new AClass();System.out.println(ClassLayout.parseInstance(o).toPrintable());}public static class AClass {char a;double b;int c;}
}
AlignDemo$AClass object internals:OFFSET  SIZE     TYPE DESCRIPTION                               VALUE0     4          (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)4     4          (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)8     4          (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)12     4      int AClass.c                                  016     8   double AClass.b                                  0.024     2     char AClass.a                                   26     6          (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 6 bytes external = 6 bytes total

最终整个对象大小要补足为 8 的整数倍

可见字段顺序和类中字段顺序是不一致的,因为编译器做了优化用以压缩空间

那为什么 Java 却能这样优化呢?Java 对数据的访问做了严格的限制,指针都没有,更别提上文的骚操作了

又见 Redis

负数索引

以下代码摘自 Redis 的 sds.h

typedef char *sds;struct sdshdr64 {uint64_t len;uint64_t alloc;unsigned char flags;char buf[];
};static inline size_t sdsavail(const sds s) {unsigned char flags = s[-1]; // 这是什么骚操作?...
}

因为 C 数组是没有边界检查的,所以负数索引不会报错。sds 其实是一个 char 指针,上面说到 C 结构体在内存中是按序存放的,不妨把他想象成一个数组。往前走一个 char 的宽度,便能取得 flags。