IE盒子

搜索
查看: 135|回复: 12

C/C++ 从数组负数下标开始

[复制链接]

4

主题

14

帖子

29

积分

新手上路

Rank: 1

积分
29
发表于 2022-9-23 00:17:37 | 显示全部楼层 |阅读模式
如果我们定义一个长度为 n 的数组,那么理论上下标的范围为 [0,n - 1] 。
但是实际上,在C/C++中,数组的下标可以是负数,而且是可以通过编译的。
int arr[] = { 1,2,3,4 };
int num = arr[-3];
这里需要明确,C/C++ 是不会检查下标时候合法。
因为C要追求速度,如果他要检查下标,就需要在运行的时候,时刻检查下标是否落在 [0,n - 1] 的位置中。
我们可以这样理解,下面两条语句是等价的
arr[2];
*(arr + 2);
也就是  [ \ \ \ ] 是会展开成首地址加一个偏移量。
当然这里有一个很沙雕的写法。


我们要明白,C/C++的代码最终会转换到汇编。


上面的代码可以理解为,在 a,b,c 对应着 [rbp - 4],[rbp - 8],[rbp - 12] 的内存单元。
这里我们发现,相邻的变量,在物理内存上也是相邻的。
所以我们有个邪恶的想法,用指针偷偷的修改a的值。


注意,这样的行为属于未定义行为,每个编译器的实现都不一样
到这里我们可以发现,C/C++对于运行期基本就是放任的。
那么这里,我们可以举一个例子。C++中的类的公有私有属性是编译器的内容,在运行期的时候是不检查的。
因此我们可以写出这样的代码


解释一下为什么
A的内存结构为


这个时候我们强制用一个int * 的指针指向 a
int* p = (int*)&a;


然后我们通过指针修改
*p = 114514;


那就修改了x的值,修改y的值也是同理。
推荐阅读严格鸽:C++虚函数表的位置——从内存的角度
当然这样玩基本上都是UB(未定义行为)



大家可以自行理解为什么会这样

不过有的时候,负数下标还是有点用的


这里需要明白,c++的设计思想——零成本抽象。
也就是你定义一个数组 arr[] 和你定义一堆变量 arr_0,arr_1,arr_2..... 的性能是一样的。
而c++在运行的时候是完全放任,什么都不管,这就是为什么c++没有gc而诸如Java,go等语言有。
因为c++相信程序员,我不检查下标是否越界是因为我相信你不会越界,或者你越界是有目的的。你不回收内存,也一定有自己的目的(
回复

使用道具 举报

3

主题

8

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2022-9-23 00:18:29 | 显示全部楼层
a=>*(a+i)
回复

使用道具 举报

3

主题

6

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2022-9-23 00:19:03 | 显示全部楼层
可以理解成[]只是解引用的语法糖。
回复

使用道具 举报

3

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2022-9-23 00:19:54 | 显示全部楼层
我不回收内存一定是有自己的目的吧[飙泪笑]
回复

使用道具 举报

2

主题

10

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2022-9-23 00:20:49 | 显示全部楼层
假设vector的迭代器是指针不太好吧[捂脸]
回复

使用道具 举报

5

主题

17

帖子

29

积分

新手上路

Rank: 1

积分
29
发表于 2022-9-23 00:21:07 | 显示全部楼层
不是吗
回复

使用道具 举报

4

主题

8

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2022-9-23 00:21:40 | 显示全部楼层
vector的迭代器重载了[] 和加减法。
回复

使用道具 举报

2

主题

8

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2022-9-23 00:22:15 | 显示全部楼层
迭代器就是对指针的封装啊
回复

使用道具 举报

2

主题

11

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2022-9-23 00:22:54 | 显示全部楼层
operator [] 的参数类型不是size_t吗,能取到反向地址吗
回复

使用道具 举报

1

主题

4

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-9-23 00:23:29 | 显示全部楼层
不是,重载了啊。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表