我接受了他们问我这个问题的采访
#include<stdio.h>
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;
答案 0 :(得分:28)
<强> 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为零(在所有当前实现中均为true),递增NULL指针实际上是未定义的行为)
和陈述:
(*q)++;
将无法编译,因为尝试修改常量值(指向的整数是常量)
答案 1 :(得分:25)
上述程序将如何表现?
回答相当简单:程序无法编译。
后缀++
需要一个可修改的左值作为其参数; p
不可修改,因为它是const
- 合格。
const
之后的*
表示指针是合格的;如果const
出现在*
之前,就像它在q
的声明中那样,则意味着指针引用的对象是合格的。您可以使用the clockwise/spiral rule解码C声明符语法。
如果从程序中删除p
及其所有引用,以便只保留包含q
的行,则答案是程序显示未定义的行为:您无法对空指针执行算术运算(至少如果结果不是空指针则不行。)
答案 2 :(得分:2)
http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html
他们具体说:
弹出一个有趣的额外功能 现在。这是什么意思?
char c; char * const cp =&amp; c;
真的很简单; cp是指针 一个char,这正是它的意思 如果const不在那里。该 const意味着cp不是 修改,虽然无论它指出什么 可以 - 指针是常量,而不是 它指向的东西。另一个 方式回合是
const char * cp; 这意味着现在cp是一个 普通的,可修改的指针,但是 它指向的东西一定不是 改性。所以,取决于你 选择做,指针和 它指向的东西可能是可修改的 或不;只需选择合适的 声明。
答案 3 :(得分:1)
对于回答这个问题以及关于const和指针的更多问题,你必须要理解一些基本的东西。我将首先口头解释,然后举个例子:
指针对象可以声明为const指针或指向const对象(或两者)的指针:
const指针无法重新分配以指向与最初分配的对象不同的对象,但它可用于修改它指向的对象(称为“指针对象”) 。因此,引用变量是constpointers的替代语法。
另一方面,指向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
}
答案 4 :(得分:0)
我刚刚提供了代码并运行它,
我然后编译它,并且不能修改只读指针的错误,并且在我们的情况下递增,如下面的中止编译
我只想举例说明不能使用常量指针。
网络模拟器ns3的另一个例子,阐明了常量指针的使用。当我们定义将检查到达数据包的错误模型时。 功能na 在IsCorrupt返回true(发生错误)之后,程序可以从其数据缓冲区中删除或删除数据包。
bool IsCorrupt (Ptr<Packet> pkt);
请注意,我们不传递const指针,因此如果IsCorrupt()返回true,则允许函数修改数据包。