Что означает void в C, C++ и c#?

глядя, чтобы получить основы о том, где термин" void", и почему это называется пустота. Цель вопроса состоит в том, чтобы помочь кому-то, у кого нет опыта c/" class="blnk">C, и внезапно смотрит на кодовую базу на основе C.

15 ответов


в основном это означает "ничего"или" нет типа"

существует 3 основных способа использования void:

  1. функции аргумент: int myFunc(void) -- функция ничего не принимает.

  2. функция возвращаемое значение: void myFunc(int) -- функция не возвращает ничего

  3. общий указатель данных:void* data -- "данные" - это указатель на данные неизвестного типа и не могут быть разыменованы

Примечание:void в функции аргумент необязателен в C++, поэтому int myFunc() точно так же, как int myFunc(void), и он полностью исключен в C#. Это всегда требуется для возвращаемого значения.


Я всегда считал, что это означает отсутствуют. Вот четыре случая на языке C, который соответствует этому использованию отсутствуют

  • R f(void) - параметры функции отсутствуют
  • void f(P) - возвращаемое значение отсутствуют
  • void *p - тип того, на что указывает is отсутствуют
  • (void) p - использование значение отсутствуют

другие потомки C используют его для других вещей. The D язык программирования использует его для случаев, когда инициализатор отсутствуют

  • T t = void; - инициализации значение отсутствуют

Это означает "нет значения". Вы используете void чтобы указать, что функция не возвращает значение или что у нее нет параметров или обоих. В значительной степени согласуется с типичным использованием word пустота на английском языке.


есть два способа использовать void:

void foo(void);

или

void *bar(void*);

первый указывает, что аргумент не передается или что аргумент не возвращается.

второй сообщает компилятору, что нет никакого типа, связанного с данными, что означает, что вы не можете использовать данные, указанные до тех пор, пока он не будет приведен к известному типу.

например, вы увидите void* используется, когда у вас есть интерфейс, который называет функция, параметры которой не могут быть известны заранее.

например, в ядре Linux при отсрочке работы вы настроите функцию для запуска в последнее время, дав ей указатель на выполняемую функцию и указатель на данные, которые будут переданы функции:

struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data        = somedata;
} deferred_work;

затем поток ядра переходит через список отложенных работ, и когда он попадает на этот узел, он эффективно выполняет:

bar(somedata);

потом в баре у вас есть:

void bar(void* mydata) {
    int *data = mydata;
    /* do something with data */;
}

это указывает на отсутствие возвращаемого значения в функции.

некоторые языки имеют два вида подпрограмм: процедуры и функции. Процедуры - это просто последовательность операций, в то время как функция-это последовательность операций, возвращающих результат.

в C и его производных разница между ними не является явной. Все в основе своей является функцией. the void ключевое слово указывает, что это не "функция", поскольку он не возвращает значение.


подумайте о пустоте как о "пустой структуре". Позвольте мне объяснить.

каждая функция принимает последовательность параметров, где каждый параметр имеет тип. Фактически, мы могли бы упаковать параметры в структуру, причем слоты структуры соответствуют параметрам. Это делает каждую функцию иметь ровно один аргумент. Аналогично, функции производят результат, который имеет тип. Это может быть логическое значение, или это может быть float, или это может быть структура, содержащая произвольный набор других типизированных значений. Если мы хотим languge, который имеет несколько возвращаемых значений, легко просто настаивать, чтобы они были упакованы в структуру. Фактически, мы всегда можем настаивать на том, что функция возвращает структуру. Теперь каждая функция принимает ровно один аргумент и производит ровно одно значение.

теперь, что происходит, когда мне нужна функция, которая производит значение "нет"? Ну, считай, что я получаю, когда я формирую структуру с 3 слотами: это имеет 3 значения. Когда у меня есть 2 слота, он держит два ценности. Когда это имеет один слот, одно значение. И когда он имеет нулевые слоты, он держится... э, нулевые значения или " нет " значения. Итак, я могу думать о функции, возвращающей void как возврат структуры, не содержащей значений. Вы даже можете решить, что "пустота" является просто синонимом типа, представленного пустой структурой, вместо ключевого слова на языке (возможно, это просто предопределенный тип:)

аналогично, я могу думать о функции, не требующей значений, как о принятии пустой структуры, например, "пустой."

