2014-09-22 1 views
4

Я почти закончил свою книгу C Primer Plus, и я собираюсь попасть в структуры и союзы и т. Д. И т. Д., Но я до сих пор не полностью понимаю, что именно означает ключевое слово void. Что делает пустота? Как это работает? И когда я должен его использовать?Что такое тип void и как он работает?

я понимаю, что

void function(void) 

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

int function(void); //has a return of type int -- voids args 
void function(int); //voids return type -- takes type int as an arg 

я также понимаю, что

void * p = 0L; 

действует код и что это в основном указатель на аннулируются с инициализируется значением 0 в длину.

но есть какое-либо значение или цель его использования таким образом

void k = 0; 

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

size_t fwrite(const void * restrict ptr, ...more args...); 

, так как первый аргумент не фиксированный типа, моя книга описывает это как «тип catchall для указателей» и что «Pre-ANSI C использует для этого аргумента тип char *, который требует от вас фактических аргументов типа для этого типа».

Означает ли это, что я могу использовать любой тип данных? И если да, то это ограничивается указателями и функциями только?

Снова ... Меня не интересует, как преобразовать int в пустоту. Меня не интересует, является ли указатель-на-void действительным, а просто о том, как эффективно использовать это ключевое слово. Я беспокоюсь о том, «Когда я должен его использовать?» и «Как его использовать?».

Заранее благодарим за любые ответы.

ответ

6

есть какое-либо значение или цель его использования таким образом

void k = 0;

Нет, это утверждение не имеет никакого смысла, и компилятор будет жаловаться на неполный тип , Обратите внимание на то, что всякий раз, когда вы видите void, используемый в объявлении типа, это следует *, который указывает указатель, как:

void *foo = nil; 

В этом случае, вы сообщаете компилятору, что foo является указателем, который на самом деле все, что нужно знать, чтобы создать foo. Без * вы пытаетесь объявить переменную, у которой нет типа, и это не то, с чем может работать компилятор (или человек, если на то пошло).

, так как первый аргумент не фиксированный типа, моя книга описывает это как являющиеся «типа неоднородной для указателей»

Первого аргумент является «фиксированный типа» - тип является указателем. Верно, что тип указателя указывает на неуказанный, но сам параметр является указателем.

Означает ли это, что я могу использовать любой тип данных?

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

+2

спасибо. моя книга не входила в детали. это помогает прояснить некоторые недостающие детали из моего понимания того, что потенциально происходит с этими типами данных. также помогает напомнить, что указатель - это тип, который является тем, что ускользает из моей памяти. спасибо за помощь новичку C. Это мой первый «реальный программирующий язык», и я пытаюсь понять как можно больше основных понятий, насколько могу, по мере того, как я продвигаюсь дальше к своим исследованиям. – jargonjunkie

3

Есть три основных ситуации, в которых используются void типа. Могут быть и другие крайние ситуации, но эти три - это то, где вы увидите void, может быть, в 99% случаев.

Это помогает понять это, имея в виду, что «пустота» означает «нет типа здесь», как в «тип данных».

1) Объявить функцию, которая не возвращает значения, в отличие от функции, которая возвращает некоторое значение.

2) Объявляет функцию, которая не принимает никаких параметров, в отличие от Funciton, который принимает один или несколько параметров.

3) "указатель на аннулированию" ситуацию.

Третий случай в основном определяет общий указатель. Указатель на ... что-то, но это «что-то» не важно в разделе кода, который имеет дело с указателем.

Например, вот страница руководства для memcpy функции():

MEMCPY(3)     Linux Programmer's Manual     MEMCPY(3) 

NAME 
     memcpy - copy memory area 

SYNOPSIS 
     #include <string.h> 

     void *memcpy(void *dest, const void *src, size_t n); 

DESCRIPTION 
     The memcpy() function copies n bytes from memory area src to memory 
     area dest. The memory areas must not overlap. Use memmove(3) if the 
     memory areas do overlap. 

Вы можете прочитать остальную часть страницы вручную самостоятельно. memcpy() принимает пару указателей, которые определяют блок памяти для копирования. memcpy() не волнует, на что указывают указатели. Это не нужно знать, поэтому прототип функции указывает, что любой указатель может быть передан ему. Указывает на int, указатель на char или указатель на некоторый экземпляр класса.

+0

спасибо. это помогло прояснить, что сказал калеб выше. – jargonjunkie