const int против int const как параметр функции в C ++ и C - PullRequest
107 голосов
/ 02 октября 2008

Быстрый вопрос:

int testfunc1 (const int a)
{
  return a;
}

int testfunc2 (int const a)
{
  return a;
}

Являются ли эти две функции одинаковыми во всех аспектах или есть разница? Мне интересен ответ для языка C, но если есть что-то интересное в языке C ++, я бы тоже хотел знать.

Ответы [ 9 ]

321 голосов
/ 02 октября 2008

Хитрость заключается в том, чтобы прочитать декларацию в обратном направлении (справа налево):

const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"

Оба - одно и то же. Поэтому:

a = 2; // Can't do because a is constant

Трюк с обратным чтением особенно полезен, когда вы имеете дело с более сложными объявлениями, такими как:

const char *s;      // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"

*s = 'A'; // Can't do because the char is constant
s++;      // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++;      // Can't do because the pointer is constant
165 голосов
/ 02 октября 2008

const T и T const идентичны. С типами указателей становится все сложнее:

  1. const char* - указатель на константу char
  2. char const* - указатель на константу char
  3. char* const - постоянный указатель на (изменяемый) char

Другими словами, (1) и (2) идентичны. Единственный способ сделать указатель (а не указатель) const - это использовать суффикс- const.

Именно поэтому многие люди предпочитают всегда ставить const справа от шрифта (стиль «восточный конст»): это делает его расположение относительно типа последовательным и легко запоминающимся (это также, похоже, делает случайным новичкам легче учить).

13 голосов
/ 02 октября 2008

Разницы нет. Они оба объявляют "a" как целое число, которое нельзя изменить.

Место, где начинают появляться различия, это когда вы используете указатели.

Оба из них:

const int *a
int const *a

объявляем "a" указателем на целое число, которое не изменяется. «a» может быть назначен, но «* a» не может.

int * const a

объявляет "a" постоянным указателем на целое число. «* a» может быть назначено, но «a» не может.

const int * const a

объявляет "a" постоянным указателем на постоянное целое число. Ни "a", ни "* a" не могут быть назначены.

static int one = 1;

int testfunc3 (const int *a)
{
  *a = 1; /* Error */
  a = &one;
  return *a;
}

int testfunc4 (int * const a)
{
  *a = 1;
  a = &one; /* Error */
  return *a;
}

int testfunc5 (const int * const a)
{
  *a = 1;   /* Error */
  a = &one; /* Error */
  return *a;
}
7 голосов
/ 02 октября 2008

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

"const int * p" - это указатель на int, который не позволяет изменять int через этот указатель. «int * const p» - это указатель на int, который нельзя изменить, чтобы он указывал на другое int.

См. http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5.

5 голосов
/ 05 ноября 2008

const int идентичен int const, как и для всех скалярных типов в C. В общем случае объявление параметра скалярной функции как const не требуется, поскольку семантика вызова по значению в C означает, что любой изменения в переменной являются локальными по отношению к ее функции включения.

4 голосов
/ 02 октября 2008

Это не прямой ответ, а связанный совет. Чтобы держать вещи прямо, я всегда использую конвекцию «положи const снаружи», где под «снаружи» я подразумеваю крайний левый или крайний правый. Таким образом, нет никакой путаницы - const применяется к ближайшей вещи (либо к типу, либо к *). Например.,



int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
3 голосов
/ 23 сентября 2015

Они одинаковые, но в C ++ есть веская причина всегда использовать const справа. Вы будете последовательны везде, потому что функции-члены const должны быть объявлены следующим образом:

int getInt() const;

Изменяет указатель this в функции с Foo * const на Foo const * const. См. Здесь.

3 голосов
/ 02 октября 2008

Я думаю, что в этом случае они одинаковы, но вот пример, где порядок имеет значение:

const int* cantChangeTheData;
int* const cantChangeTheAddress;
3 голосов
/ 02 октября 2008

Да, они одинаковы только для int

и отличается для int*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...