Const int vs. int const как параметр функции в С++ и C

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

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

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

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

Ответ 1

const T и T const идентичны. Однако обратите внимание на приоритет указателя:

char const* - это указатель на константу char (массив), а char* const - указатель константы на переменный char (массив).

Ответ 2

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

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

Ответ 3

Нет никакой разницы. Они оба объявляют "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;
}

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

Да, они одинаковы для всего int

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

Ответ 7

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

const int* cantChangeTheData;
int* const cantChangeTheAddress;

Ответ 8

Это не прямой ответ, а связанный отзыв. Чтобы все было в порядке, я всегда использую конвекцию "put 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

Ответ 9

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

int getInt() const;

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