小弟初学C++,看到数组那块,发现和C#差距挺大,有些地方想不清楚。
1. C++ 的数组没有数据越界之说, 比如 定义长度10 的数组 int a[10]; 但 取值 a[20] 是可以取出值来的, 取出来的值就是 a[20] 所对应的内存地址上的值(数组各个值的内存地址是连续的); 那么定义数组时,给数组定义长度还有意义吗? 如果有的话,有什么意义?节约内存吗? 而且给数组直接初始化时,如果长度不够还会报错,比如 int a[1] ={1,2,3}, 但 int a[]={1,2,3} 则没有问题。
2. 在 1 的基础上, 如果有数组 int a[10]; 和变量 int b; 假设 b 的指针和 a[11] 的指针一样, 那修改 a[11] 的值就会把 b 的值也改了,这种情况应该会发生吧,虽然概率比较小,但一旦发生会非常麻烦,因为根本就不知道是哪出的问题,这个问题C++是不是在内部自己做了处理?
1、
a、当然有意义,指定长度后,系统会分配指定长度的内存空间,便于初始化,而不仅仅是什么节约内存,在C里,节约内存应该是合理定义数组长度。
b、初始数组时,如果数组长度有明确指定而初始数据的长度超出数组长度会报告错误,这个是编译器检查的错误,而不是C语言运行时检查的错误,这就好比把一个大的物件放到一个小的容器里去,是不可以的,编译器能发现这个错误。
c、不指定数组长度的初始化操作,就是使用默认初始化值的数量定义数组长度:
int a[] = {1,2,3}
等价于:
int a[3] = {1,2,3}
2、如你所言,如果b的地址是a[11]的地址,那么修改a[11]是会同时导致b的值变化。
这个也就是C语言很让人头痛的地方,因为不做越界检查,一不小心就超出了可操作范围,导致系统崩溃。
这个也是C语言异常强大的地方,通过指针,没有什么不可以。(可以通过a[11]这个指针来修改b的值,是否很神奇?)
是很神奇,但更多的是感到头疼
@xmj112288: 选择了C,你就要接受这个头疼。凡事都是两面的,权利与责任是并重的。
@519740105: C++ 有 运算符 new 和 delete , 是不是每次创建变量都 new 出来就可以避免越界的问题了?
@xmj112288: 不是。越界与否是要你自己在代码里进行控制的。
new运算符是构建指针类型实例的方法,而delete运算符是销毁通过new构建的实例的对应方法,跟指针越界没关系。
直接通过 类型 变量 方式定义的非指针类型变量,在超出作用域后,实例占用的内存空间会自动收复,但通过new创建的指针变量是不会自动收复的,此时就需要delete来执行收复操作(销毁)。
承如楼上数字ID所言,指针以及越界操作这是C以及C++最重要的特点,没有之一。
黑客们用他来做各种事情,常见的溢出攻击主要就是指针干的好事。
不同语言的设计,其实是有初衷以及取向的。
语言或者工具切换,大部份人容易陷入即有思维中...
这正是c++的高级之处