C 为什么我的代码没有限制?

C 为什么我的代码没有限制?,c,arrays,memory,C,Arrays,Memory,这是我的代码: #include<stdio.h> int main() { int vet[10], i; for(i=30; i<=45; i++) { scanf("%d", &vet[i]); } for(i=30; i<=45; i++) printf(" %d ", vet[i]); for(i=30; i<=45; i++) printf("

这是我的代码:

#include<stdio.h>

int main()
{
    int vet[10], i;

    for(i=30; i<=45; i++)
    {
        scanf("%d", &vet[i]);
    }

    for(i=30; i<=45; i++)
        printf(" %d ", vet[i]);

    for(i=30; i<=45; i++)
        printf(" %x", &vet[i]);

    return 0;
}
并返回:

1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  /*I put space to indent*/

22ff6c 22ff70 22ff74 22ff78 22ff7c 22ff80 22ff84 22ff88 22ff8c 22ff90 22ff94 22ff98     22ff9c 22ffa0 22ffa4 22ffa8

在访问数组进行读写操作时,C语言不检查边界。由程序作者确保程序只访问有效的数组元素


在本例中,您将值写入声明数组之外的内存地址。在这种情况下,您有时可能会遇到分段冲突(
SIGSEGV
),但您可能只是“幸运”——实际上是不幸的——并且在运行时不会遇到任何问题。

C不强制执行数组边界。在该语言中,保持在限制范围内是您的责任-它会让您做明显错误的事情,但在运行时可能会崩溃。

C语言不仅不会检查数组访问的数组大小限制,这也解释了为什么您会成功地写入数组15次,但是C也没有一种机制将30到45的范围转换为数组的前10个(或15个?)元素的范围


因此,您实际上是在尝试写入数组
vet
的第31到46个元素,该数组只有10个元素。

C不对数组执行边界检查,您正在访问一个超出边界的数组。数组中可能的有效索引是
[0,9]
,但您正在访问
[30,45]

您应该修改代码以仅访问有效索引:

int SIZE = 10;
int vet[SIZE]; 

//...

// not for( i = 30; i <= 45; i++ )
for( i = 0; i < SIZE; ++i ) { /* ... */ }
int SIZE=10;
int vet[尺寸];
//...

//不适用于(i=30;iC非常乐意让您读取和写入超过您设置的边界的数组(在本例中为10)

读超过限制只会给你带来垃圾;写超过限制会做各种疯狂的事情,通常会使你的程序崩溃(或者,如果你运气不好,会覆盖整个硬盘)


你很幸运使用了这个程序,但你不应该继续这样做。在C语言中,你自己负责执行数组的限制。

int-vet[10]
在内存中声明一个由十个整数组成的块。这些内存位置通过
vet[0]
通过
vet[9]访问
。通过
vet
访问内存的任何其他行为都是未定义的行为。内存中绝对可能存在任何内容,并且您很容易损坏程序执行的其余部分。编译器相信您比您所做的更清楚

正如@NigelHarper正确指出的那样,
%p
是打印指针的官方方式。它以十六进制打印。指针可以以十进制打印,但数字本身毫无意义。十六进制使打印更加简洁,并且很容易看到地址之间的差异


也可以使用<代码> %x<代码>打印指针,因为所有的操作都取值并打印成十六进制形式。

< P> C语言不支持检查绑定数组访问。在C++中,如果您试图访问绑定数组内存位置,它将产生分割错误,这会导致进程出错。终止。因为,C不允许,这是预期的行为。

W Wat?
for(i=30;i
45-30=15
。一切看起来都很好。如果我为(i=0;i
for)设置,那么数组的差异就溢出了(i=0;i@X0R40:是的,有一点不同。间隔的大小不是问题所在;实际的索引值才是问题所在。唯一有效的索引值是0到9;任何其他索引值都在数组的边界之外。@X0R40;是的。在第二种情况下,您访问数组时超出了边界,它调用了未定义的行为。因此,让我来获取这个stra好的,我声明了一个int值,在这种情况下,
vet[10]
,所以操作系统给了我一个内存地址,让我们假设
0x100
,所以,操作系统为我保留的内存是
0x100
0x100+10*sizeof(int)
,然后,
0x100认为0x140
,如果我访问了vet[1],实际上,我将访问内存
0x108 trought 0x112(它的范围)
。是否正确?@X0R40关闭。
vet
0x100
0x100+10*sizeof(int)-1
int
大小可以是2,4,8等。指针的标准转换说明符是%p.%x(和%d)“可能有效,但绝不能保证。”奈杰尔哈尔谢谢,那是我的一个严重错误。现在修复。
int SIZE = 10;
int vet[SIZE]; 

//...

// not for( i = 30; i <= 45; i++ )
for( i = 0; i < SIZE; ++i ) { /* ... */ }