[C算法]番外篇-offset(偏移量)

[C算法]番外篇-offset(偏移量)

Lucas Lv4

“Offset” 这个词直译是 “偏移量”,在计算机科学里,它是一个非常核心且通用的概念。

用一句大白话解释:Offset 就是“相对于起点的距离”

它永远回答同一个问题:“我要找的东西,离头(Base)有多远?”


1. 在 寻找中位数 代码中

在中位数算法里,offset 起到了一个 “微调开关” 的作用。

  • 场景: 数组切分。
  • 问题: 当数组长度是偶数时,我们要切掉中位数(往前走一步,+1);当长度是奇数时,我们要保留中位数(原地不动,+0)。
  • Offset 的作用:
  • 如果是偶数,offset = 1 (向右偏移 1 格)。
  • 如果是奇数,offset = 0 (没有偏移)。
  • 统一公式: start = mid + offset

如果没有 offset 这个变量,就要写两个 if-else。用了它,就把“动”与“不动”统一成了一个数学表达。


2. 在 C 语言 / 内存管理中 (最本质的含义)

C 语言的数组和指针,本质上全都是 基地址 (Base) + 偏移量 (Offset)

想象一把尺子:

  • Base (基地址): 尺子的 0 刻度。
  • Offset (偏移量): 离 0 刻度几厘米。
1
2
3
int arr[] = {10, 20, 30, 40};
// arr 是基地址 (Base Address),假设在内存地址 1000

当写 arr[3] 时,计算机实际在算:

  • 这里 3 就是 Offset(下标偏移)
  • 在 C 库里的 offsetof(struct type, member) 宏,也是问:某个成员变量离结构体开头隔了多少个字节。

3. 在 OpenGL 中 (遇到的坑)

在图形学(OpenGL/DirectX/Vulkan)中,offset 经常让人头大,特别是在处理 VBO (Vertex Buffer Object) 时。

为什么 OpenGL 需要 Offset?

因为 GPU 的显存是一块连续的大肉(Byte Buffer)。我们需要告诉 GPU:哪里是“坐标”,哪里是“颜色”。

假设数据是 交错存储 (Interleaved) 的,一个顶点的结构如下:
{ x, y, z, r, g, b } (每个 float 4 字节,共 24 字节)

当调用 glVertexAttribPointer 时:

  1. 告诉 GPU 读位置 (x,y,z):

    • 从哪开始读?从头开始。
    • Offset = 0
  2. 告诉 GPU 读颜色 (r,g,b):

    • 从哪开始读?不管是第几个顶点,颜色永远在这个顶点的起始位置往后数 12个字节 (3个 float 之后)。
    • Offset = 12 (或者是 (void*)12 )。

    代码对比:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 设置位置属性 (位置 0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
    6 * sizeof(float), // Stride (步长:跳过整个顶点大小)
    (void*)0); // Offset:位置数据在最开头,距离0

    // 设置颜色属性 (位置 1)
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
    6 * sizeof(float), // Stride (步长)
    (void*)(3 * sizeof(float))); // Offset:颜色数据在位置数据后面,距离12字节

总结

不管在哪个领域,看到 offset,就把它想成 “相对距离”

  1. 算法里: 它是逻辑上的修正值(加 1 还是加 0)。
  2. C 指针里: 它是下标(第几个元素)。
  3. OpenGL/文件流里: 它是字节数(跳过多少个字节才能读到要的数据)。
  • 标题: [C算法]番外篇-offset(偏移量)
  • 作者: Lucas
  • 创建于 : 2025-12-24 08:43:32
  • 更新于 : 2025-12-24 16:49:24
  • 链接: https://darkflamemasterdev.github.io/2025/12/24/C算法-番外篇-offset-偏移量/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论