Основной вопрос об указателе C с использованием 'strcpy' - PullRequest
3 голосов
/ 13 октября 2010

Человек, указатели продолжают доставлять мне неприятности.Я думал, что понял концепцию. (По сути, вы будете использовать * ptr, когда хотите манипулировать фактической памятью, сохраненной в том месте, на которое указывает ptr. Вы просто используете ptr, если вы хотите переместить этот указатель, выполняя такиекак ptr ++ или ptr--.) Итак, если это так, если вы используете звездочку для манипулирования файлами, на которые указывает указатель, как это работает:

char *MallocAndCopy( char *line ) {

    char *pointer;
    if ( (pointer = malloc( strlen(line)+1 )) == NULL ) {
        printf( "Out of memory!!!  Goodbye!\n" );
        exit( 0 );
    }
    strcpy( pointer, line );

    return pointer;
}

malloc возвращает указатель, поэтому я понимаю, почему «указатель» в условии if не использует звездочку.Однако в функции strcpy она отправляет СОДЕРЖАНИЕ строки в СОДЕРЖАНИЕ указателя.Разве это не должно быть:

strcpy( *pointer, *line);

?????Или я правильно понимаю указатели, и именно так работает функция strcpy?

Ответы [ 11 ]

6 голосов
/ 13 октября 2010

Строка в стиле C - это массив символьных байтов.Когда вы передаете массив как указатель на тип массива, указатель содержит адрес первого элемента массива.

Функция strcpy принимает указатель на первый char источникамассив (который является началом строки) и указатель на первый char в массиве назначения и выполняет итерацию по источнику, пока не достигнет символа '\0', который завершает строку.также, почему, когда вы вызываете malloc, размер, который вы передаете ему, равен strlen(line)+1, потому что вам нужно выделить еще один байт для символа завершения (насколько я знаю).

4 голосов
/ 13 октября 2010

char* strcpy(char *destination, const char *source) является подписью для strcpy. Он ожидает получить указатели в качестве аргументов. В вашем случае pointer уже является указателем, как и line.

strcpy возьмет указатели source и destination и скопирует нижележащие байты, на которые указывают значения от source до destination, до тех пор, пока он не достигнет байта \0 (NULL) в строке, указанной на на source, или если произошла ошибка сегментации, потому что он никогда не встречает этот байт (неопределенную строку) и просто считывает в пропасть.

Если бы вы использовали *pointer, вы бы фактически разыменовали указатель и получили char по адресу, на который указывает указатель.

1 голос
/ 13 октября 2010

Написав *pointer, вы получите символ, на который он указывает (который оказывается первым символом строки, которую представляет pointer). Передача в strcpy включает создание копии этого персонажа. Для strcpy невозможно знать, куда он должен писать, если вы не дадите ему указатель на эти данные.

Аналогичным образом, предоставляя *line, вы даете strcpy копию первого символа вашей строки.

Итак, вы в основном говорите:

У меня есть две строки. Я не даю их тебе. Первая буква одного - C, первая буква другого - µ. Скопируйте содержимое первого на второй

1 голос
/ 13 октября 2010

* находится внутри strcpy.

Применение оператора * называется разыменованием и точно так же, как применение [0].

strlen и strcpy необходимо знать, где начинаются строки, чтобы они могли получить доступ ко всем своим элементам, а не только к первому.

Тип pointer равен char *, а тип *pointer равен char, что означает отдельный символ без понятия соседних символов.

1 голос
/ 13 октября 2010

Посмотрите на объявление strpcy ().

char *strcpy(
   char *strDestination,
   const char *strSource 
);

Вам нужно передать указатель. Таким образом, вы не разыменовываете указатель и строку . Потому что это пройдет символ.

1 голос
/ 13 октября 2010

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

1 голос
/ 13 октября 2010

подпись strcpy

char * strcpy ( char * destination, const char * source );

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

0 голосов
/ 15 октября 2010

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

char * my_strdup(const char* s)
{
  size_t len = strlen(s);
  char *r = malloc(len+1);
  return r ? memcpy(r, s, len+1) : NULL;
}

memcpy обычно быстрее, чем strcpy для более длинных строк.

0 голосов
/ 13 октября 2010

Рассмотрим код strcpy как:

char * strcpy(char * dst, char* src) 
{
    int i = 0 ;
    for (;dst[i]=source[i++];);
    return dst ;
}

\ 0 (NULL) - конец строки и цикла for.

0 голосов
/ 13 октября 2010

Ваше базовое понимание strcpy верно.Функция действительно копирует содержимое line поверх содержимого pointer.Тем не менее, вы должны передавать указатели на функцию, а не сами данные.Это делается по нескольким причинам.

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

Кроме того, передача данных в функцию обеспечивает функцию копией содержимого переменной.Если вы непосредственно передали данные (или указатели со ссылками) на strcpy, функция будет работать с копиями, а не с исходными данными.Невозможно записать данные в исходную строку.

По сути, передавая указатели на strcpy, вы указываете местоположение исходных данных и места назначения.Функция обрабатывает все разыменования внутри.На человеческом языке вызов strcpy можно рассматривать как «взять строку, начинающуюся с адреса памяти line, и написать ее копию, начиная с адреса памяти pointer».Для передачи адресов памяти вы используете указатели.

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