Чем строка отличается от массива указателей на символы в C? - PullRequest
1 голос
/ 08 апреля 2009

У меня сложилось впечатление, что это одно и то же. Тем не менее, мне кажется, что с ними здесь по-другому обращаются. Часть, в которой я запутался, выглядит следующим образом.

Foo* initFoo(char* name);

int main
{
  Foo* foo;
  char* player_name[25];
  scanf("%s", player_name);
  foo = initFoo(player_name);
}

Foo* initFoo(char* name)
{
  printf("\n%s", name);
}

Строка печатается нормально. Тем не менее, я получаю предупреждение компилятора, которое говорит: передача аргумента 1 'initFoo' из несовместимого типа указателя. Что мне не хватает в указателях?

Ответы [ 4 ]

7 голосов
/ 08 апреля 2009

Строка - это массив символов. Здесь у вас есть массив указателей на символы.

6 голосов
/ 08 апреля 2009

Линия:

char* player_name[25];

выделяет массив из 25 элементов-указателей на char. Указатель на char обычно считается строкой, поэтому это объявление можно интерпретировать как массив строк, но памяти для хранения этих строк еще не существует. Вы должны были бы выделить эти строки отдельно.

Предполагая, что указатели имеют 4 байта на вашей машине, эта строка будет иметь эффект выделения 25 x 4 = 100 байтов.

В C, когда вы используете имя массива без индекса, оно «разлагается» на указатель на первый элемент массива.

Итак ... когда эта строка выполняется:

scanf("%s", player_name);

player_name указывает на 100 байтов памяти, достаточно места, чтобы вместить 100 символов для чтения (ну, 99 символов плюс завершающий байт NUL). Компилятор не защищает вас от хранения тех символов в памяти, которая была выделена для 25 указателей.

Наконец:

foo = initFoo(player_name);

передает начальный адрес массива функции initFoo (). Компилятор знает, что это, вероятно, неправильно, поскольку initFoo () должен принимать указатель на символы, а не указатель на массив указателей на символы, но он позволяет вам делать это в любом случае, за исключением предупреждения. Оператор printf () в initFoo () интерпретирует этот указатель как указатель на символ, и вы получите правильный результат!

Как уже говорили другие, было бы правильно изменить одну строку на

char player_name[25];

, который объявляет массив из 25 символов.

4 голосов
/ 08 апреля 2009
char* player_name[25];  /* means an array of character pointers. */
char  player_name[25];  /* will get rid of the warning */
0 голосов
/ 08 апреля 2009

Чтобы исправить это, измените на:

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