Для чего нужен void c

Для чего нужен void c

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

Для чего нужен void c. Смотреть фото Для чего нужен void c. Смотреть картинку Для чего нужен void c. Картинка про Для чего нужен void c. Фото Для чего нужен void c

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

Примечание: адрес ячейки памяти это всегда положительное целое число. Диапазон адресов простирается от 0 (адрес первой ячейки памяти; часто этот адрес имеет специальное назначение, об этом позже) до положительной целочисленной константы (которая является адресом последней ячейки памяти).

[Переменные указателей]

Мы можем использовать переменные для хранения адресов памяти, и такие переменные известны как переменные указателей. Обычные переменные используются для хранения в себе значений каких-то данных определенного типа (char, int, float и т. д.). Перед использованием переменной в программе мы сначала её декларируем. Специальным образом нам нужно также декларировать переменные и для указателей – чтобы компилятор знал, что мы декларируем переменную как указатель (это не обычная переменная). Делается такая декларация с помощью оператора *, это так называемый оператор косвенного обращения на языке C (indirection operator), иногда его называют оператором разыменования.

Общий синтаксис декларации указателя следующий:

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

Почему для указателей нужно указывать тип данных? По некоторому адресу в памяти могут содержаться какие-то данные, и это понятно. И это может быть данные любого типа char, int, float, даже структура, и т. д. Разница между типами в том, что они могут занимать для себя разное количество памяти. Char требует 1 байт, int может требовать 2 байта (хотя это не всегда так), и float занимает 4 байта. Память, выделенная для всех этих типов это последовательность из нескольких непрерывно следующих друг за другом байт.

Давайте рассмотрим сценарий наподобие следующего, в программе определены 3 переменные:

Предположим, что память системы начинается с адреса 2000H. Теперь символьная переменная ‘a’ будет находиться по адресу 2000H (и займет в памяти 1 байт), тогда как int-переменная ‘b’ займет 2 байта и будет находиться по адресам 2001H и 2002H. И наконец, последняя float-переменная ‘c’ займет 4 байта, и они будут находится в расположенных друг за другом байтах памяти с адресами 2003H, 2004H, 2005H, 2006H. Теперь Вы можете догадаться, зачем надо указывать типы данных, чтобы объявить переменную указателя. Причина в том, что области памяти под переменные выделяются в последовательных, находящихся друг за другом байтах памяти, и количество выделенных байт зависит от типа переменной, которая в них содержится.

Примечание: показанное в этом примере распределение памяти типично для 8-разрядных систем, таких как MSC-51 и AVR. Для 16-битных и 32-разрядных систем реальное распределение памяти для переменных может быть другим, что связано с выравниванием данных в памяти с целью более эффективного использования особенностей процессора.

Таким образом, когда мы декларируем переменную указателя как float *ptr, и затем присваиваем ей адрес обычной float-переменной c, то для компилятора устанавливается привязка указателя ptr ко всей области памяти от 2003H до 2006H. Но сама переменная ptr будет хранить в себе только начальный адрес блока памяти переменной (т. е. в нашем примере это 2003H), а тип указателя будет указывать для компилятора размер этого блока.

Следовательно, чтобы компилятор мог корректно интерпретировать содержимое памяти, соответствующее указателю, для указателя должен быть при декларации указан тип данных. И этот тип данных должен совпадать с типом данных, которые находятся по адресу переменной – тому адресу, который присваивается переменной указателя. Например, если адрес 2000H будет присвоен указателю ptr, то указателю будет соответствовать память, в которой находится символьная переменная ‘a’. В этом случае переменная указателя ptr должна быть декларирована с типом char, как показано ниже:

Примечание: фактически мы могли бы декларировать переменную указателя без какого либо типа данных, используя ключевое слово void. Тогда получится так называемый пустой указатель.

[Присваивание адреса переменной указателя]

