Вопрос, который вы задаете в названии, и вопрос о restrict
- это на самом деле два совершенно не связанных между собой вопроса. Другие ответы уже дали вам хорошие ссылки, которые помогут вам узнать больше о restrict
.
Однако, главное различие между этими двумя функциями не в спецификаторе restrict
. На самом деле, в версии спецификации языка C99 для C99 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
- нет.