Я даже могу реализовать свой язык программирования таким образом. Передача значения void занимает нулевые байты, поэтому передача значений void - это просто частный случай передачи другие значения произвольного размера. Это упрощает обработку компилятором результат или аргумент" void". Вы, вероятно, хотите функцию langauge это может отбросить результат функции; в C, если вы вызываете результат Non-void функция foo в следующей инструкции: foo.(..); компилятор знает, что Foo производит результат и просто игнорирует его. Если void является значением, это отлично работает и теперь "процедуры" (которые просто прилагательное для функции с результатом void) просто тривиальные специальные случаи общих функций.

Void* немного смешнее. Я не думаю, что дизайнеры C думали о пустоте в выше пути; они просто создали ключевое слово. Это ключевое слово было доступно, когда кто-то нужна точка произвольного типа, таким образом, void* как идиома в C. Это на самом деле работает довольно хорошо, если вы интерпретируйте пустоту как пустую структуру. Указатель void* - это адрес места, где эта пустая структура имеет был поставлен.

бросает из void* в T* для других типов T, также работает с этой перспективой. Приведения указателей-это полный обман, который работает на большинстве распространенных архитектур, чтобы воспользоваться тем фактом, что если составной тип T имеет элемент с подтипом S, физически расположенный в начале T в его макете хранения, то приведение S* В T* и наоборот с использованием того же самого физический адрес машины имеет тенденцию работать, так как большинство указателей машины имеют одно представление. Замена типа S на тип void дает точно такой же эффект, и, таким образом, литье в/из void* работает.

язык программирования PARLANSE реализует вышеуказанные идеи довольно близко. Мы дурачились в его дизайне и не обращали пристального внимания на" пустоту " как возвращение введите и, таким образом, ключевые слова langauge для процедуры. Его в основном просто изменение синтаксиса, но его один из вещи, до которых ты не доберешься, как только доберешься. большой рабочий код тела на языке.


в c# вы бы использовали ключевое слово void, чтобы указать, что метод не возвращает значение:

public void DoSomeWork()
{
//some work
}

три случая использования для void:

  1. функции подписи. void foo(int bar) не возвращает значение. int bar(void) не принимает никаких параметров, но обычно это выражается с пустым списком аргументов: int bar(). Использование ключевого слова void здесь соответствует его значению на английском языке.

  2. универсальный указатель верхнего типа void * это указывает на неопределенные данные и не может быть разыменовано. Здесь значение пустоты отличается от других значений пустоты: всеобщий тип и тип.

  3. в бросках, таких как (void) new Foo(this) для обозначения того, что возвращаемое значение намеренно выбрасывается. Здесь ключевое слово usage также соответствует его значению на английском языке.

случаи 1 и 2 уже были охвачены @Gerald, но случай 3 еще не был рассмотрен.


Если вы объясняете концепцию новичку, может быть полезно использовать аналогию. Использование слова " пустота "во всех этих случаях аналогично значению страницы в книге, которая имеет следующие слова:" эта страница намеренно оставлена пустой."Он должен различать компилятор между чем-то, что должно быть помечено как ошибка, и типом, который намеренно должен быть оставлен пустым, потому что это поведение, которое вы хотите.

Он всегда появляется в коде, где обычно вы ожидалось бы увидеть тип, такой как возвращаемый тип или тип указателя. Вот почему в C# void сопоставляется с фактическим типом CLR System.Пустота, потому что она сама по себе является типом.

некоторые языки программирования никогда не разрабатывали концепцию пустоты, так же как некоторые человеческие культуры никогда не изобретали концепцию числа ноль. Void представляет собой то же продвижение в языке программирования, что и концепция нуля для человеческого языка.


Это означает "нет значения". Вы используете void, чтобы указать, что функция не возвращает значение или что у нее нет параметров или обоих.Это очень согласуется с типичным использованием слова void в английском языке.

Void не следует путать с null. Null означает для переменной, адрес которой находится в стеке, значение в куче для этого адреса пустое.


Void используется только в сигнатурах метода. Для возвращаемых типов это означает, что метод ничего не возвращает в вызывающий код. Для параметров это означает, что никакие параметры не передаются методу

например

void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}

В C# мы можем опустить void для параметров и написать вышеуказанный код как:

void MethodThatReturnsAndTakesVoid()
{
// Method body
}

Void не следует путать с null. Null означает для переменной, адрес которой находится в стеке, значение в куче для этого адреса пустой.


Void-неполный тип, который по дефиниции не может быть lvalue. Что означает, что ему не может быть присвоено значение.

поэтому он также не может содержать любое значение.


void означает, что вы не будете возвращать какое-либо значение из функции или метода


Void означает отсутствие значения, необходимого для возвращаемого типа функции на всех трех языках.


Void является эквивалентом суб Visual Basic.