Глядя на то, чтобы получить основы, на которых исходит термин VOID, и почему его называют недействительным. Цель вопроса состоит в том, чтобы помочь кому-то, у кого нет опыта работы в C, и вдруг смотрит на кодовую базу на основе C.
Что означает void в C, С++ и С#?
Ответ 1
В основном это означает "ничего" или "нет типа"
Существует 3 основных способа использования void:
-
Аргумент функции:
int myFunc(void)
- функция ничего не принимает. -
Возвращаемое значение функции:
void myFunc(int)
- функция ничего не возвращает -
Общий указатель данных:
void* data
- "данные" - это указатель на данные неизвестного типа и не может быть разыменован
Примечание: параметр void
в аргументе функции является необязательным в С++, поэтому int myFunc()
точно такой же, как int myFunc(void)
, и он полностью не учитывается в С#. Это всегда необходимо для возвращаемого значения.
Ответ 2
Я всегда считал это отсутствующим. Вот четыре случая на языке C, которые соответствуют этому использованию отсутствующих
-
R f(void)
- отсутствуют функциональные параметры -
void f(P)
- Возвращаемое значение отсутствует -
void *p
- Тип того, на что указывает, отсутствует -
(void) p
- Использование значения отсутствует
Другие потомки C используют его для других вещей. Язык программирования D
использует его для случаев, когда инициализатор отсутствует
-
T t = void;
- значение инициализации отсутствует
Ответ 3
Это означает "нет значения". Вы используете void
, чтобы указать, что функция не возвращает значение или что у него нет параметров или обоих. В значительной степени соответствует типичному использованию слова void на английском языке.
Ответ 4
Существует два способа использования void:
void foo(void);
или
void *bar(void*);
Первое указывает, что никакой аргумент не передается или что аргумент не возвращается.
Второй сообщает компилятору, что нет никакого типа, связанного с данными, что означает, что вы не можете использовать данные, на которые указывает, пока он не будет передан известному типу.
Например, вы увидите, что void*
используется много, когда у вас есть интерфейс, который вызывает функцию, параметры которой не могут быть известны заранее.
Например, в ядре Linux при отсрочке работы вы настроите функцию, которая будет запущена в последний раз, указав ей указатель на функцию, которая будет запущена, и указатель на данные, которые будут переданы функции:
struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data = somedata;
} deferred_work;
Затем поток ядра просматривает список отложенной работы, и когда он достигает этого node, он эффективно выполняет:
bar(somedata);
Затем в баре вы:
void bar(void* mydata) {
int *data = mydata;
/* do something with data */;
}
Ответ 5
Указывает на отсутствие возвращаемого значения в функции.
Некоторые языки имеют два вида подпрограмм: процедуры и функции. Процедуры - это всего лишь последовательность операций, тогда как функция представляет собой последовательность операций, возвращающих результат.
В C и его производных разница между ними не является явной. Все в принципе является функцией. ключевое слово void
указывает, что это не "фактическая" функция, так как она не возвращает значение.
Ответ 6
Подумайте о пустоте как о "пустой структуре". Позвольте мне объяснить.
Каждая функция принимает последовательность параметров, где каждый параметр имеет тип. Фактически, мы могли бы упаковать параметры в структуру, а слоты структуры соответствовали параметрам. Это означает, что каждая функция имеет ровно один аргумент. Аналогично, функции производят результат, который имеет тип. Это может быть логическое значение, или оно может быть плавающим, или это может быть структура, содержащая произвольный набор других типизированных значений. Если мы хотим, чтобы язык имел несколько возвращаемых значений, легко просто настаивать на том, чтобы они были упакованы в структуру. На самом деле мы всегда могли утверждать, что функция вернула структуру. Теперь каждая функция принимает ровно один аргумент и производит ровно одно значение.
Теперь, что происходит, когда мне нужна функция, которая производит "нет" значение? Ну, рассмотрим, что я получаю, когда я формирую структуру с тремя слотами: это имеет 3 значения. Когда у меня есть 2 слота, он имеет два значения. Когда это имеет один слот, одно значение. И когда он имеет нулевые слоты, он держится... мм, нулевые значения или "no" значение. Итак, я могу думать о функции, возвращающей void как возврат структуры, не содержащей значений. Вы даже можете решить, что "пустота" является просто синонимом типа, представленного пустой структурой, а не ключевое слово в языке (возможно, это только предопределенный тип:)
Аналогично, я могу думать о функции, не требующей значений, принимающих пустую структуру, например, "void".
Я даже могу реализовать свой язык программирования таким образом. Передача значения пустоты занимает нулевые байты, поэтому передача значений void является лишь частным случаем прохождения другие значения произвольного размера. Это упрощает компилятор для обработки "void" результат или аргумент. Вероятно, вам нужна функция langauge который может отбросить функцию; в C, если вы вызываете непустой результат function foo в следующем выражении: Foo (...); компилятор знает, что foo производит результат и просто игнорирует его. Если void является значением, это отлично работает и теперь "процедуры" (которые просто прилагательное для функции с результатом void) просто тривиальны случаи общих функций.
Void * немного смешнее. Я не думаю, что дизайнеры C думали о пустоте в выше; они просто создали ключевое слово. Это ключевое слово было доступно, когда кто-то нужна точка произвольному типу, поэтому void * как идиома в C. Это действительно работает очень хорошо, если вы интерпретируете пустоту как пустую структуру. Указатель void * - это адрес места, где эта пустая структура имеет был поставлен.
Отбрасывает от void * до T * для других типов T, также работает с этой перспективой. Присвоения указателей - это полный чит, который работает на большинстве распространенных архитектур, чтобы воспользоваться тем фактом, что если у составного типа T есть элемент с подтипом S, физически расположенный в начале T в его макете хранения, тогда литье S * в T * и наоборот, использование одного и того же физического адреса устройства имеет тенденцию к разработке, поскольку большинство указателей машин имеют одно представление. Замена типа S по типу void дает точно такой же эффект, и, таким образом, отбрасывание в/из void * выполняется.
Язык программирования PARLANSE очень хорошо реализует приведенные выше идеи. Мы придумали его дизайн и не обращали пристального внимания на "пустоту" как на возвращение тип и, следовательно, имеют langauge ключевые слова для процедуры. Его в основном просто изменение синтаксиса, но это одна из вещей, с которыми вы не обходитесь, когда вы получаете рабочий код большого тела на языке.
Ответ 7
В С# вы должны использовать ключевое слово void, чтобы указать, что метод не возвращает значение:
public void DoSomeWork()
{
//some work
}
Ответ 8
Три случая использования для void:
-
Подписи функций.
void foo(int bar)
не возвращает значение.int bar(void)
не принимает никаких параметров, но обычно это выражается пустым списком аргументов:int bar()
. Использование ключевого слова void здесь соответствует его значению на английском языке. -
Общий указатель верхнего уровня
void *
, который указывает на неуказанные данные и не может быть разыменован. Здесь значение void отличается от других значений void: universal type vs. no type. -
В выражениях, таких как
(void) new Foo(this)
, означает, что возвращаемое значение намеренно выбрасывается. Здесь использование ключевого слова также соответствует его значению на английском языке.
Случаи 1 и 2 уже были охвачены компанией @Gerald, но случай 3 еще не был рассмотрен.
Ответ 9
Если вы объясняете концепцию новичку, может быть полезно использовать аналогию. Использование void во всех этих случаях аналогично по значению странице в книге, которая имеет следующие слова: "Эта страница оставлена умышленно пустой". Он должен отличать компилятор от того, что должно быть помечено как ошибка, по сравнению с типом, который намеренно остается пустым, потому что это поведение, которое вы хотите.
Он всегда появляется в коде, где обычно вы ожидаете увидеть тип, например, тип возврата или тип указателя. Вот почему в С#, void отображает фактический тип CLR, System.Void, потому что это сам тип.
Некоторые языки программирования никогда не разрабатывали концепцию пустоты, точно так же, как некоторые человеческие культуры никогда не изобретали концепцию нулевого числа. Void представляет такое же продвижение на языке программирования, как понятие нуля представляет собой человеческий язык.
Ответ 10
Это означает "нет значения". Вы используете void, чтобы указать, что функция не возвращает значение или что у него нет параметров или обоих. Это очень похоже на типичное использование слова void на английском языке.
Нельзя путать пустоту с нулем. Null означает для переменной, адрес которой находится в стеке, значение в куче для этого адреса пусто.
Ответ 11
Пустота используется только в сигнатурах метода. Для типов возвращаемых значений это означает, что метод ничего не возвращает вызывающему коду. Для параметров это означает, что никакие параметры не передаются методу
например.
void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}
В С# мы можем опустить void для параметров и записать код выше:
void MethodThatReturnsAndTakesVoid()
{
// Method body
}
Void не следует путать с нулем. Нуль означает переменную, адрес которой находится в стеке, значение в куче для этого адреса пуст.
Ответ 12
Пустота - это неполный тип, который дефинированием не может быть lvalue. Что означает, что ему не может быть присвоено значение.
Таким образом, он также не может иметь никакого значения.
Ответ 13
void означает, что вы не будете возвращать какое-либо значение из функции или метода
Ответ 14
Void означает, что в возвращаемом типе значение не требуется для функции во всех трех языках.
Ответ 15
Void является эквивалентом Sub Visual Basic.