свойства const TYPE * const VAR - PullRequest
0 голосов
/ 05 февраля 2020

Я пытаюсь понять следующую ситуацию:

У нас есть объявление переменной const pfPowerManStates указателя типа на const PowerManStateType. PowerManStateType является указателем на функцию - uint8 (*PowerManStateType)(void);
Другими словами, pfPowerManStates является указателем const на переменную const типа указатель функции. определение pfPowerManStates:

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

И оно указывает на массив, полный указателей на функции

Пока все хорошо. Но позже я вижу следующее утверждение:

NewPowerModeL = pfPowerManStates[CurrentPowerMode]();

Здесь мы присваиваем значение pfPowerManstate некоторой переменной. Так что я не могу обернуть это вокруг своей головы. Разве наличие в объявлении двух ключевых слов const не означает, что мы можем ПРОЧИТАТЬ только самое первое значение массива (&(pfStates[0])? Я понимаю следующее: у меня есть константный указатель типа константный указатель на функцию, которая принимает (void) аргументы и возвращает int. Для своего объявления этот указатель const получает значение адреса первой функции в массиве функций pfStates[X], а поскольку его const, мы не можем указывать на другую функцию в массиве pfStates[X]. Я очень запутался в этом пункте, прочитал пост 5 раз и стал еще более запутанным, поэтому я просто опубликую его и надеюсь на лучшее. Спасибо.

Ответы [ 3 ]

3 голосов
/ 05 февраля 2020

Оператор

NewPowerModeL = pwPowerManStates[CurrentPowerMode]();

можно разбить на более мелкие части:

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

Таким образом, вы не можете присвоить значение pwPowerManStates переменной NewPowerModeL, вместо этого вы разыменовываете указатель pwPowerManStates, чтобы получить один элемент. Этот элемент является указателем на функцию. И затем вы вызываете эту функцию, чтобы получить значение для присвоения NewPowerModeL.


Также обратите внимание, что

NewPowerModeL = pwPowerManStates[CurrentPowerMode]();

должно быть эквивалентно

NewPowerModeL = pfStates[CurrentPowerMode]();
2 голосов
/ 05 февраля 2020

Краткое резюме:

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 T, а p имеет тип const T * const - ни может быть написано p - это указатель const на const объект.

В данном конкретном случае:

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

pfPowerManStates указывает на первый элемент массива, который выглядит как указатель на функцию. Поскольку pfPowerManStates сам по себе является указателем, вы можете использовать оператор [] для него как массив и, таким образом, читать элементы из массива. Однако вы не можете изменить ни один из элементов с помощью pfPowerManStates, и при этом вы не можете установить его так, чтобы он указывал на другой объект.

1 голос
/ 05 февраля 2020
Указатель

const не препятствует его индексации (ie. Используется в качестве массива) или используется в арифметике указателей c. Вы не можете изменить только указатель.

Ниже у вас есть немного более понятный код.

#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));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...