【问题标题】:Constant pointer vs Pointer to constant [duplicate]常量指针与指向常量的指针[重复]
【发布时间】:2014-02-23 23:00:40
【问题描述】:

我想知道两者的区别

const int* ptr;

int * const ptr; 

以及它是如何工作的。

我很难理解或记住这一点。 请帮忙。

【问题讨论】:

  • 阅读 Peter linden 的《Deep C Secrets》一书的第 3 章。解读 C 中的声明,您将学习如何使用指针、常量等的任意组合破译任何复杂的声明
  • 骗子在这里:stackoverflow.com/q/890535/694576 不是它曾经接近的地方,因为后者是关于 C++ 的。
  • @user694733 另一方面,它让我感觉有多少开发人员希望为社区做出贡献,问题的状态对他们来说并不重要............在次:)

标签: c pointers constants


【解决方案1】:
const int* ptr; 

声明ptr 指向const int 类型的指针。 ptr本身可以修改,但ptr指向的对象不能修改。

const int a = 10;
const int* ptr = &a;  
*ptr = 5; // wrong
ptr++;    // right  

虽然

int * const ptr;  

声明ptr 一个const 指向int 类型的指针。 ptr不允许修改,但ptr指向的对象可以修改。

int a = 10;
int *const ptr = &a;  
*ptr = 5; // right
ptr++;    // wrong

一般来说,我更喜欢这样的声明,它易于阅读和理解(从右到左阅读):

int const  *ptr; // ptr is a pointer to constant int 
int *const ptr;  // ptr is a constant pointer to int

【讨论】:

  • 在第二种情况下,我们不能在初始化后指向NULL吗?
  • 我刚刚意识到即使是这个代码int i = 10; const int* ptr = &i; 也可以工作。这意味着ptr 不必总是指向一个常量值。你也可以通过它指向一个变量值。只是你永远无法修改ptr指向的值。
  • 即使它是重复的,这个答案是迄今为止最好的......
  • @JinKwon 当然可以,但意义完全不同。
  • @JinKwon const int * const aa 声明为 const 指向 const int 的指针。在这种情况下,aa*a 所指向的对象都不应被修改。
【解决方案2】:
const int * ptr;

表示指向的数据是常量和不可变的,但指针不是。

int * const ptr;

表示指针是常量和不可变的,但指向的数据不是。

【讨论】:

  • 指向const 的指针并没有说明指针指向的对象是否为const。将指针定义为指向const 的指针只会影响我们可以使用指针做什么。
【解决方案3】:

1) 常量指针: 这些类型的指针是不能改变它们指向的地址的指针。这意味着假设有一个指针指向一个变量(或存储该变量的地址)。现在如果我们尝试将指针指向其他变量(或者尝试让指针存储其他变量的地址),那么常量指针就无法做到这一点。

一个常量指针被声明为:int *const ptr('const'的位置使得指针'ptr'为常量指针)

2) 指向常量的指针: 这些类型的指针不能改变它们所指向的值。这意味着他们无法更改他们持有的地址的变量的值。

