C++

C++中负数下标

C++

Posted by bbkgl on December 15, 2019

一川烟草

满城风絮

梅子黄时雨

在阅读luajit源码的时候,发现在特别多地方使用了负数下标,当时觉得特别奇怪,C的数组中使用负数下标,不是会直接报段错误吗?

20200112220102.png

其实这里就引出一个问题,下标在C/C++中,代表的实际意义是什么?

下标的意义

可以说,在碰到负数下标这个操作之前,我根本就没思考过,为什么会存在下标索引这个操作呢,为什么下标会从0开始?

在此之前,可以先思考一个问题:数组是什么?底层实现?

数组是什么

众所周知,数组其实就是一块连续的内存空间。通常来说,数组是将相同类型的元素放一起组成的一种结构。

相同类型代表什么?同样大小的地址空间占用。

所以如果更准确地描述数组,那么数组应该是由多块同样大小的连续地址空间组成的一种结构。

于是就可以想到,那对于一个数组来说,取其中任意连续的几个元素,就会构成一个子数组?是的!

关于下标

从数组是“由多块同样大小的连续地址空间组成的一种结构”出发,很容易就能想到,那下标就是一个从首地址开始计数的偏移量,用来访问内存的一种简单索引。

同样的,数组下标为什么从0开始呢?因为0表示0偏移量,也就是数组首地址处记录的元素值。

负数下标

说了那么多,负数下标表示什么?负偏移量

如果说非负数下标是往前,那么负数下标就是往后了。

从内存角度来说,就是往前寻址了,也就是往低地址寻址。

写个简单的例子:

#include <iostream>
#include <cstdio>
#include <cstring>

int main() {
    int a[10] = {1, 2, 3, 4};
    int *b = &a[2];
    printf("%d", b[-1]);
    return 0;
}

输出:

20200112220157.png

显然,b[-1] == a[1],也验证了负数下标表示负偏移量

需要注意的是,如果访问的还是没有申请的空间,无论正数下标还是负数下标,都会段错误的。