常量指针与常量值上的指针

下列声明之间的区别是什么?

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关键字是如何运作的?

188118 次浏览
char * const a;

意味着指针是常量和不可变的,而指向的数据不是。
在这种情况下,您可以使用 const_cast(在 C + + 中)或 c 样式强制转换来抛弃常量,因为数据本身不是常量。

const char * a;

意味着不能使用指针 a 写入指向的数据。 在这种情况下,使用 const_cast(C + +)或 c 样式强制转换去掉常量会导致 未定义行为

第一个是指向常量 char 的常量指针,第二个是指向常量 char 的指针。您没有触及代码中的所有案例:

char * const pc1 = &a; /* You can't make pc1 point to anything else */
const char * pc2 = &a; /* You can't dereference pc2 to write. */


*pc1 = 'c' /* Legal. */
*pc2 = 'c' /* Illegal. */


pc1 = &b; /* Illegal, pc1 is a constant pointer. */
pc2 = &b; /* Legal, pc2 itself is not constant. */
char * const a;

*a是可写的,但是 a不是; 换句话说,您可以通过 a修改值 指向,但是您不能修改 a本身。a指向 char的常量指针

const char * a;

a是可写的,但是 *a不是; 换句话说,您可以修改 a(将它指向一个新位置) ,但是不能通过 a修改值 指向

请注意,这与

char const * a;

在这种情况下,a指向 const char的指针

要解析复杂类型,首先从变量开始,向左转,然后向外螺旋。如果没有任何数组或函数需要担心(因为它们位于变量名的右边) ,这就变成了从右向左读的情况。

因此,使用 char *const a;就有了 a,它是一个指向 charconst指针(*)。换句话说,你可以改变 a指向的字符,但是你不能让 a指向任何不同的东西。

const char* b;相反的是 b,它是指向 char的指针(*) ,它是 const。您可以使 b指向任何您喜欢的字符,但是您不能使用 *b = ...;更改该字符的值。

当然,你也可以同时拥有两种口味的常量: const char *const c;

现在您已经知道了 char * const aconst char * a之间的区别。很多时候我们搞不清楚它是一个常量指针还是一个常量变量的指针。

如何阅读? 按照下面的简单步骤来识别上面两个。

让我们看看如何阅读下面的声明

char * const a;

从右往左读

现在从 a开始,

1. 在 a附近有 const

字符 * (const a);

所以 aconstant (????)

2. 现在继续,你会得到 *

字符 (* (const a));

所以 a是从 constantpointer(????)

3. 沿着这条路走,就会看到 char

(char (* (const a)));

- > a是一个从 constant pointercharacter的变量

a is constant pointer to character variable.

不是很好读吗?

对于第二个声明也是如此

const char * a;

现在再从 a开始,

1. 在 a的旁边是 *

所以 apointer到(? ? ?)

2. 现在是 char

所以 apointer character,

这没有任何意义! ! ! 所以把 pointercharacter洗牌

所以 a是从 characterpointer(?????)

3. 现在你有 constant

所以 acharacter pointerconstant变量

但是,尽管您可以理解声明的含义,让我们使它听起来更加合理。

a is pointer to constant character variable

理解这种差异最简单的方法就是考虑不同的可能性。有两个对象需要考虑,指针和指向的对象(在本例中,‘ a’是指针的名称,指向的对象未命名,类型为 char)。可能性有:

  1. 没有什么是永恒的
  2. 指针是 const
  3. 指向的对象是 const
  4. 指针和指向的对象都是常量。

这些不同的可能性可以用 C 表示如下:

  1. Char * a;
  2. Char * const a;
  3. Const char * a;
  4. Const char * const a;

我希望这说明了可能存在的差异

以上都是很好的答案。这里有一个简单的方法来记住这一点:

A 是一个指针

* a is the value

现在如果你说“ const a”,那么指针就是 const (即 char * const a;)

如果你说“ const * a”,那么值就是 const (即 const char * a;)

您可以使用 cdecl 实用程序或其在线版本,如 https://cdecl.org/

例如:

void (* x)(int (*[])()); 是一个 declare x as pointer to function (array of pointer to function returning int) returning void

试着用简单的方式回答:

char * const a;  => a is (const) constant (*) pointer of type char {L <- R}. =>( Constant Pointer )
const char * a;  => a is (*) pointer to char constant             {L <- R}. =>( Pointer to Constant)

常量指针:

指针是常数! !.也就是说,它所持有的地址不能更改。它将存储在只读内存中。

让我们尝试更改指针的地址以了解更多内容:

char * const a = &b;
char c;
a = &c; // illegal , you can't change the address. `a` is const at L-value, so can't change. `a` is read-only variable.

它意味着一旦常量指针指向某个东西,它就是永恒的。

指针 a点只有 b

但是你可以改变 b的值,例如:

char b='a';
char * const a =&b;


printf("\n print a  : [%c]\n",*a);
*a = 'c';
printf("\n now print a  : [%c]\n",*a);

指向常数的指针:

不能更改指针指向的值。

const char *a;
char b = 'b';
const char * a =&b;
char c;
a=&c; //legal


*a = 'c'; // illegal , *a is pointer to constant can't change!.
const char * a;

此状态指向常量字符的指针。 为了..。

char b='s';
const char *a = &b;

这里 a指向一个常量 char (在本例中是‘ s’)。您不能使用 a来更改该值。但是这个声明并不意味着它指向的值是 真的是一个常数,它只是意味着就 a而言这个值是一个常量。 You can change the value of b directly by changing the value of b,but you can't change the value indirectly via the a pointer.

* a = ‘ t’;//无效 B = ‘ t’;//VALID

char * const a=&b

这表示一个指向 char 的常量指针。 它限制 a只能指向 b,但是它允许你改变 b的值。

希望能有所帮助! ! ! :)

我将首先口头解释一下,然后举个例子:

指针对象可以声明为常量指针或指向常量对象的指针(或两者兼而有之) :

常量指针不能被重新分配以指向与它最初分配的对象不同的对象,但是它可以用来修改它所指向的对象(称为“ pointee”)。
因此,引用变量是常量指针的替代语法。

另一方面,可以重新分配 指向常量对象的指针以指向同一类型或可转换类型的另一个对象,但它不能用于修改任何对象。

也可以声明 指向常量对象的常量指针,它既不能用于修改被指向对象,也不能重新分配指向另一个对象。

例如:

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
}

乐意效劳,祝你好运!