Pod względem funkcjonalnym i składniowym, czy istnieje różnica między funkcją, której prototypem jest int foo(void)
i int foo(void *)
?
Znam różnicę między, na przykład, int bar(int)
a int bar(int *)
- jeden z nich szuka int, a drugi szuka wskaźnika int. Czy void
zachowuje się w ten sam sposób?
c++
c
function-prototypes
Nick Reed
źródło
źródło
foo(void)
ifoo()
.Odpowiedzi:
Z tej odpowiedzi na temat inżynierii oprogramowania
void
traktujemy specjalnie, w zależności od tego, jak jest używana. WC
iC++
,void
służy do wskazania nieobecności danego typu danych, podczas gdyvoid *
jest używany do wskazywania wskaźnik, który wskazuje na jakiś danych / przestrzeni w pamięci, które nie mają typu.void *
nie można samodzielnie wyrejestrować i należy go najpierw przenieść na inny typ. Ta obsada nie musi być jawna wC
, ale musi być jawna wC++
. (Właśnie dlatego nie wylewamy wartości zwracanej przez mallocvoid *
).W przypadku użycia z funkcją jako parametrem
void
oznacza całkowity brak jakichkolwiek parametrów i jest jedynym dozwolonym parametrem. Próba użycia void jak typu zmiennej lub dołączenia innych argumentów powoduje błąd kompilatora:Podobnie niemożliwe jest zadeklarowanie zmiennej typu
void
:void
jako wartość zwracana dla funkcji oznacza, że żadne dane nie zostaną zwrócone. Ponieważ nie można zadeklarować zmiennej typuvoid
, nie można uchwycić wartości zwracanej przezvoid
funkcję, nawet za pomocą pustego wskaźnika.Typless
void *
to inna sprawa. Pusty wskaźnik wskazuje wskaźnik do lokalizacji w pamięci, ale nie wskazuje rodzaju danych w tym wskaźniku. (Jest to używane do osiągnięcia polimorfizmu w C , na przykład z funkcją qsort ()) . Te wskaźniki mogą być jednak trudne w użyciu, ponieważ bardzo łatwo jest przypadkowo rzucić je na niewłaściwy typ. Poniższy kod nie wrzuci żadnych błędów kompilatoraC
, ale spowoduje niezdefiniowane zachowanie:Poniższy kod jest jednak całkowicie legalny; rzutowanie na i z pustego wskaźnika nigdy nie zmienia wartości, którą posiada.
Jako parametr funkcji
void *
wskazuje, że typ danych przekazywanych przez wskaźnik nie jest znany i od programisty zależy, czy odpowiednio zajmie się tym, co znajduje się w tym miejscu pamięci. Jako wartość zwracanavoid *
oznacza, że typ zwracanych danych nie jest znany lub jest bez typu i musi być obsługiwany przez program.tl; dr
void
w prototypie funkcji oznacza „brak danych” i wskazuje brak wartości zwracanej lub brak parametrów,void *
w prototypie funkcji oznacza „dane wskazane wskaźnikiem tej funkcji nie mają znanego typu” i wskazuje parametr lub wartość zwracaną którego wskaźnik musi być rzutowany na inny typ, zanim będzie można użyć danych na wskaźniku.źródło
void * ... must be cast to another type first, but may be done so without an explicit cast.
Nieprawda w C ++. W C ++ formularz konwersjivoid*
musi być jawny. PS nazywając rzutowanie jawne jest zbędne, ponieważ rzutowanie jest z definicji jawną konwersją.foo(void)
- funkcja bez parametrówfoo(void *)
- funkcja z jednymvoid *
parametremCo to jest
void *
? Jest to tylko wskaźnik do danych bez określonego typu. Można go rzutować na dowolny inny typ wskaźnikaźródło
(type) vs. (type *)
wszechświecie par, ponieważ pustka nie jest tak naprawdę typem.Jest różnica:
int foo(void)
deklaruje funkcję, która nie przyjmuje żadnych argumentów.int foo(void *)
deklaruje funkcję, która akceptuje pojedynczy argument typuvoid*
.W C ++
int foo(void)
jest równoważnyint foo()
.źródło