指向常量的指针声明为:const int *ptr('const' 的位置使指针'ptr' 成为指向常量的指针。

示例

常量指针

#include<stdio.h>

int main(void)
{
    int a[] = {10,11};
    int* const ptr = a;

    *ptr = 11;

    printf("\n value at ptr is  : [%d]\n",*ptr);
    printf("\n Address pointed by ptr  : [%p]\n",(unsigned int*)ptr);

    ptr++;
    printf("\n Address pointed by ptr  : [%p]\n",(unsigned int*)ptr);

    return 0;
}

现在,当我们编译上面的代码时,编译器会报错:

practice # gcc -Wall constant_pointer.c -o constant_pointer
constant_pointer.c: In function ‘main’:
constant_pointer.c:13: error: increment of read-only variable ‘ptr’

因此我们在上面非常清楚地看到编译器抱怨我们无法更改常量指针所持有的地址。

指向常量的指针

#include<stdio.h>

int main(void)
{
    int a = 10;
    const int* ptr = &a;


    printf("\n value at ptr is  : [%d]\n",*ptr);
    printf("\n Address pointed by ptr  : [%p]\n",(unsigned int*)ptr);

    *ptr = 11;

    return 0;
}

现在,当上面的代码被编译时,编译器会报错:

practice # gcc -Wall pointer_to_constant.c -o pointer_to_constant
pointer_to_constant.c: In function ‘main’:
pointer_to_constant.c:12: error: assignment of read-only location ‘*ptr’

因此在这里我们也看到编译器不允许指向常量的指针改变被指向的变量的值。

Quotation

【讨论】:

    【解决方案4】:

    参考 This Thread

    常量指针

    让我们首先了解什么是常量指针。常量指针是不能改变其持有地址的指针。换句话说,我们可以说,一旦一个常量指针指向一个变量,它就不能指向任何其他变量。

    常量指针声明如下:
    &lt;type of pointer&gt; * const &lt;name of pointer&gt;
    示例声明如下所示:
    int * const ptr;
    让我们用一个小代码来说明这些类型的指针:

    #include<stdio.h>
    
    int main(void)
    {
        int var1 = 0, var2 = 0;
        int *const ptr = &var1;
        ptr = &var2;
        printf("%d\n", *ptr);
    
        return 0;
    } 
    

    在上面的例子中:

    • 我们声明了两个变量 var1 和 var2
    • 已声明常量指针“ptr”并指向 var1
    • 接下来,ptr 指向 var2。
    • 最后,我们尝试打印 ptr 指向的值。

    指向常量的指针

    从名字可以看出,一个不能改变它所指向的变量值的指针被称为常量指针。这些类型的指针可以改变它们指向的地址,但不能改变保存在这些地址的值。

    指向常量的指针定义为: const &lt;type of pointer&gt;* &lt;name of pointer&gt; 定义的一个例子可能是: const int* ptr; 让我们用一个小代码来说明一个指向常量的指针:

     #include<stdio.h>
    
    int main(void)
    {
        int var1 = 0;
        const int* ptr = &var1;
        *ptr = 1;
        printf("%d\n", *ptr);
    
        return 0;
    } 
    

    在上面的代码中:

    • 我们定义了一个值为 0 的变量 var1
    • 我们定义了一个指向变量 var1 的常量的指针
    • 现在,我们试图通过这个指针改变 var1 的值
    • 使用 printf 打印新值。

    【讨论】:

    • 我一般不做作业...url answers 不建议伴侣...下次发布答案,而不是网址...+1 ! :)
    • 您应该提到这些是非编译示例,而不是正确使用示例。
    【解决方案5】:
    const int* ptr;
    

    是指向常量(内容)的指针。您可以修改指针。例如ptr = NULLptr++,但不可能修改内容。

    int * const ptr;
    

    是一个常量指针。反之亦然。 不允许修改指针,但允许修改指针指向的内容,例如*ptr += 5.

    【讨论】:

      【解决方案6】:
      int i;
      int j;
      
      int * const ptr1 = &i;
      

      编译器会阻止你更改ptr1

      const int * ptr2 = &i;
      

      编译器会阻止你更改*ptr2

      ptr1 = &j; // error
      *ptr1 = 7; // ok
      
      ptr2 = &j; // ok
      *ptr2 = 7; // error
      

      请注意,您仍然可以更改*ptr2,只是不能直接输入*ptr2

      i = 4;
      printf("before: %d\n", *ptr2); // prints 4
      i = 5;
      printf("after: %d\n", *ptr2); // prints 5
      *ptr2 = 6; // still an error
      

      您还可以拥有具有这两种功能的指针:

      const int * const ptr3 = &i;
      
      ptr3 = &j; // error
      *ptr3 = 7; // error
      

      【讨论】:

        【解决方案7】:

        请参考以下链接更好地了解Const指针和Pointer on a constant value的区别。

        constant pointer vs pointer on a constant value

        【讨论】:

          【解决方案8】:

          const int* ptr; 这里认为 *ptr 是恒定的,*ptr 不能再次更改

          int * const ptr; 而这里认为 ptr 是一个常数,不能再改变

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-04-22
            • 1970-01-01
            • 2020-03-25
            • 2020-10-23
            • 1970-01-01
            • 2021-04-19
            • 2013-01-04
            • 1970-01-01
            相关资源
            最近更新 更多