如何回答关于常量指针的面试测试?
我接受了一次采访,他们问我这个问题
#include int main () { int* const p=NULL; int const *q=NULL; p++; q++; printf("%d\n",p); printf("%d\n",q); }
以上程序将如何表现
a)p将增加4个字节;
和q也将增加4个字节;
b)p将为零
q将指向前面4个字节的内存;
c)错误将出现在上述程序中
我无法理解这些陈述之间的区别
int* const p=NULL; int const *q=NULL;
int* const p=NULL;
p
是一个指向整数的常量指针 。 指针IS常量(指针值不能改变); 指向的整数不是常量(可以修改整数值)。
所以声明:
p++;
将无法编译因为尝试修改常量值(指针)。
声明:
(*p)++;
将增加指针p
指向的整数值(但因为p
被赋值为NULL
,所以它将是未定义的行为 )
int const *q=NULL;
q
是一个指向常量整数的指针。指针不是常量(指针值可以改变); 指向IS常量的整数(不能修改整数值)。
所以声明:
q++;
将修改指针q
指向前面4个字节的内存(假设sizeof(int)
为4)。 (因为q
被赋值为NULL
, q
将为0x4
– 我假设NULL为零(在所有当前实现中都是如此),递增NULL指针实际上是未定义的行为 )
声明:
(*q)++;
将无法编译因为尝试修改常量值(指向的整数是常量)
以上程序将如何表现?
这很简单:程序不会编译。
后缀++
需要一个可修改的左值作为其参数; p
不可修改,因为它是const
-qualified。
*
之后的const
表示指针是合格的; 如果const
出现在*
之前,就像它在q
的声明中那样,则意味着指针引用的对象是合格的。 您可以使用顺时针/螺旋规则解码C声明符语法。
如果从程序中删除p
及其所有引用,以便只保留包含q
的行,则答案是程序显示未定义的行为:您不能对空指针执行算术运算(至少如果结果不是null则不行)指针)。
http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html
他们具体说:
现在出现了一个有趣的额外function。 这是什么意思?
char c; char * const cp =&c;
这真的很简单; cp是一个指向char的指针,这正是const不在那里的情况。 const意味着cp不被修改,尽管它指向的是什么 – 指针是常量,而不是它所指向的东西。 反过来是
const char * cp; 这意味着现在cp是一个普通的,可修改的指针,但它指向的东西不能被修改。 因此,根据您的选择,指针和它指向的东西都可以修改或不修改; 只需选择适当的声明。
对于回答这个问题以及关于const和指针的更多问题,你必须要理解一些基本的东西。 我将首先口头解释,然后举个例子:
指针对象可以声明为const指针或指向const对象(或两者)的指针:
const指针不能被重新分配以指向与最初分配的对象不同的对象,但它可以用于修改它指向的对象(称为“指针对象”)。 因此,引用变量是constpointers的替代语法。
另一方面, 指向const对象的指针可以重新分配以指向相同类型或可转换类型的另一个对象,但它不能用于修改任何对象。
还可以声明指向const对象的const指针,既不能用于修改指针,也不能重新指定指向另一个对象。
例:
void Foo( int * ptr, int const * ptrToConst, int * const constPtr, int const * const constPtrToConst ) { *ptr = 0; // OK: modifies the "pointee" data ptr = 0; // OK: modifies the pointer *ptrToConst = 0; // Error! Cannot modify the "pointee" data ptrToConst = 0; // OK: modifies the pointer *constPtr = 0; // OK: modifies the "pointee" data constPtr = 0; // Error! Cannot modify the pointer *constPtrToConst = 0; // Error! Cannot modify the "pointee" data constPtrToConst = 0; // Error! Cannot modify the pointer }
我刚刚提供了代码并运行了它
然后我编译它,并且不能修改只读指针的错误,并且在我们的情况下递增,如下面的中止编译 我只想举例说明我们不能使用const指针的地方 。
来自网络模拟器ns3的另一个例子阐明了常量指针的使用。 当我们定义将检查到达的数据包的错误模型。 函数na在IsCorrupt返回true之后(如果出现错误),程序可以从其数据缓冲区中删除或删除数据包。
bool IsCorrupt (Ptr pkt);
请注意,我们不传递const指针,因此如果IsCorrupt()返回true,则允许函数修改数据包。