согласно C++ http://en.cppreference.com/w/cpp/string/byte/memcpy memcpy
берет три параметра: место назначения, источник и размер/байты. это также возвращает указатель. почему то, что так? параметров не достаточно, чтобы ввести и скопировать данные.
или я неправильно понимаю что-то? примеры не используют возвращаемое значение
Если функция не имеет ничего особенного для возврата, часто бывает принято возвращать один из входных параметров (тот, который рассматривается как первичный один). Это позволяет использовать в выражениях «связанные» вызовы функций. Например, вы можете сделать
char buffer[1024];
strcat(strcpy(buffer, "Hello"), " World");
именно потому, что strcpy
возвращает исходное значение dst
в качестве своего результата. По сути, при разработке такой функции вы можете захотеть выбрать наиболее подходящий параметр для «связывания» и вернуть его в качестве результата (опять же, если вы не отметили еще, что нужно вернуть, т.е. если в противном случае ваша функция вернет void
).
Кому-то это нравится, кому-то нет. Это вопрос личных предпочтений. Стандартная библиотека C часто поддерживает эту технику, memcpy
- другой пример. Возможным вариантом использования может быть что-то вроде
char *clone_buffer(const char *buffer, size_t size)
{
return memcpy(new char[size], buffer, size);
}
. Если memcpy
не вернет указатель целевого буфера, нам, вероятно, придется реализовать указанное выше как
char *clone_buffer(const char *buffer, size_t size)
{
char *clone = new char[size];
memcpy(clone, buffer, size);
return clone;
}
, что выглядит «длиннее».Нет причин для разницы в эффективности между этими двумя реализациями. И спорно, какая версия читабельнее. Тем не менее, многие люди могут оценить «бесплатную» возможность написать такие краткие однострочные строки, как первая версия выше.
Довольно часто людей сбивает с толку тот факт, что memcpy
возвращает указатель целевого буфера, потому что существует распространенное мнение, что возврат указателя из функции должен обычно (или всегда) указывать на то, что функция может выделить / перераспределить объем памяти. Хотя это может действительно указывать на последнее, такого жесткого правила нет и никогда не было, поэтому часто высказываемое мнение, что возврат указателя (например, memcpy
) является каким-то «неправильным» или «плохая практика» совершенно необоснованна.
IIRC, в ранних версиях C не было возврата void
. Таким образом, библиотечные функции, которые существуют достаточно долго, возвращают что-то по устаревшим причинам, и это было лучшее, что они могли придумать.
В string.h
есть несколько функций, которые возвращают параметр назначения: memcpy
, strcpy
, strcat
. Это не очень полезно, но не причиняет вреда (вероятно, во многих соглашениях о вызовах даже не требуется инструкция для реализации).
Вы могли бы предположить использование: char * nextbuf = memcpy (get_next_buf (), previous_buf + offset, previous_size-offset);
вместо char * nextbuf = get_next_buf (); memcpy (nextbuf и т. д.);
Или что-то в этом роде.
Для сравнения qsort
возвращает значение void. Его можно было определить так, чтобы он возвращал базу
по принципу «вернуть что-нибудь, это может пригодиться», но этого не произошло. std :: copy
более полезно возвращает итератор в конец диапазона вывода. Для итераторов без произвольного доступа, которые могут быть нетривиальными или даже невозможными для вычисления вызывающей стороной.
Вы можете бросить возврат в пустоту, если хотите указать, что вы его не используете - например:
( void) memcpy (mydest, mysrc, mybytes);
При возврате значения вызов функции memcpy может использоваться как r-значение.