152

以下声明有什么区别?

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

4

11 回答 11

189
char * const a;

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

const char * a;

表示无法使用指针 a 写入指向的数据。在这种情况下,使用const_cast(C++) 或 c 风格的强制转换来抛弃 const 会导致Undefined Behavior

于 2012-04-10T15:39:53.797 回答
104

要解析复杂的类型,您从变量开始,向左走,然后向外盘旋。如果没有任何数组或函数需要担心(因为它们位于变量名的右侧),这将成为从右到左读取的情况。

所以char *const a;你有a,它是一个指向 a 的const指针 ( *) char。换句话说,您可以更改a指向的字符,但不能a指出任何不同的地方。

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

当然,您也可以同时拥有两种 const-ness 风格:const char *const c;.

于 2014-05-20T09:11:11.037 回答
65
char * const a;

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

const char * a; 

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

请注意,这与

char const * a;

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

于 2012-04-10T16:01:52.107 回答
27

char * const a现在您知道和之间的区别了const char * a。很多时候,如果它是常量指针还是指向常量变量的指针,我们会感到困惑。

怎么读?按照下面的简单步骤来识别上两者。

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

char * const a;

从右到左读

现在开始a

1. 旁边aconst

字符 * (const a);

--->a一个constant (????).

2. 现在继续你得到*

字符(* (const a));

---> a一个constant pointerto也是如此(????)

3. 走过去就有char

(char (* (const a)));

--->aconstant pointer一个character变量

a is constant pointer to character variable. 

不是很容易阅读吗?

同样对于第二次声明

const char * a;

现在再次开始a

1. 旁边a*

--->a一个pointerto (????)

2. 现在有char

---> 原来a如此pointer character

好吧,这没有任何意义!!!所以洗牌pointercharacter

--->所以acharacter pointer(?????)

3. 现在你有constant

---> 所以a是可变character pointerconstant

但是,尽管您可以弄清楚声明的含义,但让它听起来更明智。

a is pointer to constant character variable
于 2014-07-05T07:38:08.587 回答
16

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

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

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

  1. 字符 * a;
  2. 字符 * 常量一个;
  3. 常量字符 * a;
  4. 常量字符 * 常量 a;

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

于 2014-08-13T09:54:54.733 回答
12

第一个是指向 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. */
于 2012-04-10T15:39:57.120 回答
6

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

指针对象可以声明为 const 指针或指向 const 对象的指针(或两者):

const 指针不能重新分配以指向与最初分配的 对象不同的对象,但它可用于修改它指向的对象(称为“指针对象”)。
因此,引用变量是常量指针的另一种语法。

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

指向 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 
}

乐意效劳!祝你好运!

于 2015-08-03T12:14:06.203 回答
5

以上是很好的答案。这是记住这一点的简单方法:

a 是一个指针

*a 是值

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

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

于 2014-12-25T15:08:20.963 回答
2

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

例如:

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

于 2015-02-03T14:54:24.950 回答
1

尝试以简单的方式回答:

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!.
于 2015-02-07T08:24:34.370 回答
0
const char * a;

这表明指向常量字符的指针。例如。

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

这里a 指向一个常量 char('s', 在这种情况下)。你不能a用来改变那个值。但是这个声明并不意味着它指向的值真的是一个常量,它只是意味着这个值是一个就相关而言是恒定a的。您可以b通过更改 的值直接更改 的值b,但不能通过a指针间接更改值。

*a='t'; //INVALID b='t' ; //VALID

char * const a=&b

这声明了一个指向 char 的常量指针。它限制a仅指向,b但它允许您更改b.

希望能帮助到你!!!:)

于 2015-03-31T08:04:36.773 回答