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;i45-30=15
。一切看起来都很好。如果我为(i=0;ifor)设置,那么数组的差异就溢出了(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 ) { /* ... */ }