Почему мы используем `const` для строк при определении с помощью указателей в C? - PullRequest
0 голосов
/ 24 августа 2018

Для определения массивов с указателями мы пишем
int *const a;
потому что массивы имеют значения переменных, но указатели констант. Но для строк пишем
const char *s;.

Я не понимаю, почему. Это правильно? Действительно ли строки имеют константные значения и указатели на переменные в C?

Ответы [ 3 ]

0 голосов
/ 24 августа 2018
  1. Когда вы используете этот оператор

    char *str = "Stack Overflow";
    

    , это означает, что str указывает на строку "Stack Overflow", которая хранится в памяти кода, и пользователь не может изменять ее,Таким образом, для этого утверждения запись const перед char *str не имеет никакого эффекта, потому что строка уже является постоянной.

    Но const играет важную роль, когда вы указываете на базовый адрес массива,как

    char arr[20];
    strcpy(arr,"Stack Overflow");
    const char *str = arr;
    

    Использование const означает, что вы не можете изменить строку в arr через указатель str.

  2. Когда вы используете

    char * const ptr;
    

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

0 голосов
/ 24 августа 2018

Рассмотрим следующее:

char* a;
char* const b = "Hello"
const char* c;
const char* const d = "world";

a просто указывает на персонажа. Это может быть первый символ строки или один байт. Этот символ можно изменить, написав *a='Z' или a[0]='q' или передав a в функцию, принимающую параметр char*. Сам указатель также можно изменить, чтобы он указывал на некоторые другие символы, например a=b; или a="foo";. Это наиболее гибкая и наименее безопасная форма, поскольку с ней можно делать все что угодно.

b - постоянный указатель на символ. В этом случае он указывает на массив символов. Эти символы могут быть изменены, например, b[1]='a'; или *b=0;, но b сам по себе является постоянным, что означает, что он никогда не может указывать на другую часть памяти. Эта форма может использоваться, когда вы выделили буфер или массив, содержимое которого вы хотите изменить, но которое не может быть перемещено, поскольку оно было выделено операционной системой.

c указывает на постоянный символ. Вы можете изменить то, на что он указывает (c="foo"; или c=b;), но вы не можете использовать этот указатель для изменения символов, на которые он указывает, - , даже если он указывает на непостоянный буфер b. Эта форма обычно используется при обработке предварительно сгенерированных строк. Вы можете использовать эту переменную для хранения найденных строк и передачи их адресов, если только вы не изменили сами строки.

d - постоянный указатель на постоянный символ. Вы не можете изменить символы, на которые он указывает, и вы не можете направить сам указатель в другое место в памяти. Все, что вы можете сделать, это прочитать строку или отдельные символы (char e=d[4]; или puts(d);). Эта форма в основном используется при передаче строк ссылок, например, при именовании реальных объектов.

0 голосов
/ 24 августа 2018

Код, такой как int *const a;, в большинстве случаев бессмыслен.Основное использование создания указателя const - это когда у вас есть справочная таблица на основе указателей.Или когда вы хотите, чтобы указатель хранился в постоянной памяти во встроенной системе.

Некоторым запутанным программистам нравится писать код вроде void func (int* const ptr), но, на мой взгляд, это только запутывание, поскольку ptrв любом случае, это копия исходного указателя, и вызывающей стороне все равно, что функция делает со своей локальной копией внутри.

Не путать с const правильностью , что означаетуказатели на данные только для чтения должны быть объявлены как const int* ptr.Это широко признано в качестве хорошей практики программирования и является каноническим C, поскольку большая часть стандарта C использует константную корректность для стандартной библиотеки C.

Что касается указателей на строковые литералы (например,"hello") в частности, они должны быть объявлены const char* ptr = "hello"; по той причине, что модификация строкового литерала вызывает неопределенное поведение.Это означает, что его изменение является ошибкой и может привести к сбою программы.Это известный недостаток C - тип самого строкового литерала, даже если нам не разрешено писать в него, это char[].Это по историческим причинам.Однако в C ++ они исправили этот языковой недостаток, унаследованный от C, поэтому все строковые литералы в C ++ const char[].

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