这个问题在这里已有答案:
以下声明之间有什么区别?
char * const a;
const char * a;
为了理解我写这个小程序的区别:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv)
{
char a = 'x';
char b = 'y';
char * const pc1 = &a;
const char * pc2 = &a;
printf ("Before\n");
printf ("pc1=%p\n", pc1);
printf ("*pc1=%c\n", *pc1);
printf ("pc2=%p\n", pc2);
printf ("*pc2=%c\n", *pc2);
*pc1 = b;
/* pc1 = &b; */
/* *pc2 = b; */
pc2 = &b;
printf ("\n\n");
printf ("After\n");
printf ("pc1=%p\n", pc1);
printf ("*pc1=%c\n", *pc1);
printf ("pc2=%p\n", pc2);
printf ("*pc2=%c\n", *pc2);
return EXIT_SUCCESS;
}
我编译了程序(使用gcc 3.4)并运行它 . 输出突出显示了差异:
Before
pc1=ffbfd7e7
*pc1=x
pc2=ffbfd7e7
*pc2=x
After
pc1=ffbfd7e7
*pc1=y
pc2=ffbfd7e6
*pc2=x
但是,我必须编写小程序才能得到答案 . 如果我离开机器(例如在面试时),我将无法回答这个问题 .
有人可以通过评论上面的例子来解释 const
关键字如何运作?
11 回答
指的是指针是常量且不可变的,但指针数据不是 .
在这种情况下,您可以使用
const_cast
(在C中)或c样式转换来抛弃常量,因为数据本身不是常量 .表示无法使用指针a写入指向的数据 . 在这种情况下使用
const_cast
(C)或c样式转换来抛弃常量会导致 Undefined Behavior .要解析复杂类型,您可以从变量开始,向左移动,向外螺旋 . 如果没有任何数组或函数需要担心(因为它们位于变量名称的右侧),这将成为从右到左阅读的情况 .
所以对于
char *const a;
,你有一个a
,它是const
指针(*
)到char
. 换句话说,你可以改变a
所指向的字符,但你不能使a
指向任何不同的点 .与
const char* b;
相反,你有b
,这是一个char
的指针(*
),它是const
. 您可以在任何您喜欢的字符处指定b
点,但不能使用*b = ...;
更改该字符的值 .当然,你也可以同时拥有两种常量:
const char *const c;
.*a
是可写的,但a
不是;换句话说,您可以修改a
指向的值,但不能修改a
本身 .a
是一个指向char
的常量指针 .a
是可写的,但*a
不是;换句话说,您可以修改a
(将其指向新位置),但不能修改a
指向的值 .请注意,这与
在这种情况下,
a
是指向const char
的指针 .现在你知道了
char * const a
和const char * a
之间的区别 . 很多时候,如果它是一个常量指针或指向常量变量的指针,我们会感到困惑 .怎么看?按照以下简单步骤识别上面两个 .
让我们看看如何阅读下面的声明
从右到左阅读
现在从
a
开始,1 . 与
a
相邻,有const
.char *
(const a)
;--->所以
a
是constant
(????)
.2 . 现在去吧
*
char
(* (const a))
;--->所以
a
是constant
pointer
到(????)
.3 . 一起去,有
char
(char (* (const a)))
;--->
a
是一个constant
pointer
到character
变量阅读不容易吗?
类似于第二次宣言
现在再次从
a
开始,1 . 毗邻
a
有*
--->所以
a
是pointer
到(????)2 . 现在有
char
--->所以
a
是pointer
character
,嗯这没有任何意义!所以洗牌
pointer
和character
--->所以
a
是character
pointer
到(?????)
3 . 现在你有
constant
--->所以
a
是character
pointer
到constant
变量但是,虽然你可以弄清楚声明的含义,但让它听起来更合理 .
理解差异的最简单方法是考虑不同的可能性 . 有两个对象需要考虑,指针和指向的对象(在这种情况下,'a'是指针的名称,指向的对象是未命名的,类型为char) . 可能性是:
什么都不是常量
指针是const
指向的对象是const
指针和指向对象都是const .
这些不同的可能性可以用C表示如下:
char * a;
char * const a;
const char * a;
const char * const a;
我希望这说明了可能存在的差异
第一个是指向char的常量指针,第二个是指向常量char的指针 . 您没有触及代码中的所有案例:
以上是很好的答案 . 这是一个记住这个的简单方法:
a是指针
现在如果你说“const a”那么指针就是const . (即char * const a;)
如果你说“const * a”,则值为const . (即const char * a;)
我将首先口头解释,然后举个例子:
指针对象可以声明为const指针或指向const对象(或两者)的指针:
无法重新分配 const pointer 以指向不同的对象来自最初分配的对象,但它可用于修改它指向的对象(称为"pointee") .
因此,引用变量是constpointers的替代语法 .
另一方面, pointer to a const object 可以重新分配以指向同一类型或可转换类型的另一个对象,但它不能用于修改任何对象 .
const pointer to a const object 也可以声明,既不能用于修改指针,也不能重新指定指向另一个对象 .
例:
乐于帮助!祝好运!
您可以使用cdecl实用程序或其在线版本,例如https://cdecl.org/
例如:
void (* x)(int (*[])());
是declare x as pointer to function (array of pointer to function returning int) returning void
试着以简单的方式回答:
常量指针:
指针是不变的!即,它所持有的地址不能改变 . 它将存储在只读存储器中 .
让我们尝试更改指针的地址以了解更多:
这意味着一旦常量指针指向它永远存在的东西 .
指针
a
仅指b
.但是,您可以更改
b
的值,例如:指向常量的指针:
指针指向的值无法更改 .
这表明指向常量字符的指针 . 例如 .
这里
a
指向一个常量字符(在这种情况下为's') . 你不能使用a
来改变那个值 . 但是这个声明并不意味着它指向的值是 really a constant ,它只是意味着值是一个常数 . 正如a
所关注的那样 . 您可以通过更改b
的值直接更改b
的值,但不能通过a
指针间接更改该值 .*a='t'; //INVALID b='t' ; //VALID
这表示一个指向char的常量指针 . 它将
a
限制为仅指向b
但是它允许您更改b
的值 .希望能帮助到你!!! :)