In-depth usage Summary of C ++ typedef (mandatory)

Source: Internet
Author: User

Purpose 1 and 4
Purpose 1:
Define a type of Alias, not just a simple macro replacement. It can be used as multiple objects that declare the pointer type at the same time. For example:
Char * pa, pb; // most of them do not conform to our intention. It only declares a pointer to a character variable,
// And a character variable;
The following are feasible:
Typedef char * PCHAR; // generally, uppercase is used.
PCHAR pa, pb; // feasible. Two pointers pointing to character variables are declared at the same time.
Although:
Char * pa, * pb;
It is also feasible, but it is not intuitive in the form of typedef, especially where a large number of pointers are required, the typedef method is more convenient.
Purpose 2:
It is used in the code of the old C (not checked for many old ones) to help struct. In the previous Code, when declaring a new struct object, you must carry the struct, that is, the form is: struct structure name object name, such:
Struct tagPOINT1
{
Int x;
Int y;
};
Struct tagPOINT1 p1;
In C ++, you can directly write: Structure name Object Name, namely:
TagPOINT1 p1;
It is estimated that it is too troublesome for someone to write another struct, so they invented:
Typedef struct tagPOINT
{
Int x;
Int y;
} POINT;
POINT p1; // in this way, a struct is written less than the original method, which is easier to use, especially when it is used in a large amount.
Maybe, in C ++, typedef is not very useful, but understanding it is helpful for mastering the old code, after all, we may encounter code that was left behind in earlier years in the project.
Purpose 3:
Use typedef to define platform-independent types.
For example, define a floating point type called REAL. On the target platform 1, make it the highest precision type:
Typedef long double REAL;
On Platform 2 that does not support long double, change:
Typedef double REAL;
On Platform 3 that is not supported by double, change:
Typedef float REAL;
That is to say, when using a cross-platform system, you only need to change the typedef itself, without any modifications to other source codes.
This technique is widely used in the standard library, such as size_t.
In addition, because typedef defines a new type of Alias, it is not a simple string replacement, so it is more robust than a macro (although it can do the above when a macro is used ).
Purpose 4:
Define a new simple alias for complex statements. The method is: gradually replace a part of the complex declaration with an alias in the original declaration. In this loop, leave the part with the variable name to the final replacement, and the most simplified version of the original declaration is obtained. Example:
1. Original Declaration: int * (* a [5]) (int, char *);
The variable name is a. replace a with a new alias pFun:
Typedef int * (* pFun) (int, char *);
The most simplified version of the original statement:
PFun a [5];
2. Original Declaration: void (* B [10]) (void (*)());
The variable name is B. Replace pFunParam with alias 1 in the brackets on the right:
Typedef void (* pFunParam )();
Replace B with the variable on the left, and pFunx with alias 2:
Typedef void (* pFunx) (pFunParam );
The most simplified version of the original statement:
PFunx B [10];
3. original statement: doube (*) (* e) [9];
The variable name is e. Replace the left part with pFuny as Alias 1:
Typedef double (* pFuny )();
Replace the variable e on the right, and pFunParamy is alias 2.
Typedef pFuny (* pFunParamy) [9];
The most simplified version of the original statement:
PFunParamy e;
Understand the "right-left rule" available for complex statements ":
Starting from the variable name, start from the right to the left, and then turn the reading direction when it comes to a parentheses. After the analysis in the parentheses, the brackets will jump out of the brackets, or in the order of right to left, until the entire statement is analyzed. Example:
Int (* func) (int * p );
First, find the variable name func, and there is a pair of parentheses on the outside, and there is a * sign on the left, which indicates that func is a pointer. Then jump out of the parentheses and look at the right first, this indicates that (* func) is a function, so func is a pointer to this type of function, that is, a function pointer. This type of function has an int * type parameter, and the return value type is int.
Int (* func [5]) (int *);
The right side of func is a [] Operator, indicating that func is an array with five elements; there is a * on the left of func, indicating that the func element is a pointer (note that * is not a modifier of func, instead, modify func [5] Because the [] operator has a higher priority than *, and func is first combined ). Jump out of the brackets and look at the right side. The parentheses indicate that the element of the func array is a pointer of the function type. It points to an int * type parameter and the return value type is int.
You can also remember two modes:
Type (*) (...) function pointer
Type (*) [] array pointer
Second, two traps
Trap 1:
Remember, typedef defines a new type of alias. Unlike macros, typedef is not a simple string replacement. For example:
First, define:
Typedef char * PSTR;
Then:
Int mystrcmp (const PSTR, const PSTR );
Is const PSTR actually equivalent to const char? No, it is actually equivalent to char * const.
The reason is that const gives the entire pointer itself constant, that is, the constant pointer char * const is formed.
Simply put, remember that when const and typedef appear together, typedef won't simply replace strings.
Trap 2:
Typedef syntax is a storage class keyword (such as auto, extern, mutable, static, register, etc.), although it does not really affect the storage features of objects, such:
Typedef static int INT2; // not feasible
Compilation will fail, and the system will prompt "more than one storage class is specified ".
Third, the difference between typedef and # define
Case 1:
Generally, typedef is better than # define, especially when there is a pointer. See the example below:
Typedef char * pStr1;
# Define pStr2 char *;
PStr1 s1, s2;
PStr2 s3, s4;
In the preceding variable definition, s1, s2, and s3 are both defined as char *, while s4 is defined as char, which is not the expected pointer variable, the root cause is that # define is a simple string replacement, while typedef is a new name for a type.
Case 2:
In the following code, the compiler reports 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 ++;
P2 ++ error. Another reminder is that typedef is different from # define, which is not a simple text replacement. In the above Code, const pStr p2 is not equal to const char * p2. There is no difference between const pStr p2 and const long x in nature. They both impose read-only restrictions on variables, except that the data type of the variable p2 is defined by ourselves rather than the inherent type of the system. Therefore, const pStr p2 indicates that the variable p2 with the Data Type limited to char * is read-only, so p2 ++ is incorrect.
Part 4: Use typedef to suppress inferior code
Abstract: Typedef statements help you create platform-independent types and even hide complex and incomprehensible syntaxes. In any case, the use of typedef can bring unexpected benefits to the code. Through this article, you can learn to use typedef to avoid missing, so that the code is more robust.
Typedef declaration, or typedef for short, creates a new name for an existing type. For example, typedef is often used to write more beautiful and readable code. The so-called beauty means that typedef can hide clumsy Syntax structures and platform-related data types to enhance portability and future maintainability. This article will do its best to reveal the powerful features of typedef and how to avoid some common traps.
Q: How to Create platform-independent data types and hide clumsy and incomprehensible syntaxes?
A: Use typedefs to create A synonym for an existing type.
Define a type name that is easy to remember
Typedef is used most often to create a type name that is easy to remember and use it to archive the programmer's intent. Type appears in the declared variable name, which is on the right of the ''typedef ''keyword. For example:
Typedef int size; this statement defines an int synonym and its name is size. Note that typedef does not create a new type. It only adds a synonym for an existing type. You can use size in any context that requires an int:
Void measure (size * psz); size array [4]; size len = file. getlength (); std: vector <size> vs; typedef can also conceal conforming types, such as pointers and arrays. For example, you do not need to repeatedly define an array with 81 characters as follows:
Char line [81]; char text [81]; defines a typedef, which can be used whenever an array of the same type and size is used:
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 'const char * 'parameters. Therefore, it may mislead people to declare mystrcmp () as follows ():
Int mystrcmp (const pstr, const pstr); this is incorrect. In order, 'const pstr' is interpreted as 'Char * const' (a constant pointer to char ), instead of 'const char * '(pointer to constant char ). This is a problem Easy to solve:
Typedef const char * cpstr; int mystrcmp (cpstr, cpstr); // remember right now: Whenever you declare typedef for the pointer, add a const to the final typedef name so that the pointer itself is a constant rather than an object.
Simplified code
The typedef behavior discussed above is a bit like the # define macro, which replaces the synonym with its actual type. The difference is that typedef is interpreted during compilation, so let the compiler handle text replacement beyond the pre-processor capability. For example:
Typedef int (* PF) (const char *, const char *); this declaration introduces the PF type as the synonym of the function pointer, this function has two parameters of the const char * type and a return value of the int type. If you want to use the following form of function declaration, the above typedef is indispensable:
PF Register (PF pf); the Register () parameter 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. The following shows how to implement the declaration without typedef:
Int (* Register (int (* pf) (const char *, const char *) (const char *, const char *); few programmers understand what it means, not to mention the risk of errors caused by this obscure code. Obviously, using typedef is not a kind of privilege, but a necessity. Skeptical people may ask, "OK, will someone write such code ?", Quickly browse the header file <csinal> that reveals the signal () function, a function with the same interface.
Typedef and storage class specifier)
This is not surprising. typedef is like auto, extern, mutable, static. Like register, it is a storage keyword. This means that typedef will really affect the Storage Feature of objects. It only means that in the statement structure, the typedef declaration looks like a variable declaration of static, extern, and other types. The following is a second trap:
Typedef register int FAST_COUNTER; // The Error Code cannot be translated. The problem is that you cannot have multiple storage-class keywords in the Declaration. Because the symbol typedef occupies the storage class keyword, register (or any other storage class keyword) cannot be used in the typedef declaration ).
Promote cross-platform development
Another important purpose of typedef is to define machine-independent types. For example, you can define a floating point type called REAL. On the target machine, it can obtain 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 is not even supported by double, the typedef looks like this :,
Typedef float REAL; you can compile this REAL-type application on each platform without making any changes to the source code. The only change is typedef itself. In most cases, even this tiny change can be automatically implemented through fantastic Conditional compilation. Isn't it? The standard library uses typedef to create such platform-independent types: size_t, ptrdiff, and fpos_t. In addition, typedef such as std: string and std: ofstream also hides long, incomprehensible template-specific syntax, such as: basic_string <char, char_traits <char>, allocator <char> and basic_ofstream <char, char_traits <char>.

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.