В чем разница между этими объявлениями в C?

Что делают следующие объявления в C и C++?

const int * i;
int * const i;
const volatile int ip;
const int *i;

Любое из приведенных выше заявлений неверно?

Если не в чем смысл и различия между ними?

Каковы полезные применения вышеуказанных объявлений (я имею в виду, в какой ситуации мы должны использовать их в C / C++ / встроенном C)?

Если вы собираетесь редактировать грамматику и орфографию, почему бы не ввести «Если» с «I», а не «!»?

Eclipse 24.10.2008 10:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
1
1 392
2

Ответы 2

const int * i;

i - указатель на постоянное целое число. i можно изменить так, чтобы он указывал на другое значение, но значение, на которое указывает i, изменить нельзя.

int * const i;

i - это постоянный указатель на непостоянное целое число. Значение, на которое указывает i, можно изменить, но нельзя изменить i, чтобы указать на другое значение.

const volatile int ip;

Это довольно сложно. Тот факт, что ip - это const, означает, что компилятор не позволит вам изменить значение ip. Однако теоретически его все еще можно модифицировать, например взяв его адрес и используя оператор const_cast. Это очень опасно и не очень хорошая идея, но это разрешено. Квалификатор volatile указывает, что каждый раз, когда осуществляется доступ к ip, он всегда должен быть перезагружен из памяти, то есть НЕ должен кэшироваться в регистре. Это мешает компилятору выполнять определенные оптимизации. Вы хотите использовать квалификатор volatile, когда у вас есть переменная, которая может быть изменена другим потоком, или если вы используете ввод-вывод с отображением памяти, или в других подобных ситуациях, которые могут вызвать поведение, которого компилятор может не ожидать. Использование const и volatile для одной и той же переменной довольно необычно (но законно) - вы обычно увидите одно, но не другое.

const int *i;

Это то же самое, что и первое объявление.

Вы уверены, что volatile гарантирует, что значение, доступное только для чтения, будет отражать изменения, сделанные в другом потоке? На каких реализациях? А как насчет многоядерных архитектур с некогерентным кешем?

Steve Jessop 24.10.2008 12:51

Если переменная - объявленconst (как здесь ip), то удаление const с помощью const_cast для изменения значения является неопределенным поведением. Кроме того, не гарантируется, что volatile сделает изменения видимыми для другого потока. Определенные компиляторы могут дать такую ​​гарантию.

Anthony Williams 24.10.2008 17:51

Энтони совершенно прав. volatile не делает вашу переменную зависимой от потоков. кроме того, исключение const из переменной, объявленной const, является неопределенным поведением.

Johannes Schaub - litb 08.11.2008 19:42

volatile гарантирует следующее AFAIK, хранилища и чтения не будут переупорядочены или оптимизированы, компилятор не будет предполагать, что значение не будет изменено между ссылками на var

Hasturkun 01.07.2009 13:53

Несколько слов из мира микроконтроллеров: регистр (например, аналого-цифровой регистр) нередко бывает изменчивой константой. Ознакомьтесь с заголовочными файлами по умолчанию для микросхем HC11 и PIC, если у вас есть копия CodeWarrior.

Conspicuous Compiler 01.07.2009 14:51
const и «константа» - это разные вещи. const означает только чтение. Выражение постоянный - это выражение, которое может (а в некоторых случаях должно) вычисляться во время компиляции. Пример различия: const int r = rand();
Keith Thompson 27.05.2015 20:49

Вы читаете объявления переменных в C / C++, так сказать, справа налево.

const int *i;  // pointer to a constant int (the integer value doesn't change)

int *const i;  // constant pointer to an int (what i points to doesn't change)

const volatile int ip;  // a constant integer whose value will never be cached by the system

У каждого из них свои цели. В любом учебнике C++ или приличном ресурсе есть объяснения по каждому из них.

Другие вопросы по теме