Чтобы можно было использовать указатель и его возможности, указателю должен быть присвоен адрес переменной. Указателю можно присвоить адрес как одиночной переменной, так и адрес массива, так и адрес структуры, и адрес переменной класса, и даже адрес переменной указателя. Это делает указатели особенно мощным (но и достаточно опасным при неумелом использовании) инструментом в программировании на языке C. Мы можем играючи обращаться с памятью системы, используя указатели.

Чтобы присвоить адрес переменной указателя мы используем оператор & (оператор взятия адреса переменной). Оператор & возвратит начало места в памяти, где расположена переменная. Пример:

[Обращение к содержимому памяти по указателю]

Теперь мы знаем, как присваивать адрес переменной указателя. Но как можно в программе обратиться к содержимому переменной, адрес которой присвоен указателю? Для этого мы используем тот же оператор косвенного обращения *, который мы использовали для декларации переменной указателя. Операция взятия значения по указателю также называется разыменованием указателя.

Запуск этого кода выведет следующую строку:

[Арифметические операции над указателями]

[Указатели void на языке C]

Обычно переменная указателя декларируется с указанием типа данных содержимого, которое хранится в том месте памяти, на которое ссылается указатель (перевод статьи [2]). Примеры:

Переменная указателя, декларированная на определенный тип, не может содержать в себе адрес переменной другого типа. Это неправильно, и приведет к сообщению об ошибке при компиляции. Пример:

На языке C есть возможность создать указатель на неопределенный тип, так называемый «пустой указатель» (void pointer). Указатель на void это просто переменная указателя, которая декларирована с зарезервированным на языке C ключевым словом void. Пример:

Когда указатель декларируется с ключевым словом void, он становится универсальным. Это значит, что ему может быть присвоен адрес переменной любого типа (char, int, float и т. д.), и это не будет ошибкой.

[Разыменование void-указателя]

Как делается разыменование типизованных указателей с помощью оператора *, Вы уже знаете (если нет, то см. врезку «Что такое указатель»). Но в случае указателя на void нужно использовать приведение типа (typecast) переменной указателя, чтобы выполнить её разыменование (выполнить обращение к содержимому памяти, на которую ссылается void-указатель). Причина в том, что с void-указателем не связан никакой тип, и для компилятора нет никакого способа автоматически узнать, как обращаться к содержимому памяти, связанному с void-указателем. Таким образом, чтобы получить данные, на который ссылается void-указатель, мы делаем приведение указателя к корректному типу данных, которые находятся по адресу, содержащемуся в void-указателе.

Указатели void полезны для программиста, когда заранее неизвестно о типе данных, которые поступают на вход программы. Типичным примером могут служить библиотечные функции манипулирования блоками памяти memcpy, memset и т. п. С помощью void-указателя программист может сослаться на место размещения данных произвольного, заранее неизвестного типа данных. Программа, к примеру, может быть написана таким образом, чтобы запросить у пользователя, какое приведение типа нужно использовать, чтобы правильно обработать входные данные. Ниже приведен в качестве примера кусок подобного кода.

При использовании void-указателей следует помнить, что для них недопустимы арифметические операции, как для типизованных указателей (см. врезку «Что такое указатель»). Пример:

Источник

Урок №29. Тип данных void

Обновл. 11 Сен 2021 |

Тип void — это самый простой тип данных, который означает «отсутствие любого типа данных». Следовательно, переменные не могут быть типа void:

Тип void, как правило, используется в трех случаях:

Использование №1: Указать, что функция не возвращает значение:

Использование №2: Указать, что функция не имеет никаких параметров (перешло из языка Cи):

Указание типа void как «никаких параметров» является пережитком, сохранившимся еще со времен языка Cи. Следующий код равнозначен и более предпочтителен для использования в языке C++:

Правило: Используйте пустой список параметров вместо void для указания отсутствия параметров в функции.

Использование №3: Ключевое слово void имеет третий (более продвинутый) способ использования в языке C++, который мы будем рассматривать на уроке №92.

Поделиться в социальных сетях:

Урок №28. Инициализация, присваивание и объявление переменных

Комментариев: 5

