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

Какая разница между strcpy и stpcpy?

При чтении справочной страницы strcpy я обнаружил, что функция stpcpy также существует. Однако единственная разница, которую я мог заметить на странице руководства:

char *
stpcpy(char *s1, const char *s2);

char *
strcpy(char *restrict s1, const char *restrict s2);

Итак, что означает restrict здесь?

4b9b3361

Ответ 1

restrict сообщает компилятору, что s1 и s2 указывают на разные массивы и что на массивах с заостренным доступом нет перекрытия. В некоторых случаях это может позволить компилятору выполнять дополнительные оптимизации (т.е. Возможно копировать блоки из нескольких символов без необходимости проверки на перекрытие).

Обратите также внимание, что возвращаемое значение отличается: stpcpy возвращает указатель на \0, который был скопирован в буфер назначения, в то время как strcpy возвращает указатель на начало строки (эффективно это делает return s1;).

Ответ 2

Вопрос, который вы задаете в заголовке и вопрос о restrict, на самом деле являются двумя разными совершенно не связанными вопросами. Другие ответы уже предоставили вам хорошие ссылки, которые помогут вам узнать больше о restrict.

Однако основное различие между этими двумя функционалами в действительности не является спецификатором restrict. Фактически, в версии C99 версии языка C, strcpy также имеет квалификацию restrict по своим параметрам. То, что вы видите на странице своего пользователя для strcpy, просто не обновляется, чтобы соответствовать C99.

Основное отличие (которое вы, кажется, пропустили) - это возвращаемое значение stpcpy. stpcpy возвращает указатель на завершающий символ \0 целевой строки. Это сразу дает понять цель stpcpy и обоснование ее существования: эта функция предназначена для использования в качестве интеллектуальной замены функции strcat в ситуациях, когда вам нужно объединить несколько подстрок в одну строку. Понимаете, strcat работает довольно плохо в таком приложении (я бы даже сказал, что strcat не имеет смысла в реальном коде). Проблема с strcat заключается в том, что она повторно сортирует строку назначения каждый раз, когда вы что-то добавляете к ней, тем самым делая много ненужной работы и в основном генерируя больше тепла, чем свет. Например, следующий код страдает от этой проблемы

const char *part1, *part2, *part3, *part4;
...
char buffer[size]; /* assume that `size` is calculated properly */

strcpy(buffer, part1);
strcat(buffer, part2);
strcat(buffer, part3);
strcat(buffer, part4);

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

stpcpy(stpcpy(stpcpy(stpcpy(buffer, part1), part2), part3), part4);

И если вам не нравятся прикованные вызовы, вы можете использовать промежуточный указатель для хранения возвращаемого значения промежуточных stpcpy вызовов

char *end = buffer;

end = stpcpy(end, part1);
end = stpcpy(end, part2);
end = stpcpy(end, part3);
end = stpcpy(end, part4);

Конечно, стоит упомянуть, что strcpy и strcat являются стандартными функциями, а stpcpy - нет.

Ответ 3

Запись в Wikipedia для restrict

Короче говоря, restrict сообщает компилятору, что сегменты памяти, на которые указывают s1 и s2, не перекрываются; это позволяет коду выполнять меньшую проверку ошибок.

Ответ 4

Функция stpcpy() копирует строку, на которую указывает src (включая завершающий символ '\0'), в массив, на который указывает dest. Строки        может не перекрываться, а целевая строка dest должна быть достаточно большой, чтобы получить копию.

Это удовлетворяет требованиям для restrict, даже если это не в сигнатуре функции. Если C99 присутствует, он может быть добавлен.

stpcpy() возвращает указатель на конец строки dest (то есть адрес конечного нулевого байта), а не на начало.

Это позволяет вам легче конкатенировать многие строки и более эффективно, так как src можно "привязать" к указателю, возвращенному из последнего stpcpy(). Наивная реализация альтернативы strcat должна найти конец строки dest до того, как она начнет копирование.

Обратите внимание на следующее:

Эта функция не является частью стандартов C или POSIX.1 и не является обычным в Unix-системах, но также не является изобретением GNU. Возможно, это        происходит от MS-DOS. В настоящее время он также присутствует в BSD.

Ответ 5

Другое отличие - это возвращаемое значение. На странице man: "Функции strcpy() и strncpy() возвращают s1. Функция stpcpy() возвращает указатель на завершающий символ`\0 's1."

Ответ 6

strcpy возвращает s1, но stpcpy возвращает s1 + strlen (s2).