我想知道两者的区别

const int* ptr;

and

int * const ptr; 

以及它是如何工作的。

我很难理解或记住这个。 请帮助。


当前回答

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

其他回答

引用 这个线程

常量指针

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

常量指针的声明如下: <指针>的类型* const <指针>的名称 声明的示例如下: 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 <指针>的类型* <指针>的名称 定义的一个例子可以是: 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打印新值。

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’

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

报价

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为指向int类型的const指针。不允许修改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

请参考以下链接,以更好地了解Const指针和常量指针之间的区别。

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

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