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

时间:2012-04-10 15:37:35

标签: c pointers const

以下声明之间有什么区别?

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 个答案:

答案 0 :(得分:169)

char * const a;

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

const char * a;

表示无法使用指针a写入指向的数据。 在这种情况下使用const_cast(C ++)或c样式转换来抛弃常量会导致未定义行为

答案 1 :(得分:87)

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

因此,对于char *const a;,您有一个a指针(const指向* char。换句话说,您可以更改a所指向的字符,但不能使a指向任何不同的字符。

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

你当然也可以同时拥有这两种风格:const char *const c;

答案 2 :(得分:60)

char * const a;

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

const char * a; 

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

请注意,这与

相同
char const * a;

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

答案 3 :(得分:22)

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

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

让我们看看如何阅读以下声明

char * const a;

从右到左阅读

现在从a开始,

1。与a相邻,有const

char * (const a);

---&GT;因此aconstant (????)

2。现在,你得到*

char (* (const a));

---&GT;因此aconstant pointer(????)

3。一直走,有char

(char (* (const a)));

---&GT; aconstant pointercharacter变量

a is constant pointer to character variable. 

难道不容易阅读吗?

类似于第二次声明

const char * a;

现在再次从a开始,

1。与a相邻的是*

---&GT;因此apointer到(????)

2。现在有char

---&GT;所以apointer character

那没有任何意义!所以随机播放pointercharacter

---&GT;因此acharacter pointer(?????)

3。现在你有constant

---&GT;所以acharacter pointerconstant变量

但是,虽然你可以弄清楚声明的含义,但让它听起来更合理。

a is pointer to constant character variable

答案 4 :(得分:14)

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

  1. 没有什么是const
  2. 指针是const
  3. 指向的对象是const
  4. 指针和指向对象都是const。
  5. 这些不同的可能性可用C表示如下:

    1. char * a;
    2. char * const a;
    3. const char * a;
    4. const char * const a;
    5. 我希望这能说明可能的差异

答案 5 :(得分: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. */

答案 6 :(得分:5)

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

a是一个指针

* a是值

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

如果你说“const * a”,则值为const。 (即const char * a;)

答案 7 :(得分:5)

我将首先口头解释,然后举例说明:

指针对象可以声明为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 
}

乐意为您服务!祝你好运!

答案 8 :(得分:2)

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

例如:

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

答案 9 :(得分: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!.

答案 10 :(得分: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的值。

希望它有所帮助! :)