C语言的数组下标a[-1]的问题?

kunikida 2012-07-10 12:44:12
C语言貌似不能定义指定下标的数组,每次系统都强制默认下标从0开始。
比如我可以定义一个数组:a[3]={1,2,3};
但是当我写到a[3]的时候,会报错,越界了,这个我知道。但是为什么我能写a[-1]=0。
为什么?难道向下就不会越界么?
...全文
3589 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
AnYidan 2012-07-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

不奇怪,编译器本来就不对数组的下标进行检查,写a[3]也是不会报错的,你的错误可能是其它原因。再者这两种下标都属于越界访问,结果不可预料,多加小心。
[/Quote]

++
pathuang68 2012-07-10
  • 打赏
  • 举报
回复
你只要很清楚地知道自己的写的代码在干什么都是可以的。
mLee79 2012-07-10
  • 打赏
  • 举报
回复
a[-1] == *( a - 1 ) , 只要你保证 a-1 的地址是有效就可以, 你的例子肯定有问题, 写程序的会经常在一个内存前面写个cookie, 用 p[-1] 去访问很方便地..
northcan 2012-07-10
  • 打赏
  • 举报
回复
a[-1],c语言标准不要求检查数组下标的范围,如果下标超出范围,程序的行为未定义,依赖于具体的编译器实现。即使a[-1]暂时没出问题,也不能这么用吧。程序不能依赖于这种未定义的行为。
hnzmdzcm 2012-07-10
  • 打赏
  • 举报
回复
越界可能破坏其他地方的数据或者程序崩溃
Kunikda 2012-07-10
  • 打赏
  • 举报
回复
学习了,谢谢。
[Quote=引用 1 楼 的回复:]

Assembly code

(gdb) disassemble
Dump of assembler code for function main:
0x00010660 <main+0>: save %sp, -128, %sp
0x00010664 <main+4>: mov 1, %g1
0x00010668 <main+8>: st %g1, [ %fp + ……
[/Quote]
Kunikda 2012-07-10
  • 打赏
  • 举报
回复
恩,我就有几次动态规划的时候用到了a[-1],觉得很方便,但总觉得有越界的嫌疑。现在懂了。谢谢啦。
[Quote=引用 5 楼 的回复:]

在一般情况下,对数组越界访问都是坚决禁止的。但是在某些特定场合,也会有a[-1]这样的访问方式,这和编译器的具体实现有关。
[/Quote]
chenpping 2012-07-10
  • 打赏
  • 举报
回复
在一般情况下,对数组越界访问都是坚决禁止的。但是在某些特定场合,也会有a[-1]这样的访问方式,这和编译器的具体实现有关。
W170532934 2012-07-10
  • 打赏
  • 举报
回复
都是越界。看编译器怎么处理罢了
恨天低 2012-07-10
  • 打赏
  • 举报
回复
gcc version 3.4.6

写a[-1], a[3] 都不会报错。
图灵狗 2012-07-10
  • 打赏
  • 举报
回复
不奇怪,编译器本来就不对数组的下标进行检查,写a[3]也是不会报错的,你的错误可能是其它原因。再者这两种下标都属于越界访问,结果不可预料,多加小心。
恨天低 2012-07-10
  • 打赏
  • 举报
回复

(gdb) disassemble
Dump of assembler code for function main:
0x00010660 <main+0>: save %sp, -128, %sp
0x00010664 <main+4>: mov 1, %g1
0x00010668 <main+8>: st %g1, [ %fp + -32 ]
0x0001066c <main+12>: mov 2, %g1
0x00010670 <main+16>: st %g1, [ %fp + -28 ]
0x00010674 <main+20>: mov 3, %g1
0x00010678 <main+24>: st %g1, [ %fp + -24 ]
0x0001067c <main+28>: clr [ %fp + -36 ]
0x00010680 <main+32>: sethi %hi(0x10400), %g1
0x00010684 <main+36>: or %g1, 0x348, %o0 ! 0x10748
0x00010688 <main+40>: ld [ %fp + -32 ], %o1
0x0001068c <main+44>: ld [ %fp + -28 ], %o2
0x00010690 <main+48>: ld [ %fp + -24 ], %o3
0x00010694 <main+52>: call 0x207f4 <printf@plt>
0x00010698 <main+56>: nop
0x0001069c <main+60>: clr %g1 ! 0x0
0x000106a0 <main+64>: mov %g1, %i0
0x000106a4 <main+68>: ret
0x000106a8 <main+72>: restore
End of assembler dump.
(gdb) l
3 int main()
4 {
5 int a[3] = {1, 2, 3};
6 a[-1] = 0;
7
8 printf("%d,%d,%d", a[0], a[1], a[2]);
9 return 0;
10 }

-1作为下标时是数组之前的一个地址

70,004

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