A Deep Exploration of C + + language void and void pointers
1. Overview
Many beginners do not understand the void and void pointer types in the C + + language, so there are some errors in their use.
This article explains the profound meaning of the void keyword and details the use and techniques of void and void pointer types.
meaning of the 2.void
void literal 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 the pointer P1 and p2 are of the same type, then we can assign values directly between P1 and P2;
if P1 and P2 point to different data types, you must use the force type conversion operator to
the pointer type to the right of the operator is converted to the type of the left pointer.
For example:
float *p1;
int *p2;
p1 = p2;
where P1 = P2 statement compiles an error,
hint "' = ': cannot convert from ' int * ' to ' float * ',
must be replaced by:
P1 = (float *) P2;
while void * is different, pointers of any type can be assigned directly to it without forcing type conversions:
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 "untyped" can contain "there is a type," and "there is a type" cannot tolerate "untyped".
The truth is simple, we can say "men and women Are human",
but can't say "man is Man" or "Man is 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 the return value type is used by the compiler as the return integer
type value processing. 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.
"The C + + language has very strict type safety checks," says Dr. Lin Rui, "high quality C/D + + programming"
This is not allowed (the function does not add a type declaration) to occur. But the compiler does not necessarily believe that,
For example, in Visual c++6.0, the compilation of the above add function is error-free and has no warning and is running correctly.
It is therefore not possible to expect the compiler to do strict type checking.
therefore, in order to avoid confusion, we must specify a type for 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 type. This is both the need for good readability of the program,
is also the requirements of programming norms. In addition, after adding the void type declaration, you can also play the code
"self-explanatory" effect. The code's "self-explanatory" 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 parameter is void meaning 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 ();
}
compile correctly and output 1, which means that in C, you can send parameters of any type to a function without parameters,
However, compiling the same code in the C + + compiler will make an error. In C + +,
you cannot pass any parameters to a function that has no parameters.
error message "' Fun ': function does not take 1 parameters".
therefore, 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
according to 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 so determined because it insists:
//The pointer to the algorithm operation must be determined to know its point to the data type size.
///For example:
int *pint;
pint++;//ansi: Right
The result of pint++ is to make it grow sizeof (int).
but the famous GNU (GNU's not UNIX abbreviation) is not so determined
It specifies that the algorithm operation of Void * is consistent with char *.
The following statements are therefore correct in the GNU compiler:
pvoid++;//gnu: Right
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 functionality:
void * PVOID;
(char *) pvoid++;//ansi: correct; GNU: Correct
(char *) pvoid + = 1;//ansi: error; GNU: Correct
There are some differences between GNU and ANSI, in general, the GNU is more "open" than ANSI,
provides support for more syntax. But we should be able to meet the ANSI standards as much as possible when it comes to real design.
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 reflects
The meaning of the memory manipulation function because the object it operates is simply a piece of memory, regardless of whether the inside
What type of deposit is. If the parameter type of memcpy and memset is not void *, but char *,
That's shouting truth 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));//Will intarray clear 0
//Example: memcpy accepts arbitrary type pointers
int intarray1[100], intarray2[100];
memcpy (Intarray1, Intarray2, 100*sizeof (int));//Copy Intarray2 to Intarray1
Interestingly, the memcpy and memset functions return a void * type,
how knowledgeable the writer of standard library functions is!
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, and the variables in the world are "typed",
For example, a person is not a man or a woman (and a shemale?) )。
void appears only for an abstract need if you correctly understand the object-oriented
The concept of "abstract base class" is also very easy to understand the void data type. As cannot be given to abstract base classes
To define an instance, we cannot define a void (the "abstract data type") variable that allows us to compare.
4. Summary
The small void contains a rich philosophy of design, as a program designer,
a deep consideration of the problem is bound to benefit us.
"Reprint" A deep exploration of the C + + language void and void pointers