Как вы назначаете строки строковому типу данных в C?

#c

Вопрос:

Я пытаюсь создать игру «камень,ножницы,бумага», используя функции на языке Си, но, похоже, не могу понять, как присвоить строку переменной char после ее инициализации. Итак, функция генерирует случайное число и сравнивает это число с эфиром, камнем, бумагой или ножницами. тем не менее, я не могу присвоить строку переменной, которую я хочу, чтобы функция возвращала после ее вызова

 int getConsoleChoice() {  char consolePick;  int randNum;  srand(time(NULL));  randNum = rand() % 3;   if(randNum == 0)  {  char consolePick = "Rock";  }  if(randNum == 1)  {  char consolePick = "Paper";   }  if(randNum == 2)  {  char consolePick = "Scissors";  }  return consolePick; }  

Комментарии:

1. Попадание: строка-это последовательность символов, а не один символ. На последовательность символов ссылается указатель, т. е. char* .

2. То, что у вас здесь есть, — это символьный тип данных. Этот код усекает указатели строковых литералов через целочисленный тип на char , а затем возвращает это значение в виде целого числа. С включенными предупреждениями компилятора ваш компилятор должен прямо сейчас устроить настоящую истерику.

3. Смотрите strcpy и strncpy в string.h заголовке.

4. Не объявляйте переменную внутри if блоков. Это делает переменную локальной для блока, она не обновляет переменную, объявленную в верхней части функции.

5. Почему ваша функция объявляется возвращаемой int , когда вы хотите вернуть строку?

Ответ №1:

Объявите возвращаемое значение переменной и функции как char * , которое является типом строки в C.

 char *getConsoleChoice() {  char *consolePick;  int randNum;  srand(time(NULL));  randNum = rand() % 3;   if(randNum == 0)  {  consolePick = "Rock";  }  else if(randNum == 1)  {  consolePick = "Paper";   }  else  {  consolePick = "Scissors";  }  return consolePick; }  

Вы также можете упростить это, используя массив:

 char *getConsoleChoice() {  char *moves[] = {"Rock", "Paper", "Scissors"};  int randNum;  srand(time(NULL));  randNum = rand() % 3;  return moves[randNum]; }  

Комментарии:

1. Это придирка, но функции должны возвращаться const char* .

2. Я собирался это сделать, но не хотел открывать эту банку с червями, объясняя изменения….

3. Он не показывает никаких ошибок, но он также ничего не выводит,

4. А, в этом есть смысл.

5. Почему бы не воспользоваться кривой обучения? Благодаря своим усилиям вы станете более всесторонним программистом.

Ответ №2:

char представляет собой один символ. Строка-это набор этих строк, хранящихся вместе где-то в памяти, с нулевым завершающим символом, чтобы мы могли определить, где заканчивается эта строка. Поэтому, когда у нас есть ячейка памяти, в которой хранится набор значений какого-либо типа, мы используем указатель. Он содержит адрес памяти, который «указывает» на начало. Тип строки таков char* .

Для иллюстрации, давайте выделим несколько байтов в памяти, отображающих строку по какому-либо адресу, представим, что у нас 32-разрядный компьютер, и в качестве аргумента строка начинается с адреса 0xffa01000:

 0 1 2 3 4 5 6 7   --- --- --- --- --- --- --- ---  0xffa01000 | R | o | c | k | ~ | ? | ? | ? |   --- --- --- --- --- --- --- ---   

вышесказанное-это то, как выглядит «Камень» в памяти. Каждая из этих ячеек представляет собой один байт, содержащий char значение. Обратите внимание, что я использовал ~ для представления байта NUL и ? для представления памяти, о которой мы не заботимся (потому что она не является частью строки).

Если вы хотите сохранить значение, указывающее на эту строку, вы используете указатель:

 const char* rock = "Rock";  

В нашем примере из предыдущего примера указатель rock теперь содержит адрес 0xffa01000, и если мы начнем считывать информацию из памяти оттуда, пока не достигнем байта NUL, то мы прочитаем строку "Rock" .

Вы можете использовать указатель как массив. Сверху rock[0] вам дадут персонажа 'R' , rock[1] дадут 'o' и так далее…

Итак, есть некоторые основы того, что на самом деле представляют собой строки в C. Но вернемся к твоей игре.

С тем, что вы пытаетесь сделать, цель, вероятно, состоит в том, чтобы использовать значение 0, 1 или 2 для представления оружия. Потому что с ним просто легче работать. Вы всегда можете превратить это в строку, когда вам нужно. Вот пример того, как вы могли бы это сделать:

 const char* weaponName(int w) {  static const char* names[] = {  "Rock",  "Paper",  "Scissors"  };   // Note: the defensive programming approach would also range-test this index  // before using it.  return names[w]; }  

Эта функция просто использует номер оружия в качестве индекса для поиска строки в массиве. Вспомните, что было раньше… То, что мы имеем здесь, — это просто массив указателей на строки, которые находятся где-то в памяти. Вам не нужно беспокоиться о том, где.

Обратите внимание, что я также использовал const . Не беспокойтесь об этом слишком сильно, но это предотвращает случайное изменение этих строк. Изменение строковых литералов запрещено, и поэтому мы храним их как константы, чтобы компилятор жаловался, если мы попытаемся их изменить.

Что касается static , ну, это другая тема, но в основном это означает, что одна копия этого массива всегда будет в памяти, даже после возврата функции. Поэтому мне не нужно беспокоиться о том, что мои строки каким-то образом не будут существовать после возврата функции. Они, вероятно, все равно не исчезли бы, но это гарантирует.

В любом случае, вернемся к тому, как это использовать, это довольно просто. Ваш случайный бросок оружия становится однострочной функцией, и получение строкового представления-это просто вызов функции, которую мы выполнили ранее.

Вот код, который 10 раз перевернет оружие и распечатает, что у него есть:

 int randomWeapon() {  return rand() % 3; }  int main() {  // Seed the random generator -- you should only do this once!  srand(time(0));    for (int i = 0; i lt; 10;   i)  {  int weapon = randomWeapon();  printf("%sn", weaponName(weapon));  } }