2013-05-14 1 views
0

У меня есть некоторые замешательства по поводу того, что я читал со следующего сайта о memcpy()malloc()):В C, лидирует (void *) не требуется/не рекомендуется для memcpy() так же, как это не требуется для malloc()?

http://www.cplusplus.com/reference/cstring/memcpy/

В этой странице, следующие 2 строки четко указаны:

назначения

Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.

источник

Pointer to the source of data to be copied, type-casted to a pointer of type const void*.

Но сразу же после этого, в коде, не отливка void* в следующих двух строках, где memcpy() используется:

memcpy (person.name, myname, strlen(myname)+1); 
    memcpy (&person_copy, &person, sizeof(person)); 

Пожалуйста, ответьте на следующие 2 вопроса возникающие из этого помещения:

1) В случае C (в отличие от C++) все это право и желательно не бросать в void* типа возвращаемого или аргументы в memcpy() так же, как это правильно и желательно не бросать в void* возвращаемого типа malloc() в C? Если это так, как я интуитивно чувствую, почему явно указано в том, что известный сайт, который нам нужен , должен отдать его void* (хотя он и не использует его в коде). Это сайт неправильно?

2) Теперь реальное противоречие о том, что известного site.Consider следующего

http://www.cplusplus.com/reference/cstdlib/malloc/

В случае malloc(), в описании написано, как будто это optional приведения к void* тип возврата (точные слова «.. can be cast to the desired type ..»), в отличие от случая memcpy() выше, где сказано, что должен быть брошен вvoid* .Но в то время как memcpy() отливка не делается, даже если написано, что it is to be cast, в случае malloc(), отливка в void* делается несмотря на то, что написано это can be cast to void* .Теперь я вижу что-то неправильное в этом, как и для C мы не предполагается литье malloc() 's возврат к void*.

Навести расхождение в двух словах снова чтобы люди, отвечая запутаться в моем словесном описании:

--Is это желательно в C не приведение к void* возвращению и аргументов в memcpy()?

- Этот сайт ошибочен в отношении malloc(), поскольку он отличает malloc(). Возврат к void* в коде C.

+0

'malloc' и' memcpy' имеют только предельное существование в C++, он существует в основном для совместимости с C. C++ имеет разные конструкции, которые лучше вписываются в их систему типов. Поэтому лучше не использовать сайт C++ в качестве ссылки для C. Это просто другое. –

+0

@JensGustedt Это перешло мне в голову, но когда я увидел, что сама программа находится на C, я подумал, что это говорит о случае C. –

+0

@JensGustedt. Все программы в разделе «Стандартная библиотека» C находятся в C. –

ответ

3

От ISO/IEC 9899: 2011 спецификации языка C, раздел 6.3.2.3, стр 55:

Указатель на void могут быть преобразованы в или из указателя на любой тип объекта. Указатель на любой тип объекта может быть преобразован в указатель на void и обратно; результат сравнивается с исходным указателем.

Таким образом, вам практически не нужно отливать результат от void* до нужного типа, и вам не нужно делать обратное.

+0

Я не совсем понял это. Можете ли вы объяснить это в контексте моего вопроса чуть подробнее. Пожалуйста, ответьте «все мясо, но трудно пережевывать». Можете ли вы сделать его немного менее плотным, подробности пожалуйста? –

+0

Как почему-то сделано для 'malloc()', но не для 'memcpy()', хотя указано, что он ** должен быть брошен ** для 'memcpy()', но необязательный для 'malloc()'? –

+0

Данных нет. в C void * может быть преобразован в любой другой указатель одинарного различного типа и без него, без необходимости использования cast, sic et simpliciter. Забудьте о том, что написано на этом конкретном сайте, литье является синтаксически правильным в обоих случаях, но не нужно. – Jack

1

-> по первому вопросу

тетсру, бросок не требуется C. Это было бы в C++.

-> по второму вопросу

таНос возвращает указатель недействительным (недействительными *), что свидетельствует о том, что он является указателем на область неизвестного типа данных. Использование кастинга требуется на C++ из-за сильной системы типов, тогда как это не так в C. Отсутствие определенного типа указателя, возвращаемого из malloc, является небезопасным поведением типа в соответствии с некоторыми программистами: malloc выделяет на основе количества байтов но не по типу. Это отличается от нового оператора C++, который возвращает указатель, тип которого зависит от операнда

1

В C мы непосредственно присваиваем void * любому типу и наоборот, нам не нужно явно указывать тип.

int *i_ptr = (int *)0xABCD; //some address 
printf("address :%p\n",i_ptr); 
void *v_ptr = i_ptr;   //no need to explictly typecast 
printf("address :%p\n",v_ptr); 
float *f_ptr = v_ptr;   //this will throw error in cpp 
printf("address :%p\n",f_ptr); 

выход:

address :0xabcd 
address :0xabcd 
address :0xabcd 

Все это действительные заявления в C, но в CPP поплавок * f_ptr = v_ptr приведет к ошибке недопустимое преобразование из 'недействительным *' до 'флоат *'.

 Смежные вопросы

  • Нет связанных вопросов^_^