Ключевое слово void имеет третий более продвинутый.
Этот void какой то эпический, уже 2й раз читаю что о нем мы узнаем дальше))) Мне кажется это пасхалка какая-то))

Если все-таки разделять понятия «процедура» и «функция» (понимаю, что в C понятие «процедура» отсутствует), то void станет более понятным.
Процедура — это просто последовательность действий.
Функция — это как бы «ответ на вопрос».
«Отсортируй переданный в параметрах массив» — процедура (void).
«Что получится, если перемножить переданные параметры?» — функция.

Все конспектировал)
довольно понятно,когда перечитываешь)

Какой же этот void задрочливый и сложен для понимания (для меня)((((((

Источник

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

Глядя на то, чтобы получить основы, на которых исходит термин VOID, и почему его называют недействительным. Цель вопроса состоит в том, чтобы помочь кому-то, у кого нет опыта работы в C, и вдруг смотрит на кодовую базу на основе C.

ОТВЕТЫ

Ответ 1

В основном это означает «ничего» или «нет типа»

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

Ответ 2

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

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

Ответ 3

Ответ 4

Существует два способа использования void:

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

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

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

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

Затем поток ядра просматривает список отложенной работы, и когда он достигает этого node, он эффективно выполняет:

Ответ 5

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

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

Ответ 6

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

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

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

Аналогично, я могу думать о функции, не требующей значений, принимающих пустую структуру, например, «void».

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

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

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

Ответ 10

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

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

Ответ 11

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

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

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

Ответ 12

Таким образом, он также не может иметь никакого значения.

Ответ 13

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

Ответ 14

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

Ответ 15

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

Источник

Урок №92. Указатели типа void

Обновл. 13 Сен 2021 |

Указатель типа void (или «общий указатель») — это специальный тип указателя, который может указывать на объекты любого типа данных! Объявляется он как обычный указатель, только вместо типа данных используется ключевое слово void:

Указатель типа void может указывать на объекты любого типа данных:

Однако, поскольку указатель типа void сам не знает, на объект какого типа он будет указывать, разыменовать его напрямую не получится! Вам сначала нужно будет явно преобразовать указатель типа void с помощью оператора static_cast в другой тип данных, а затем уже его разыменовать:

Результат выполнения программы:

Возникает вопрос: «Если указатель типа void сам не знает, на что он указывает, то как мы тогда можем знать, в какой тип данных его следует явно конвертировать с помощью оператора static_cast?». Никак, это уже на ваше усмотрение, вам самим придется выбрать нужный тип. Например:

Результат выполнения программы:

Указателям типа void можно присвоить нулевое значение:

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

Также не получится выполнить адресную арифметику с указателями типа void, так как для этого требуется, чтобы указатель знал размер объекта, на который он указывает (для выполнения корректного инкремента/декремента). Также нет такого понятия, как ссылка на void.

Заключение

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

Здесь компилятор промолчит. Но что будет в результате? Непонятно!

Хотя код, приведенный выше, кажется аккуратным способом заставить одну функцию обрабатывать несколько типов данных, в языке C++ есть гораздо лучший способ сделать то же самое (через перегрузку функций), в котором сохраняется проверка типов для предотвращения неправильного использования. Также для обработки нескольких типов данных можно использовать шаблоны, которые обеспечивают хорошую проверку типов (но об этом уже на следующих уроках).

Если вам все же придется использовать указатель типа void, то убедитесь, что нет лучшего (более безопасного) способа сделать то же самое, но с использованием других механизмов языка C++!

В чём разница между нулевым указателем и указателем типа void?

Ответ

Указатель типа void — это указатель, который может указывать на объект любого типа данных, но он сам не знает, какой это будет тип. Для разыменования указатель типа void должен быть явно преобразован с помощью оператора static_cast в другой тип данных. Нулевой указатель — это указатель, который не указывает на адрес. Указатель типа void может быть нулевым указателем.

Поделиться в социальных сетях:

Источник

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

15 ответов

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *