A first to fourth use Use one:
Define a type of alias, not just a simple macro substitution. Can be used as multiple objects that declare a pointer type at the same time. Like what:
char* PA, PB; This majority does not conform to our intent, it only declares a pointer to a character variable,
and a character variable;
The following works:
typedef char* PCHAR; General in uppercase
Pchar PA, PB; feasible, at the same time declared two pointers to character variables
Although:
Char *pa, *PB;
Also feasible, but relatively not in the form of TypeDef intuitive, especially in the need for a large number of pointers, the way the typedef more convenient.
use two:
Used in the old C code (the specific old did not check), to help struct. In previous code, when declaring struct a new object, you must take a struct, in the form of a struct struct name object name, such as:
struct TAGPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;
In C + +, you can write directly: a struct name Object name, which is:
TagPOINT1 P1;
Someone who thinks it's too much trouble to write a struct too often, then invents:
typedef struct TAGPOINT
{
int x;
int y;
}point;
Point P1; This is less than the original way to write a struct, more convenient, especially in the mass use of the time
Perhaps, in C + +, the use of a typedef is not very large, but understanding it is useful for mastering old code, after all, we may encounter earlier years of code left over in the project.
use three:
Use typedef to define platform-independent types.
For example, to define a floating-point type called real, on the target platform, let it represent the highest precision type:
typedef long double Real;
On Platform II, which does not support long double, replace the following with:
typedef double REAL;
On a platform not supported by double, replace the following:
typedef float REAL;
In other words, when cross-platform, just change the typedef itself on the line, do not make any changes to other source code.
The standard library uses this technique extensively, such as size_t.
In addition, because TypeDef is a new alias that defines a type and is not a simple string replacement, it is more robust than a macro (although the use of macros can sometimes do the above).
use four:
Define a new simple alias for a complex declaration. The method is to replace a part of the complex declaration with an alias in the original declaration, so that the loop takes the part with the variable name to the last replacement and gets the simplest version of the original declaration. Example:
1. Original declaration: Int * (*A[5]) (int, char*); Variable named a, replace a directly with a new alias Pfun:
typedef int * (*PFUN) (int, char*);
The most simplified version of the original declaration:
Pfun A[5];
2. Original declaration: void (*b[10]) (void (*) ()); Variable name B, first replace the right part of the bracket, Pfunparam for alias one:
typedef void (*pfunparam) ();
Replace the left variable B,pfunx to alias two:
typedef void (*PFUNX) (Pfunparam);
The most simplified version of the original declaration:
Pfunx B[10];
3. Original declaration: Doube (*) () (*e) [9]; Variable name e, replace the left part first, Pfuny is alias one:
typedef double (*pfuny) ();
Replace the right-hand variable E,pfunparamy with the alias two.
typedef PFUNY (*pfunparamy) [9];
The most simplified version of the original declaration:
Pfunparamy e;
Understand the "right left" rule available for complex declarations:
From the variable name look, first to the right, and then to the left, a round of parentheses to turn the reading direction; After parsing in parentheses, jump out of parentheses, or in the order of the first right and left, so cycle until the entire statement is analyzed. Example:
Int (*func) (int *p);
First find the variable name func, there is a pair of parentheses outside, and a * number on the left, which means that func is a pointer, then jumps out of the parentheses, looks to the right, and then encounters parentheses, which means that (*FUNC) is a function, so func is a pointer to such a function, the function pointer, Such functions have formal parameters of the int* type, and the return value type is int.
Int (*func[5]) (int *);
Func to the right is an [] operator, description func is an array of 5 elements; func has a * on the left, indicating that the Func element is a pointer (note that the * is not cosmetic func, but is decorated func[5] because [] operator precedence is higher than *, Func first with [] Combined). Jump out of this bracket, look to the right, and also encounter parentheses, stating that the element of the Func array is a pointer to a function type, which points to a function that has a int* type parameter, and the return value type is int.
You can also remember 2 modes:
Type (*) (...) function pointers
Type (*) [] array pointer
Second, two big traps Trap One:
Remember, a typedef is a new alias that defines a type, and unlike macro, it is not a simple string replacement. Like what:
First define:
typedef char* PSTR;
And then:
int mystrcmp (const PSTR, const PSTR);
is the const PSTR actually equivalent to the const char*? No, it's actually equivalent to char* Const.
The reason is that const gives the whole pointer itself a constant, that is, a constant pointer char* const.
In short, remember that when the const and the typedef appear together, the typedef is not a simple string replacement.
Trap Two:
A typedef is syntactically a storage class keyword (like auto, extern, mutable, static, register, etc.), although it does not really affect the storage characteristics of the object, such as:
typedef static INT INT2; Not feasible
Compilation will fail, prompting "more than one storage class specified."
Third, the typedef and the #define的区别 Case One:
Generally speaking, a typedef is better than a #define, especially in a pointer situation. Take a look at the example:
typedef char *PSTR1;
#define PSTR2 char *;
PSTR1 S1, S2;
PSTR2 S3, S4;
In the above variable definition, s1, S2, S3 are all defined as char *, and S4 is defined as char, not the pointer variable we expect, and the root cause is that #define is just a simple string replacement and the typedef is a new name for a type.
Case Two:
The compiler in the following code will report an error, do you know which statement is wrong?
typedef char * PSTR;
Char string[4] = "ABC";
const char *P1 = string;
Const PSTR P2 = string;
p1++;
p2++;
It was p2++ that made a mistake. This question once again reminds us that typedef and #define are different, and that it is not a simple text replacement. The const PSTR P2 in the above code is not equal to the const char * p2. The const PSTR P2 and const long x are essentially indistinguishable, with read-only restrictions on the variable, except that the data type of the variable P2 here is our own definition rather than the intrinsic type of the system. Therefore, the meaning of the const PSTR P2 is that a variable that qualifies the data type char * is P2 read-only, and therefore p2++ error.
Part IV: Using typedef to suppress inferior code Summary: TYPEDEF declarations help create platform-independent types and even hide complex and incomprehensible syntax. In any case, using a typedef can bring unexpected benefits to your code, and you can learn to use typedef to avoid imperfections, making your code more robust.
A typedef declaration, called a TypeDef, creates a new name for an existing type. For example, people often use a typedef to write more beautiful and readable code. The so-called aesthetics, meaning that the typedef can hide clumsy syntax constructs and platform-related data types, thereby enhancing portability and future maintainability. This article will make every effort to uncover the powerful features of the typedef and how to avoid some common pitfalls.
Q: How do I create a platform-independent data type that hides awkward and incomprehensible syntax?
A: Use typedefs to create synonyms for an existing type.
define type names that are easy to remember The most common use of a typedef is to create a type name that is easy to remember, and use it to archive the programmer's intent. The type is now declared in the variable name, located on the right side of the ' typedef ' keyword. For example:
typedef int size; This declaration defines a synonym for int, with a name of size. Note that a typedef does not create a new type. It simply adds a synonym to an existing type. You can use size in any context that requires int:
void measure (Size * psz); Size Array[4];size len = File.getlength (); std::vector <size> vs; A typedef can also mask conforming types, such as pointers and arrays. For example, you don't have to repeatedly define an array of 81 character elements as follows:
Char Line[81];char text[81]; Defines a typedef that you can do whenever you want to use an array of the same type and size:
typedef char LINE[81]; Line text, secondline;getline (text); Similarly, you can hide the pointer syntax as follows:
typedef char * Pstr;int mystrcmp (pstr, pstr); This will take us to the first typedef trap. The standard function strcmp () has two parameters for the ' const char * ' type. Therefore, it may mislead people to declare mystrcmp () as follows:
int mystrcmp (const PSTR, const PSTR); This is wrong, in order, ' const PSTR ' is interpreted as ' char * const ' (a constant pointer to char), not ' const char * ' (a pointer to a constant char). This question is
easy to solve: typedef const CHAR * CPSTR; int mystrcmp (CPSTR, CPSTR); Now is the right thing to remember: whenever you declare a typedef for a pointer, you add a const to the final typedef name so that the pointer itself is a constant, not an object.
Code Simplification The typedef behavior discussed above is somewhat like #define macro, replacing synonyms with its actual type. The difference is that the TypeDef is interpreted at compile time, so the compiler is allowed to deal with text substitutions beyond preprocessor capabilities. For example:
typedef int (*PF) (const char *, const char *); This declaration introduces the PF type as a synonym for function pointers, which has two parameters of the const char * type and a return value of type int. This typedef is essential if you want to use the following form of a function declaration:
PF Register (pf pf); The parameter of the Register () is a PF-type callback function that returns the address of a function with the same signature as the previously registered name. Take a deep breath. Let me show you how to implement this declaration without a typedef:
Int (*register (*PF) (const char *, const char *)) (const char *, const char *); Few programmers understand what it means, let alone the risk of error caused by this convoluted code. Obviously, using typedef here is not a privilege, but a necessity. Skeptics may ask: "OK, does anyone else write this code?" "A quick glance at the header file <csinal> that reveals the signal () function, a function with the same interface.
typedef and Storage class keywords (storage class specifier)
This is not a bit surprising, the TypeDef, like Auto,extern,mutable,static, is a storage-class keyword, as is the register. This is to say that a typedef really affects the storage characteristics of an object; it simply says that the TypeDef declaration looks like a variable declaration of a type such as Static,extern on the composition of the statement. Here's a second trap:
typedef register INT Fast_counter; Incorrect compilation pass. The problem is that you can't have multiple storage-class keywords in the declaration. Because the symbol typedef already occupies the location of the storage class keyword, the register (or any other storage class keyword) cannot be used in a typedef declaration.
Promotion of Cross-platform development
There is another important use of TypeDef, which is to define machine-independent types, for example, you can define a floating-point type called real, and on the target machine it can achieve the highest precision:
typedef long double Real; On a machine that does not support long double, the typedef looks like the following:
typedef double REAL; And, on a machine that does not have a double, the typedef looks like this:
typedef float REAL; Instead of making any changes to the source code, you can compile the application with real type on each platform. The only thing to change is the typedef itself. In most cases, even this tiny change can be done automatically through wonderful conditional compilation. Isn't it? The standard library uses typedef extensively to create such platform-independent types: Size_t,ptrdiff and fpos_t are examples. In addition, a typedef like std::string and Std::ofstream also hides a long, incomprehensible template-specific syntax, such as: Basic_string<char, Char_traits<char> Allocator<char>> and Basic_ofstream<char, char_traits<char>>.
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.