Я где-то читал вопрос , который был об указателе void
или , void *
и возникло сомнение по поводу зарезервированного слова void
нескольких языков.
У меня есть этот код:
typedef enum VALUE_TYPE {
VT_INTEGER, VT_STRING, VT_BOOL, VT_NULL
} valuetype_t;
typedef struct VALUE {
void *iv;
valuetype_t tp;
} value_t;
Но я не очень понимаю, для чего это void *
in struct
.
Насколько я понимаю, в c и c++ тип void
— это все и ничего, но я не очень понимаю, о чем идет речь.
Может ли кто-нибудь объяснить мне, что это такое void
и его функции на различных языках, которые его используют?
Примечание. Я использовал только c и c++ , потому что я не уверен в использовании языково-независимого тега , не стесняйтесь редактировать этот фрагмент и теги вопроса.
Для c и c++ это правда, что это
void
практически ничего не значит , но если добавить к нему простую звездочку (*
) , то это может быть что угодно или, вернее, что угодно!Начиная с частей, зарезервированное слово
void
имеет следующие варианты использования в C (среди прочего) :Спецификатор типа:
Выше приведено объявление функции типа
void
, то есть такой, которая не возвращает значение какого-либо типа и поэтому не может иметь переменную типаvoid
, которой можно присвоить возвращаемое значение функции:И гораздо меньше:
Если вы заметили, в первом блоке кода я использовал часть
(void)
параметров , которую использует объявленный там метод, это объясняется ниже.Функциональный герметик .
По умолчанию функции C являются вариативными , если они
void
явно не заключены в круглые скобки определения функции 1 :Однако, когда мы используем
void
скобки, вышеприведенное не работает:Удалить... Предупреждения?
Никогда не рекомендуется подавлять предупреждения, которые выдает ваш компилятор, когда есть неубийственные проблемы , которые могут вызвать неопределенное поведение в вашем программном обеспечении:
В этом контексте он
(void)
служит оператором приведения или преобразования ... поскольку мы ничего не приводим, значение бесполезно .Однако есть некоторые компиляторы, которые вместо этого выдают предупреждение при использовании приведения к
void
.Мы все ожидали...
void *
чего угодно, или... так мы думали.Да,
void
, сопровождаемый*
, — это мощный тип данных, который хранит указатель на любой другой существующий тип данных, фактически это то, что возвращают функции, резервирующие память:И это потому, что
void *
это указатель на адрес памяти, тип которого неизвестен 2 , что вы и делаете в коде, который у вас есть в вопросе, вы определяете поле типаvoid *
и угадываете его значение с помощью другой переменной.Я действительно думаю, что этого
void *
следует избегать или использовать только тогда, когда значение, на которое оно указывает, точно известно:На самом деле, я могу делать с этой памятью все, что захочу 3 :
В приведенном выше примере я использовал его для хранения 1000-байтового указателя динамически выделяемой памяти, но, поскольку я не знал, что делать с этими байтами, поэтому я использовал их для хранения целых чисел, я также могу преобразовать этот указатель в
void
к указателюchar
и сохранить текстовую строку.Но что остается, когда мы передаем указатель из чего-либо еще в параметр типа
void *
? Важным моментом здесь является то, что C является несколько разрешающим (я не хочу, чтобы у него были дочерние элементы) и автоматически преобразуется вvoid *
4 , чтобы вызываемая функция могла работать с указателем, переданным в качестве аргумента.Указатель на
void
является очень мощным типом в мудрых руках, однако он может вызвать оплошности и проблемы в коде, как и любая хорошая практика C, рекомендуется не злоупотреблять этим типом.1 : Ideone , чтобы проверить это.
2 : Это не совсем неслыханно, но указатель типа void позволяет нам узнать только адрес, на который он указывает, а не данные, которые он содержит.
3 : Ideone , чтобы проверить это.
4 : Все указатели имеют одинаковый размер, единственное, что меняется, — это способ интерпретации адресов памяти в зависимости от среды, в которой он работает.