"const int*ptr =&i"究竟是什么意思?为什么它接受非常数的地址?

Rüp*_*ure 4 c pointers const constants

在我对const今天意识到的理解中,你的答案非常寻求清除这个主要缺陷.

在我的程序中,我使用了该语句,const int *ptr=&i;但没有使用任何const限定符来变量i.两件事令我困惑:

1)当我试图修改的值使用ptr,在这里我用const int *ptr=&i;,我得到的错误assignment of read-only location '*ptr'|,尽管我还没有声明的变量constqualifier.So什么确切的说法const int *ptr=&i;是说,它是如何从不同int * const ptr=&i;

我把它钻进了我的脑袋,这const int *ptr=&i;意味着指针存储了一个常量的地址,同时int * const ptr=&i;意味着指针本身是常量并且不能改变.但是今天有一位用户在讨论(LINK)中告诉我const int *ptr means the memory pointed to must be treated as nonmodifiable _through this pointer_.我发现这个新东西因为这有点意味着"一些选择指针不能改变价值(而其他人可以改变)".我不知道这样的选择性声明!!但是一个18万的老手证明了那个用户是正确的!!.你也可以以更清晰,更详细和更严谨的方式陈述这一点?``const int*ptr =&i;究竟是什么? mean?

2) I was also told that we can lie to the program in the statement const int *ptr=&i;这是什么意思?为什么我们允许这样做?为什么我们不收到警告如果我们将一个非常量的地址分配给指向ptr一个常量地址的指针?如果它是如此宽容地分配非常量的地址,为什么当我们试图改变那个非常值时会抛出一个错误-constant,这是一个合理的事情,指向变量是一个非常数?

#include <stdio.h>

int main ()
{
 int i=8;
 const int *ptr=&i;
 *ptr=9;
 printf("%d",*ptr);
}
Run Code Online (Sandbox Code Playgroud)

错误: assignment of read-only location '*ptr'|

Eri*_*hil 6

该定义const int *ptr = &i;实际上是说:"我不会修改i通过ptr."它不说,intptr点到是const,它说,ptr不应该被用来进行修改.

这种转换是允许的,因为它是有道理的:既然i不是const,我可以修改它,但我也可以选择不修改它.当我选择不修改时,没有规则被破坏i.并且,如果我创建一个指针i并说"我不打算使用此指针进行修改i",那也没关系.

您希望这样做的原因是您可以将对象的地址传递给采用指向const对象的指针的例程.例如,考虑strlen例程.该strlen程序不会修改它的输入,所以它的参数是一个指针const char.现在,我有一个指针char,我想知道它的长度.所以我打电话strlen.现在我传递一个指针char作为指针参数的参数const char.我们希望转换工作.它是完全合理的:如果我想要的话,可以修改我的char,但strlen例程不会,所以它将它们视为const char.

1)你得到一个错误,*ptr = something;因为你声明ptr为指针const int,但是你违反了你的承诺,不会ptr用来修改int.ptr指向对象的事实const不会否定您不使用ptr修改它的承诺.

2)将非const对象的地址分配给指针并不是一个谎言const.赋值不会说对象是const,它表示不应该使用指针来修改对象.

此外,虽然您没有问过这个,但constC中的属性并不完全绑定.如果您定义了一个对象const,则不应对其进行修改.但是,还有一些情况,其中指针const传递给例程,该例程将其转换为指向非的指针const.这实际上是语言中的缺陷,无法保留以const我们可能更喜欢的方式处理所需的所有信息.一个例子是strchr例程.它的声明是char *strchr(const char *s, int c).该参数sconst char *因为strchr不改变其输入.但是,strchr例程的指针是从s它派生的(它指向字符串中的一个字符).所以,在内部,strchr已经转换const char *char *.

这使您可以编写一个通过代码char *strchr并使用返回指针修改字符串,这是罚款.但这意味着编译器无法完全保护您免受错误的影响,例如传递const char *strchr并使用返回的指针尝试修改字符串,这可能是一个错误.这是C的一个缺点.