首页 文章

常量指针与常量值上的指针[重复]

提问于
浏览
136

这个问题在这里已有答案:

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

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 回答

  • 77
    char * const a;
    

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

    const char * a;
    

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

  • 22

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

    所以对于 char *const a; ,你有一个 a ,它是 const 指针( * )到 char . 换句话说,你可以改变 a 所指向的字符,但你不能使 a 指向任何不同的点 .

    const char* b; 相反,你有 b ,这是一个 char 的指针( * ),它是 const . 您可以在任何您喜欢的字符处指定 b 点,但不能使用 *b = ...; 更改该字符的值 .

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

  • 165
    char * const a;
    

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

    const char * a;
    

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

    请注意,这与

    char const * a;
    

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

  • 59

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

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

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

    char * const a;
    

    从右到左阅读

    现在从 a 开始,

    1 . 与 a 相邻,有 const .

    char * (const a) ;

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

    2 . 现在去吧 *

    char (* (const a)) ;

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

    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

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

    3 . 现在你有 constant

    --->所以 acharacter pointerconstant 变量

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

    a is pointer to constant character variable
    
  • 13

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

    • 什么都不是常量

    • 指针是const

    • 指向的对象是const

    • 指针和指向对象都是const .

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

    • char * a;

    • char * const a;

    • const char * a;

    • const char * const a;

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

  • 0

    第一个是指向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. */
    
  • 1

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

    a是指针

    • a是值

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

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

  • 5

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

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

    无法重新分配 const pointer 以指向不同的对象来自最初分配的对象,但它可用于修改它指向的对象(称为"pointee") .
    因此,引用变量是constpointers的替代语法 .

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

    const pointer to a const object 也可以声明,既不能用于修改指针,也不能重新指定指向另一个对象 .

    例:

    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 
    }
    

    乐于帮助!祝好运!

  • 2

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

    例如:

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

  • 12

    试着以简单的方式回答:

    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!.
    
  • 5
    const char * a;
    

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

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

    这里 a 指向一个常量字符(在这种情况下为's') . 你不能使用 a 来改变那个值 . 但是这个声明并不意味着它指向的值是 really a constant ,它只是意味着值是一个常数 . 正如 a 所关注的那样 . 您可以通过更改 b 的值直接更改 b 的值,但不能通过 a 指针间接更改该值 .

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

    char * const a=&b
    

    这表示一个指向char的常量指针 . 它将 a 限制为仅指向 b 但是它允许您更改 b 的值 .

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

相关问题