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

rah*_*hmu 142 c pointers const

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

char * const a;
const char * a;
Run Code Online (Sandbox Code Playgroud)

为了理解我写这个小程序的区别:

#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;
}
Run Code Online (Sandbox Code Playgroud)

我编译了程序(使用gcc 3.4)并运行它.输出突出显示了差异:

Before
pc1=ffbfd7e7
*pc1=x
pc2=ffbfd7e7
*pc2=x


After
pc1=ffbfd7e7
*pc1=y
pc2=ffbfd7e6
*pc2=x
Run Code Online (Sandbox Code Playgroud)

但是,我必须编写小程序才能得到答案.如果我离开机器(例如在面试时),我将无法回答这个问题.

有人可以通过评论上面的例子来解释const关键字的运作方式吗?

Alo*_*ave 170

char * const a;
Run Code Online (Sandbox Code Playgroud)

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

const char * a;
Run Code Online (Sandbox Code Playgroud)

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

  • `const char*a`不**表示"指向的数据是常量且不可变的".它只是指针`a`无法写入它.指向的数据可以由别人写.示例:https://gist.github.com/andyli/b4107c8910208fe54764 (52认同)
  • @AndyLi有针对性的数据*有时*可由其他人编写.或者,它可以是真正的常量,例如字符串文字. (4认同)

AAT*_*AAT 90

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

所以,char *const a;你有a,这是一个const指针(*)char.换句话说,你可以改变a指向的字符,但你不能a指出任何不同的东西.

相反有const char* b;b,这是一个指针(*)的charconst.您可以b在任何您喜欢的字符处指向,但您无法使用该字符更改该字符的值*b = ...;.

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

  • 一流的回应.不仅提供了答案,还教育读者如何解析这些类型的声明.我还推荐http://cdecl.org/作为将声明(例如int(*(*foo)(void))[3]转换为有意义的英文文本的网站("声明foo作为指向函数的指针(void)返回指向int")数组3的指针. (13认同)

Joh*_*ode 62

char * const a;
Run Code Online (Sandbox Code Playgroud)

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

const char * a; 
Run Code Online (Sandbox Code Playgroud)

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

请注意,这与

char const * a;
Run Code Online (Sandbox Code Playgroud)

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


Sag*_*kre 23

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

怎么看?按照以下简单步骤识别上面两个.

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

char * const a;
Run Code Online (Sandbox Code Playgroud)

从右到左阅读

现在开始a,

1.毗邻a那里const.

char*(const a);

--->所以aconstant (????).

2.现在就去吧*

烧焦(* (const a));

--->所以, aconstant pointer(????).

3.一起去吧char

(char (* (const a)));

---> a是一个constant pointercharacter可变

a is constant pointer to character variable. 
Run Code Online (Sandbox Code Playgroud)

阅读不容易吗?

类似于第二次宣言

const char * a;
Run Code Online (Sandbox Code Playgroud)

现在再次开始a,

1.毗邻a那里*

--->所以apointer(????)

2.现在有char

---> a是的pointer character,

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

---> acharacter pointer(?????)

3.现在你有了constant

--->所以acharacter pointerconstant可变

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

a is pointer to constant character variable
Run Code Online (Sandbox Code Playgroud)

  • 哦,我没看到。我的教授在我的工程期间教了我这种方法。希望对初学者有帮助。 (2认同)

Joh*_*ent 16

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

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

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

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

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


cni*_*tar 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. */
Run Code Online (Sandbox Code Playgroud)


Bar*_*rel 6

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

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

甲  常量指针不能被重新分配给指向从它最初被分配了一个不同的对象,但它可以被用来修改它指向的对象(称为"指针对象").
因此,引用变量是constpointers的替代语法.

指针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 
}
Run Code Online (Sandbox Code Playgroud)

乐于帮助!祝好运!


jac*_*ack 5

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

a是指针

*a是值

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

如果你说"const*a"那么值是const.(即const char*a;)