void and void pointers introduce "go"

Source: Internet
Author: User

This article was reproduced from: http://blog.csdn.net/renren900207/article/details/20769503

A void type pointer (such as void *p) points to a data type that is not deterministic, or that can be of any type. The data in the void type pointer cannot be accessed, and if it is not to be accessed, the void type pointer can be converted to a type that matches the data type pointed to by the explicit conversion.

1. Any type of pointer can be explicitly converted to void type without loss of data.

A 2.void type pointer can be explicitly converted to a pointer with a smaller or identical storage alignment limit, but the data may be distorted. The so-called "Same storage alignment limit" refers to the amount of data in memory that is referred to by the void type pointer is equal to the length of the data in memory that the explicitly converted pointer refers to, such as P1 refers to the original data in memory accounted for 2 bytes, p2 refers to the data in memory also accounted for two data. However, it should be noted that only the conversion of the data type consistent with the pointer before and after the conversion will keep the data not distorted, and if the type is inconsistent, it may be distorted even with the same storage alignment limit.

3. If you convert a pointer of type void to a pointer with a greater storage alignment limit, an invalid value is generated.

Meaning of Void

Void is no type, void * is an untyped pointer, and can point to any data type.
void pointer Usage specification
The ①void pointer can point to any type of data, that is, a pointer to an arbitrary data type to assign a value to the void pointer. For example:
int * PINT;
void *pvoid;
PVOID = pint; /* but not pint= pvoid; */
If you want to assign pvoid to other type pointers, you need to force type conversions such as: pint= (int *) pvoid;

② in the Ansic standard, it is not allowed to perform arithmetic operations such as pvoid++ or pvoid+=1 on void pointers, as in GNU, because, by default, the GNU considers void * to be the same as char *. sizeof (*pvoid) = = sizeof (char).

The role of Void
① the limit returned by the function.
② the qualification of function parameters.
When a function does not need to return a value, you must use void qualification. For example: void func (int, int);
The void qualifier must be used when the function does not allow the parameter to be accepted. For example: int func (void).

Because the void pointer can point to any type of data, that is, a pointer to an arbitrary data type assigns a value to the void pointer, you can also use a void pointer as a function parameter so that the function can accept pointers of any data type as arguments. For example:
void * memcpy (void *dest, const void *SRC, size_t len);
void * memset (void * buffer, int c, size_t num);

------------------------------------------------------------------------------

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 "untyped", void* is "untyped pointer", and 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 Voida 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.
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 the force type conversion operator to convert the pointer type to the right of the assignment operator to the type of the left pointer.
For example:
float * P1;
In t* p2;
P1 = p2;
where P1 = P2 statement will compile error, prompt "' = ': cannotconvertfrom ' int * ' to ' float * '", must be changed to:
p1= (float*) P2;
Unlike void*, a pointer of any type 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 type conversions. 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 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 "' = ': Cannotconvertfrom ' 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 (INTA,INTB)
{
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 security checks and does not allow this to happen (the function does not add a type declaration)," said Dr. Lin Rui, "high quality C + + programming". However, the compiler does not necessarily think so, for example, in visualc++6.0 the above add function compile error-free and no warning and run correctly, so you can not hope that the compiler will do a strict type check.
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 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-explanatory" code can annotate itself. [Page]
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)
{
RETURN1;
}
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 TurboC2.0:
#include "stdio.h"
Fun ()
{
RETURN1;
}
Main ()
{
printf (/"%d/", Fun (2));
GetChar ();
}
Compiles correctly and outputs 1, which means that in C, you can pass arguments of any type to a function without parameters, but compiling the same code in the C + + compiler will make an error. In C + +, you cannot pass any parameters to a function without parameters, and the error "' Fun ': functiondoesnottake1parameters".
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
By the ANSI (Americannationalstandardsinstitute) 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 ' Snotunix 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: Right; GNU: Right
(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 we should be able to meet the ANSI standards as much as possible when it comes to real design.
Rule four if the argument to a function can be any type of pointer, declare its argument as void*
Typical function prototypes, such as memory manipulation functions memcpy and memset, are:
void * memcpy (Void*dest,constvoid*src,size_tlen);
void * memset (void*buffer,intc,size_tnum);

Thus, 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, regardless of what type of memory it 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]; [Page]
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 the 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". Just as it is not possible to define an instance of an abstract base class, we cannot define a void (the "abstract data type") variable that allows us to compare.


4. Summary
The small void contains a very rich design philosophy, as a program designer, a deep level of thinking about the problem will certainly benefit us.

void and void pointers introduce "go"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.