我遇到以下代码后:
LocalBusiness
我无法理解为什么我能够访问不存在的p [3](只有p存在单指针但我仍然可以访问p [3],即数组我从来没有创造过)。
它是一些编译器错误还是它是一个功能,或者我不了解C ++的一些基础知识来涵盖这个?
谢谢
答案 0 :(得分:3)
为什么C ++会将指针和指针数组视为同一个东西?
没有。你问为什么它将指针和数组视为一样。
[]
运算符只是指针运算的缩写形式。 a[b]
相当于*(a + b)
。数组名称可以衰减为指针,然后应用指针算法。这是程序员的工作,以确保他们不会超出界限。编译器不可能阻止你离开你的脚。
此外,声称能够“访问”它是一个强有力的断言。那就是UB,很可能会读错内存或者出现段错误。
答案 1 :(得分:2)
不,这不是编译器错误,它是一个非常有用的功能......但是我们不能在这里超越自己,代码的结果被称为Undefined Behaviour
那么,这个功能是什么?所有 naked arrays
实际上是指向第一个元素的指针。 未衰减的数组除外(请参阅What is array decaying?)。
考虑以下代码:
int s =10;
int* array = new int[12];
int *p;
p = array; // p refers to the first element
int* x = p + 7; //advances to the 7th element, compiler never checks bounds
int* y = p + 700; //ditto ...this is obviously undefined
p = &s; //p is now pointing to where s
int* xx = p + 3; //But s is a single element, so Undefined Behaviour
一旦数组被衰减,它只是一个指针...而且一个指针可以递增,递减,解除引用,高级,分配或重新分配。
所以,
cout << p[7] << endl;
是一个有效的C ++程序。但不一定正确。
程序员有责任知道指针是指向单个元素还是数组。但是由于静态分析器和https://github.com/isocpp/CppCoreGuidelines,事情正在发生变化。
另见What are all the common undefined behaviours that a C++ programmer should know about?
答案 2 :(得分:1)
从here开始,数组到指针衰减部分:
从数组类型的左值和右值到指针类型的右值有一个隐式转换:它构造一个指向数组第一个元素的指针。每当数组出现在不期望数组的上下文中时,就会使用此转换,但指针是
答案 3 :(得分:1)
继承自C,C ++允许您处理任何指针,如从该地址开始的数组的第一个元素。 这部分是因为它通过引用传递数组作为指针,所以为了理解你需要能够将指针视为数组。 它还可以在各种情况下使用一些非常整洁且非常高效的代码。
结果是'a' is not recognized as an internal or external command, operable program or batch file.
在这种情况下是一个有效的结构。
但显然它有未定义的行为,因为p[3]
没有指向数组!不幸的是,语言规则(和编译器)不够智能,无法解决这个问题。
C是一种非常低级的语言,在编译或执行期间不会强制执行诸如范围检查之类的好事。