1. Overview
Many beginners do not understand the void and void pointer types in C/C, so there are some errors in their use. This article explains the deep meaning of the void keyword and
Detailed methods and techniques for using void and void pointer types.
Meaning of the 2.void
Void literally means "no type",void * is "untyped pointer", void * can point to any type of data。
Void is almost only "annotated" and restricts the function of the program, since no one will ever define a void variable, let's try to define:
void A;
This line of statement compiles with an error, prompting "illegal use of type ' void '". However, even if the compilation of void A does not go wrong, it does not have any practical significance.
Void really plays a role in:
(1) The qualification of function return;
(2) The qualification of function parameters.
We will specify the above two points in the third section.
It is well known that if pointers P1 and p2 are of the same type, then we can assign values directly between P1 and P2, and if P1 and P2 point to different data types, you must use mandatory type
The conversion operator converts the pointer type to the right of the assignment operator to the type of the left pointer.
For example:
float *P1;
int *p2;
P1 = p2;
where P1 = P2 statement will compile error, prompt "' = ': cannot convert from ' int * ' to ' float * '", must be changed to:
P1 = (float *) P2;
andvoid * is different, any type of pointer can be assigned directly to it, without forcing the type conversion:
void *p1;
int *p2;
P1 = p2;
This does not mean, however, that void * can also be assigned to other types of pointers without forcing the type to convert. Because "no type" can contain "have type", "have type" cannot package
the "no type" tolerance. The truth is simple, we can say "men and women are people", but can not say "man is a Man" or "man is a woman." The following statement compiles an error:
void *p1;
int *p2;
P2 = p1;
Hint "' = ': cannot convert from ' void * ' to ' int * '".
Use of 3.void
The following rules are given for the use of the Void keyword:
Rule one if the function does not return a value, it should be declared as void type
In the C language, a function that is not qualified with a return value type is processed by the compiler as a return integer. But many programmers mistakenly think of it as void type. For example:
Add (int a, int b)
{
return a B;
}
int main (int argc, char* argv[])
{
printf ("2 3 =%d", add (2, 3));
}
The result of the program running is output:
2 3 = 5
This means that a function that does not add a return value description is indeed an int function.
Dr. Lin Rui, "high-quality C/C programming", mentions that "there is a strict type-safety check in the language, which does not allow this to happen" (meaning that the function does not add a type declaration). But compile
The compiler does not necessarily think so, for example, in Visual C 6.0, the above Add function compiles without errors or warnings and runs correctly, so you cannot expect the compiler to do strict type checking.
Therefore, in order to avoid confusion, we must specify the type of any function without a leak when we write a C + + program. If the function does not return a value, be sure to declare it as void class
Type. This is both the need for good readability of the program and the requirements of programming norms. In addition, the "self-commenting" function of the code can also be played after the void type declaration is added. The code's "self-injection
The code can annotate itself.
Rule two if the function has no arguments, declare that its argument is void
Declare one of these functions in the C language:
int function (void)
{
return 1;
}
It is not legal to make the following call:
function (2);
Because in C, the function argument is void means that the function does not accept any arguments.
We compile in Turbo C 2.0:
#include "stdio.h"
Fun ()
{
return 1;
}
Main ()
{
printf ("%d", Fun (2));
GetChar ();
}
Compiles correctly and outputs 1, which means that in C, you can send parameters of any type to a function without parameters, but it is an error to compile the same code in the C compiler. In C
, you cannot pass any parameters to a function without parameters, and the error prompts "' Fun ': function does not take 1 parameters".
So, whether in C or C, if the function does not accept any arguments, be sure to indicate that the argument is void.
Rule three beware of using void pointer types
By the ANSI (American National standards Institute) standard, you cannot perform algorithmic operations on void pointers, that is, the following operations are not valid:
void * PVOID;
PVOID; ANSI: Error
PVOID = 1; ANSI: Error
The ANSI standard is determined because it insists that the pointer to the algorithm operation must be determined to be aware of its point to the data type size.
For example:
int *pint;
Pint; ANSI: Correct
The result of pint is to make it grow sizeof (int).
However, the famous GNU (GNU's not UNIX abbreviation) does not assume that it specifies that the algorithm operation of Void * is consistent with char *.
The following statements are therefore correct in the GNU compiler:
PVOID; GNU: Correct
PVOID = 1; GNU: Correct
The result of Pvoid's execution was that it increased by 1.
In the actual program design, in order to meet the ANSI standard and improve the portability of the program, we can write code that implements the same function:
void * PVOID;
(char *) pvoid; ANSI: correct; GNU: Correct
(char *) pvoid = 1; ANSI: Error; GNU: correct
There are some differences between GNU and ANSI, and in general, the GNU is more "open" than ANSI, providing support for more grammars. But when it comes to real design, we should try to cater to
ANSI Standard.
Rule four if the parameter of a function can be any type of pointer, then declare its argument to be void *
Typical function prototypes, such as memory manipulation functions memcpy and memset, are:
void * memcpy (void *dest, const void *SRC, size_t len);
void * memset (void * buffer, int c, size_t num);
In this way, any type of pointer can be passed into memcpy and memset, which also truly embodies the meaning of the memory manipulation function, because the object it operates is only a piece of memory, not
What type of memory this piece of RAM is. If the parameter type of memcpy and memset is not void *, but char *, then shouting truth is strange! Such memcpy and memset are obviously not a
"Pure, out of the vulgar" Function!
The following code executes correctly:
Example: Memset accepts arbitrary type pointers
int intarray[100];
memset (intarray, 0, 100*sizeof (int.)); The intarray will be cleared 0
Example: memcpy accepts arbitrary type pointers
int intarray1[100], intarray2[100];
memcpy (Intarray1, Intarray2, 100*sizeof (int.)); Copy the Intarray2 to Intarray1
Interestingly, the memcpy and memset functions return a void * type, and the writer of standard library functions is so knowledgeable!
Rule five void cannot represent a real variable
The code below attempts to have void represent a real variable, so it's all the wrong code:
void A; Error
function (void a); Error
Void embodies an abstraction in which variables in the world are "typed", such as a person who is not a man or a woman (and a shemale?). )。
Void appears only for an abstract need, and it is easy to understand the void data type if you correctly understand the concept of an object-oriented "abstract base class". As cannot be pumped
As the base class defines an instance, we cannot define a void (the "abstract data type") variable that lets us make an analogy.
void type and void pointer