【问题标题】:properties of const TYPE* const VARconst TYPE*​​ const VAR 的属性
【发布时间】:2020-05-21 10:18:07
【问题描述】:

我正在尝试了解以下情况:

我们声明了一个指向 const PowerManStateType 的类型指针的 const 变量 pfPowerManStatesPowerManStateType 是一个函数指针 - uint8 (*PowerManStateType)(void);
换句话说,pfPowerManStates 是一个指向函数指针类型的 const 变量的 const 指针。 pfPowerManStates的定义:

const PowerManStateType* const pfPowerManStates = &(pfStates[0]);

它指向一个充满函数指针的数组

到目前为止一切顺利。但后来我看到下面的说法:

NewPowerModeL = pfPowerManStates[CurrentPowerMode]();

这里我们将pfPowerManstate 的值分配给某个变量。 所以,我不能把它缠在我的头上。 声明中没有两个const 关键字是否意味着我们只能阅读非常 数组(&(pfStates[0]) 的第一个值? 我的理解如下: 我有一个 const 类型的 const 指针,指向函数,它接受(void)参数并返回一个 int。 对于它的声明,这个 const 指针接收函数数组pfStates[X] 中第一个函数的地址值,并且由于它的 const,我们不能指向数组pfStates[X] 中的另一个函数。 在这一点上我很困惑,阅读了 5 次帖子并且变得更加困惑,所以我将发布它并希望最好。 谢谢。

【问题讨论】:

  • 您正在调用该函数,并分配返回值不是吗?行尾的那些小括号很重要。
  • 不要发布文本图像,而是将文本复制粘贴为文本。我想将一些“文本”复制粘贴到答案中,但这是不可能的,因为它是图像。
  • 是的,我相信。但是我为什么要调用不同的函数,指针 const 不正是指向第一个函数吗?
  • 标签行下方有一个edit链接。

标签: c pointers constants


【解决方案1】:

声明

NewPowerModeL = pwPowerManStates[CurrentPowerMode]();

可以分解成更小的部分:

PowerManStateType temporary_function_pointer = pwPowerManStates[CurrentPowerMode];
NewPowerModeL = temporary_function_pointer();

因此,您无需将pwPowerManStates 的值分配给NewPowerModeL 变量,而是取消引用pwPowerManStates 指针以获取单个元素。该元素是指向函数的指针。然后你调用这个函数来获取分配给NewPowerModeL的值。


还要注意

NewPowerModeL = pwPowerManStates[CurrentPowerMode]();

应该等价于

NewPowerModeL = pfStates[CurrentPowerMode]();

【讨论】:

    【解决方案2】:

    const 指针不会阻止它被索引(即用作数组)或用于指针运算。你不能只改变指针本身。

    下面有一些更容易理解的代码。

    #include <stdio.h>
    
    const int array[] = {1,2,3,4,5,6,7,8,9,10};
    
    const int *const constptr = array;
    
    int pick(const int *const ptr, int index)
    {
        return ptr[index];
    }
    
    int pick1(const int *const ptr, int index)
    {
        return *(ptr + index);
    }
    
    int main()
    {
        for(int x = 0; x < sizeof(array) / sizeof(array[0]); x++)
        {
            printf("x = %d constptr[%d] == %d\n", x, x, pick(constptr, x));
            printf("x = %d constptr + %d == %d\n", x, x, pick1(constptr, x));
        }
    }
    

    【讨论】:

      【解决方案3】:

      简短的总结:

      const T *p;  // p is writable, *p is not
      T const *p;  // same as above
      

      表达式 *p 的类型为const T,因此您无法为*p 分配新值(您无法写入p 指向的对象)。但是,您可以为p 分配一个新值,将其设置为指向不同的const T 对象。 p 是指向 const 对象的非 const 指针。

      T * const p; // *p is writable, p is not
      

      表达式*p 的类型为T,所以它是可写的——你可以更新p 指向的值。但是,指针p 本身的类型为T * const,因此无法写入 - 您无法将p 设置为指向不同的对象。 p 是一个指向非const 对象的const 指针。

      const T * const p; // neither p nor *p are writable
      T const * const p; // same as above
      

      在这种情况下,*p 的类型为 const Tp 的类型为 const T * const - 两者都不能写入。 p 是一个 const 指向 const 对象的指针。

      在这种特殊情况下:

      const PowerManStateType* const pfPowerManStates = &(pfStates[0]);
      

      pfPowerManStates 指向一个看似函数指针的数组的第一个元素。由于pfPowerManStates 本身就是一个指针,因此您可以像数组一样在其上使用[] 运算符,从而读取 数组中的元素。但是,您不能通过pfPowerManStates 修改任何元素,也不能将其设置为指向不同的对象。

      【讨论】:

      • 这很清楚。我脑子里想得太多了,不能这样看。非常感谢。
      猜你喜欢
      • 2016-09-30
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 2018-05-06
      • 1970-01-01
      相关资源
      最近更新 更多