Подтвердить что ты не робот

C - зачем нужен strcpy()

Может кто-нибудь объяснить мне, почему strcpy() необходимо для назначения строк массивам символов, например, в следующем фрагменте кода.

int main(void) {

char s[4];

s = "abc"; //Fails
strcpy(s, "abc"); //Succeeds

return 0;
}

В чем причина неудачи s = "abc"? И почему strcpy() единственный способ назначить строки массивам char после их объявления? Мне кажется странным, что вам нужно использовать функцию для выполнения основного задания.

4b9b3361

Ответ 1

Массивы в C не являются назначаемыми и не копируемыми. Это как раз то, как массивы находятся в C. Исторически, в контексте стоимости (по RHS присвоения) массивы распадаются на указатели, что формально предотвращает назначение и копирование. Это относится ко всем массивам не только к массивам char.

Язык C наследует поведение этих массивов от его предшественников - языков B и BCPL. В этих языках массивы были представлены физическими указателями. (И, очевидно, повторное назначение указателей - это не то, что вы хотели бы сделать, когда вы назначаете один массив другому.) В языках C массивы не являются указателями, но они "имитируют" историческое поведение массивов B и BCPL путем разложения для указателей в большинстве случаев. Это историческое наследие - это то, что сохраняет C массивы, не подлежащие копированию, по сей день.

Одним из исключений из вышеизложенного является инициализация строковым литералом. То есть вы можете сделать

char c[] = "abc";

но что он.

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

Ответ 2

Это просто, какие массивы находятся в C. Вы не можете назначить их. Вы можете использовать указатели, если хотите:

char *p;
p = "abc";

Кстати, есть C FAQ.

Массивы являются "гражданами второго сорта" в C; один итог этого предвзятость заключается в том, что вы не можете назначить им.

Ответ 3

Короткий ответ: исторические причины. C никогда не имел встроенного строкового типа. Только после того, как С++ появился, появился std::string, и даже это не пришло с первой версией

Длинный ответ: тип "abc" не char[], а скорее char *. strcpy - это один из механизмов, с помощью которого вы можете скопировать данные, на которые указывает указатель (в данном случае это ABC).

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

Ответ 4

На языке C отсутствует удобный синтаксис для получения указателя на строковый литерал вместе с указанием его длины. Некоторые языки, включая много диалектов Паскаля, префикс каждой строки с байтом, сообщающим о своей длине; это хорошо работает для многих целей, но ограничивает строковые литералы до 255 символов. C позволяет использовать строковые литералы любой длины, но добавляет только один байт служебных данных независимо от длины.

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