Рассматривать:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
Эти две функции одинаковы во всех аспектах или есть разница?
Меня интересует ответ для языка C, но если есть что-то интересное в языке C ++, я бы тоже хотел знать.
Ответы:
const T
иT const
идентичны. С типами указателей все становится сложнее:const char*
указатель на константуchar
char const*
указатель на константуchar
char* const
постоянный указатель на (изменяемый)char
Другими словами, (1) и (2) идентичны. Единственный способ сделать указатель (а не указатель)
const
- использовать суффикс-const
.Вот почему многие люди предпочитают всегда ставить
const
справа от шрифта (стиль «Восточная константа»): это делает его расположение относительно типа последовательным и легким для запоминания (это также, по некоторым данным, упрощает обучение начинающих. ).источник
Уловка состоит в том, чтобы прочитать декларацию в обратном порядке (справа налево):
Оба они одно и то же. Следовательно:
Уловка с обратным чтением особенно полезна, когда вы имеете дело с более сложными объявлениями, такими как:
источник
char const *
, читается слева направо: "указатель, константа, символ". Это указатель на const char. Когда вы говорите «указатель, который является постоянным», прилагательное «постоянный» стоит на указателе. Итак, в этом случае ваш список прилагательных действительно должен был быть: «const, указатель, char». Но вы правы, в этой уловке есть двусмысленность. Это действительно «трюк», больше, чем окончательное «правило».Нет никакой разницы. Оба они объявляют "a" целым числом, которое нельзя изменить.
Различия начинают проявляться при использовании указателей.
Оба эти:
объявить "a" указателем на целое число, которое не изменяется. "a" можно присвоить, но нельзя "* a".
объявляет "a" постоянным указателем на целое число. «* a» можно присвоить, но нельзя.
объявляет, что «a» является постоянным указателем на постоянное целое число. Ни "a", ни "* a" нельзя присвоить.
источник
Пракаш прав в том, что декларации те же самые, хотя может быть уместно еще немного пояснить случай указателя.
«const int * p» - это указатель на int, который не позволяет изменять int с помощью этого указателя. «int * const p» - это указатель на int, который нельзя изменить, чтобы указать на другой int.
См. Https://isocpp.org/wiki/faq/const-correctness#const-ptr-vs-ptr-const .
источник
const int
идентичноint const
, как и верно, для всех скалярных типов в C. В общем, объявление параметра скалярной функции какconst
не требуется, поскольку семантика вызова C по значению означает, что любые изменения в переменной являются локальными для ее включающей функции.источник
Это не прямой ответ, а соответствующий совет. Чтобы все было прямо, я всегда использую конвекцию «положить
const
снаружи», где под «снаружи» я подразумеваю крайний левый или крайний правый угол. Таким образом, не возникает путаницы - константа применяется к ближайшему объекту (типу или типу*
). Например,источник
Они такие же, но в C ++ есть веская причина всегда использовать const справа. Вы будете последовательны везде, потому что функции-члены const должны быть объявлены следующим образом:
Он изменяет
this
указатель в функции сFoo * const
наFoo const * const
. Посмотреть здесь.источник
Да они такие же только
int
и разные для
int*
источник
Я думаю, что в этом случае они такие же, но вот пример, где порядок имеет значение:
источник