Можно ли конвертировать char [] в char * в C? - PullRequest
48 голосов
/ 09 марта 2012

Я выполняю задание, в котором мы должны прочитать последовательность строк из файла в массив. Я должен вызвать алгоритм шифрования на массиве (шифр транспонирует 2D-массивы). Итак, сначала я поместил всю информацию из файла в 2D-массив, но у меня было много проблем с конфликтующими типами в остальной части моего кода (в частности, пытаясь установить char [] в char *). Итак, я решил переключиться на массив указателей, что сделало все намного проще в большей части моего кода.

Но теперь мне нужно преобразовать char * в char [] и обратно, но я не могу понять это. Я не смог ничего найти в Google. Я начинаю задумываться, возможно ли это вообще.

Ответы [ 4 ]

99 голосов
/ 09 марта 2012

Звучит так, будто вы запутались между указателями и массивами.Указатели и массивы (в данном случае char * и char []) - это не одно и то же.

  • Массив char a[SIZE] говорит, что значение в местоположении a является массивом длины SIZE
  • Указатель char *a; говорит, чтозначение в местоположении a является указателем на char.Это может быть объединено с арифметикой указателя, чтобы вести себя как массив (например, a[10] - это 10 записей после того, где a указывает)

В памяти это выглядит так (пример взят из FAQ ):

 char a[] = "hello";  // array

   +---+---+---+---+---+---+
a: | h | e | l | l | o |\0 |
   +---+---+---+---+---+---+

 char *p = "world"; // pointer

   +-----+     +---+---+---+---+---+---+
p: |  *======> | w | o | r | l | d |\0 |
   +-----+     +---+---+---+---+---+---+

Легко запутаться в разнице между указателями и массивами, потому что во многих случаях ссылка на массив "затухает" до указателя на его первый элемент.Это означает, что во многих случаях (например, при передаче в вызов функции) массивы становятся указателями.Если вы хотите узнать больше, в этом разделе часто задаваемых вопросов по C подробно описываются различия .

Одно важное практическое отличие состоит в том, что компилятор знает, какова длина массива.Используя приведенные выше примеры:

char a[] = "hello";  
char *p =  "world";  

sizeof(a); // 6 - one byte for each character in the string,
           // one for the '\0' terminator
sizeof(p); // whatever the size of the pointer is
           // probably 4 or 8 on most machines (depending on whether it's a 
           // 32 or 64 bit machine)

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

  • Вам нужно будет инициализировать память там, где раньше были массивы.Например, char a[10]; станет char *a = malloc(10 * sizeof(char)); с последующей проверкой a != NULL.Обратите внимание, что вам на самом деле не нужно произносить sizeof(char) в этом случае, потому что sizeof(char) определено равным 1. Я оставил его для полноты.

  • Везде, где у вас ранее былоsizeof(a) для длины массива нужно будет заменить на длину выделенной памяти (если вы используете строки, вы можете использовать strlen(), что составляет '\0').

  • Вам потребуется сделать соответствующий звонок на free() для каждого звонка на malloc().Это говорит компьютеру, что вы сделали, используя память, которую вы запросили с помощью malloc().Если ваш указатель a, просто напишите free(a); в той точке кода, где, как вы знаете, вам больше не нужны все, на что указывает a.

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

char* p = &a[0] 

Вы можете прочитать это как "указатель на символ p становится адресом элемента [0] из a».

14 голосов
/ 09 марта 2012

Если у вас есть char[] c тогда вы можете сделать char* d = &c[0] и получить доступ к элементу c [1], выполнив *(d+1) и т. д.

2 голосов
/ 09 марта 2012

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

int i;
int M=30, N=25;
int ** buf;
buf = (int**) malloc(M * sizeof(int*));
for(i=0;i<M;i++)
    buf[i] = (int*) malloc(N * sizeof(int));

и тогда вы можете ссылаться на buf[3][5] или что-то еще.

0 голосов
/ 09 марта 2012

Ну, я не уверен, что понимаю ваш вопрос ...

В Си Char [] и Char * - это одно и то же.

Редактировать: спасибо за эту интересную ссылку.

...