【问题标题】:const pointer fix to a variable variableconst 指针固定到变量变量
【发布时间】:2011-07-28 19:33:01
【问题描述】:

我不知道如何告诉 C 我想要一个不会移动的指针。它总是指向同一个数组。也就是说,数组成员不是恒定的,但数组本身是全局的,因此它位于固定位置。

所以,当我编写这个代码时:

#include <stdio.h>

int v[2]={0, 1};
const int *cpv=v;

int main(void)
{
    v[1]=2;     printf("%d\n", v[1]);
    *(cpv+1)=3; printf("%d\n", v[1]);
    cpv[1]=4;   printf("%d\n", v[1]);
}

并得到这个错误:

constp.c: In function ‘main’:
constp.c:9: error: assignment of read-only location '*(cpv + 4u)'
constp.c:10: error: assignment of read-only location '*(cpv + 4u)'

我了解编译器认为我需要 const int v[2] 才能与 const int *iv 一起使用。如何获得一个常量指针来完成这项工作?

如果您看到错误消息,我什至没有移动指针(例如 pv++)。我只是取消引用它使一些字节错位。

如果我这样做:

int *pv=cpv;
*(pv+1)=5;  printf("%d\n", v[1]);
printf("%p == %p !?\n", cpv, pv);

我收到此警告,但它有效:

constp.c:9: warning: assignment discards qualifiers from pointer target type
pointer# ./constp 
5
0x601020 == 0x601020 !?

谢谢, 贝科。

【问题讨论】:

    标签: c pointers constants variable-assignment readonly


    【解决方案1】:

    移动const 限定符:

    int *const cpv=v;
    

    说明:在 C 声明规则中,这是从标识符开始从右到左读取的:“cpv 是指向int 的常量指针”。您的版本将显示为“cpv 是指向int 常量的指针”。

    请注意,cpv+1*cpv 之后仍会为您提供指向int 的指针;制作指针const 只会阻止++--+=-=

    【讨论】:

    • 谢谢!很好的解释。我的意图正是:指针将始终指向该数组的第一个元素。 ;)
    【解决方案2】:

    您使用的是指向 const 的指针,而不是 const 指针。

    const int *cpv=v;

    应该变成:

    int *const cpv=v;

    【讨论】:

      【解决方案3】:

      指针类型的“向后阅读”:

      const int * p;
      

      在这种情况下,“p”是指向“const int”的(变量)“指针”。从字面上看,向后阅读,'*' 意思是“指针”:“Pointer ... to int const”。

      奇怪的是,以下是同一件事:

      int const * p;  // same thing
      

      向后读,它说,“pointer ... to const int”(同样的意思)。

      所以,如果你希望你的指针是“恒定的”(而不是可变的),你需要向后阅读并做到这一点:

      int * const p;  // p cannot change
      

      现在,“p”是一个指向非常量整数的常量指针。不费吹灰之力,而是向后阅读,“const pointer ... to int”。

      使用上面的“相同的东西”示例,我们现在可以有一个指向一个常量整数的常量指针(以下相同):

      const int * const p;
      int const * const p;
      

      你应该倒着读,它们都说同样的话,“contant pointer ... to constant int”。

      【讨论】:

        【解决方案4】:
        int * const cpv=v;
        

        话虽如此,为什么还需要指针呢?如果您直接访问变量 v,编译器将能够做得更好。如果通过指针,每次访问数组时,生成的代码都必须从内存中读取指针。

        【讨论】:

        • 哈哈!谢谢@Lindy,我总是将我的问题简化为问题的核心。实际上它是一个来自外部 API 的结构的指针,它有很多长名称,我想使用一个看起来像数组的简化版本来访问它的成员,而指针就是这样做的! :) 你很好奇,不是吗? ;) 你可以在这里阅读更多:struct just like an array
        • 我当然很好奇!但是,作为编译器开发人员,有时会要求我检查客户项目。我见过的一种反模式是使用指向全局数组的全局常量指针,强制编译器执行数以千计的额外内存访问,从而减慢程序速度并占用先前的空间。
        【解决方案5】:
        #include <stdio.h>
        
        int v[2]={0, 1};
        //const int       *      cpv=v; // cpv is a pointer to int const
        //      int const *      cpv=v; // cpv is a pointer to const int == same as above ==
                int       *const cpv=v; // cpv is a constant pointer to int
        //      int const *const cpv=v; // cpv is a constant pointer to const int
        //const int       *const cpv=v; // cpv is a constant pointer to int const == same as above ==
        //const int const *const cpv=v; // == same as above ==
        
        int main(void)
        {
            v[1]=2;     printf("%d\n", v[1]);
            *(cpv+1)=3; printf("%d\n", v[1]);
            cpv[1]=4;   printf("%d\n", v[1]);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-11
          • 1970-01-01
          • 1970-01-01
          • 2016-05-03
          相关资源
          最近更新 更多