一川烟草
满城风絮
梅子黄时雨
在阅读luajit源码的时候,发现在特别多地方使用了负数下标,当时觉得特别奇怪,C的数组中使用负数下标,不是会直接报段错误吗?
其实这里就引出一个问题,下标在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;
}
输出:
显然,b[-1] == a[1]
,也验证了负数下标表示负偏移量。
需要注意的是,如果访问的还是没有申请的空间,无论正数下标还是负数下标,都会段错误的。