В чем техническая разница между этими декларациями? - PullRequest
2 голосов
/ 11 февраля 2011
  char amessage[] = "now is the time"; /* an array */
  char *pmessage = "now is the time"; /* a pointer */

Ответы [ 4 ]

4 голосов
/ 11 февраля 2011

amessage относится к типу char[16].Это массив.Элементы массива содержат шестнадцать символов из строкового литерала.

pmessage имеет тип char*.Это указатель.Он указывает на (немодифицируемый) массив, содержащий шестнадцать символов из строкового литерала.(Вам следует избегать использования char* для указания на строковый литерал; это плохо. Вы всегда должны использовать const char* везде, где это возможно при обращении к строковым литералам.)

0 голосов
/ 11 февраля 2011
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */

В C вещь слева от '=' называется 'lvalue'. Тип определяется исключительно значением lvalue. Таким образом, amessage - это массив символов. 'pmessage' - указатель на символ.

В Си больше идет о том, что эквивалентно между типом массива и доступом 'char *', а также тем, что нет.

Как объявлено, «pmessage» является изменяемым «lvalue» - «amessage» не может быть изменено. Следовательно, советуем объявить «pmessage» как const, поскольку на самом деле он также не должен изменяться.

1008 * Е.Г. *

const char* const pmessage = "...";

С точки зрения доступа к памяти «amessage» приводит к прямому доступу, тогда как «pmessage» требует разыменования.

Примечание: компилятор C разрешает инициализацию 'char *' только во время компиляции через строковый литерал.

например. Если бы у вас было

1. {
2.     int j = 1;
3.     int *k = &j;
4.     int *i = 1;
5. }

Строка 4 не имеет смысла и будет незаконной.

Настоятельно рекомендую «Deep C Secrets» Питера Ван Линдена, в котором у него есть целая глава, посвященная массивам и указателям на C.

0 голосов
/ 11 февраля 2011

если вы используете GCC, включите -Wwrite-strings.фиксированные строки имеют тип const char [length_of_string], и преобразование в char * вызовет предупреждение [должно быть const].

Первое назначение - это присвоение массива символов, тогда как второе назначение - этоОснованное на указателе назначение (и получающаяся строка хранится как фиксированная строка)

Первое назначение является приемлемым как есть, тогда как второе требует квалификатор const.

В первом назначении изменение точки допустимо (например, amessage [3] = 'q').во втором назначении изменение точки недопустимо (так как строка является константой) - вы должны получить ошибку шины

0 голосов
/ 11 февраля 2011

В дополнение к ответу Джеймса Макнеллиса, amessage - это одно: массив из 16 символов в стеке, который содержит строку «сейчас время» (потому что они копируются туда при создании amessage).Вы можете изменить то, что в нем содержится.

С другой стороны, pmessage - это две вещи - строковый литерал (который хранится в незаписываемой части памяти) и указатель.Вы не можете изменить содержимое строкового литерала, но вы можете изменить то, на что указывает указатель, и сделать так, чтобы он указывал на другую строку.И вы можете использовать строковый литерал в качестве цели для других указателей.

(В некотором смысле это не совсем так - amessage также включает строковый литерал, так как это место, откуда копируется содержимое, когдаон создан. Но вы ничего не можете сделать иначе с этим строковым литералом впоследствии.)

...