1. Basic explanation
A typedef is a keyword in the C language that defines a new name for a data type. The data types here include internal data types (Int,char, etc.) and custom data types (struct, etc.).
There are two commonly used typedef in programming, one is to give variables a new name that is easy to remember and meaningful, and the other is to simplify some of the more complex type declarations.
As for the subtlety of the TypeDef, please take a look at the specific elaboration of several issues.
2. typedef & Structure Issues
When you define a struct with the following code, the compiler reports an error. is the C language not allowed to include pointers to itself in the structure? Please guess first, then read the following note:
typedef struct TAGNODE
{
Char *pitem;
Pnode Pnext;
} *pnode;
Answer and Analysis:
1, the most simple use of the typedef
typedef long BYTE_4;
Give a new name to a known data type long, called Byte_4.
2. The combination of typedef and structure use
typedef struct TAGMYSTRUCT
{
int inum;
Long llength;
} mystruct;
This statement actually accomplishes two things:
1 Define a new structure type
struct TAGMYSTRUCT
{
int inum;
Long llength;
};
Analysis: Tagmystruct called "tag", that is, "tag", is actually a temporary name, struct keyword and tagmystruct together, constitute the structure of this type, whether there is a TypeDef, this structure exists.
We can use struct tagmystruct varname to define variables, but note that it is wrong to use tagmystructvarname to define variables because struct and tagmystruct together can represent a struct type.
2 The typedef has a name for the new structure called MyStruct.
typedef struct TAGMYSTRUCT mystruct;
Therefore, MyStruct is actually equivalent to struct tagmystruct, and we can use MyStruct varname to define variables.
Answers and analysis
C language, of course, allows the structure to contain a pointer to its own, we can build a list of data structures such as the implementation of the countless examples, the fundamental problem of the above code is the application of the typedef.
As we can see from the above description: The new structure was established in the process of encountering the Pnext domain declaration, the type is pnode, to know that Pnode represents the type of the new name, then the type itself has not been completed, the type of the new name also does not exist, In other words, the compiler does not know Pnode at this time.
There are several ways to solve this problem:
1),
typedef struct TAGNODE
{
Char *pitem;
struct Tagnode *pnext;
} *pnode;
2),
typedef struct TAGNODE *pnode;
struct Tagnode
{
Char *pitem;
Pnode Pnext;
};
Note: In this example, you use a typedef to give a new name to a type that has not yet been fully declared. The C language compiler supports this practice.
3), Normative practice:
typedef uint32 (* adm_readdata_pfunc) (uint16*, UInt32);
This has not been seen before, personally think is Yu defines a uint32 pointer function, uint16*, uint32 as a function of two parameters; should be equivalent to #define UINT32 (*adm_readdata_pfunc) (uint16*, UInt32);
struct is common in code in two ways:
struct A
{
//...
};
struct
{
//...
A
This is actually two completely different uses:
The former is called "struct type definition", meaning that the structure in definition {} is a struct with a name of "a".
This usage is generally in the typedef:
typedef struct TAGA//intentionally give a different name, as the real names of the structural body
{
//...
A The alias of the struct body.
The latter is the definition of a struct variable, meaning that a variable named "a" is defined in the structure in {}. The structure here is called an anonymous structure and cannot be directly referenced.
You can also create an alias for an anonymous struct by typedef so that it can be referenced:
typedef struct
{
//...
A Define an anonymous structure with an alias of a
Second: The difference between struct and typedef in C and C + + struct
There are three ways to define structures in C and C + +.
typedef struct {
int data;
int text;
} S1;
This method can define a S1 structure in C or C + +.
struct S2 {
int data;
int text;
};
This definition can only be used in C + +, and if used in C, then the compiler will complain
struct {
int data;
int text;
} S3;
This method does not define a struct, but rather defines a s3 structure variable, and the compiler is S3 memory.
void Main ()
{
S1 mine1;//OK, S1 is a type
S2 mine2;//ok,s2 is a type
S3 mine3;//Ok,s3 is not a type
S1.data = 5;//ERRORS1 is a type
S2.data = 5;//ERRORS2 is a type
S3.data = 5;//OKS3 is a variable
}
In addition, there are several ways of writing variables that define the structure itself in the structure.
struct S6 {
s6* ptr;
};
This type of writing can only be used in C + +
typedef struct {
s7* ptr;
} S7;
This is a definition that is wrong in C and C + +.
If in C, we can use such a "curve to save the nation's Way"
typedef struct tags8{
TagS8 * PTR;
} S8;
Article III: struct and typedef struct
Divided into three pieces to tell:
1 First:
To define a struct type in C, use typedef:
typedef struct STUDENT
{
int A;
}stu;
So when you declare a variable, you can: Stu stu1;
If there is no TypeDef, you must use struct STUDENTSTU1; to declare
The Stu here is actually the alias of struct student.
In addition here also can not write student (so also cannot structstudent stu1;)
typedef struct
{
int A;
}stu;
But in C + + is very simple, direct
struct Student
{
int A;
};
Then it defines the structure body type student, declares the variable directly Studentstu2;
===========================================
2 Second:
If you use typedef in C + +, you can make a difference:
struct Student
{
int A;
}STU1;//STU1 is a variable
typedef struct STUDENT2
{
int A;
}STU2;//STU2 is a structural body type
Direct access to stu1.a when used
But STU2 must first stu2 the S2;
Then s2.a=10;
===========================================
3 Master the top two, but in the end we're going to discuss a problem that doesn't matter much.
If in the C program we write:
typedef struct
{
int num;
int age;
}AAA,BBB,CCC;
What the hell is that?
I personally observe the understanding of the compiler (VC6), which is equivalent to
typedef struct
{
int num;
int age;
}AAA;
typedef triple-A BBB;
typedef AAA CCC;
That is to say, the three aaa,bbb,ccc are structural body types. You can use any of the variables when declaring them, as well as in C + +. But what you should be aware of is that if you write down the typedef keyword in C + +, then AAA,BBB,CCC will be a completely different three object.
Fourth: The use of typedef struct and struct in C + +
struct _X1 {...} X1; and Typedefstruct _x2{...} x2; What's the difference.
In fact, the former is an object instance that defines class _x1 and _x1, and the latter is the class name _x2 that defines classes _x2 and x2,
So they're in the process of using something else. See Example 1.
[Knowledge Point]
A struct is also a data type, and you can use a struct variable, so, like other types of variables, you define the structure variables first.
The general format for defining structure variables is:
struct structure name
{
The type variable name;
The type variable name;
...
} structure variables;
The structure name is the identifier of the struct, not the variable name.
Another common format is:
typedef struct Structure Name
{
The type variable name;
The type variable name;
...
} structure alias;
Note also: In C, struct cannot contain functions. In C + +, the struct is extended to include functions.
======================================================================
Instance 1:struct.cpp
#include <iostream>
using namespace Std;
typedef struct _point{
int x;
int y;
}point; Define class, give class an alias
struct _hello{
int x,y;
} Hello; Define classes and objects at the same time
int main ()
{
Point pt1;
pt1.x = 2;
PT1.Y = 5;
cout<< "ptpt1.x=" << pt1.x << "pt.y=" <<pt1.y <<endl;
Hello pt2;
pt2.x = 8;
PT2.Y = 10;
cout<< "pt2pt2.x=" << pt2.x<< "pt2.y=" <<pt2.y <<endl;
The Hello pt2 above; this line of compilation will not pass. Why?
Because Hello is a defined object instance.
The correct procedure is as follows: with Hello.x and HELLO.Y
hello.x = 8;
HELLO.Y = 10;
cout<< "hellohello.x=" << hello.x<< "hello.y=" <
return 0;
}
Fifth article: Question and Answer
Q: What is the difference between defining a struct with struct and typedefstruct? Why there are two ways.
struct Student
{
int A;
} Stu;
typedef struct STUDENT2
{
int A;
}STU2;
A:
In fact, this thing is left over from the C language, a typedef can define a new compound type or give an alias to an existing type, in the C language, if you use
struct XXX
{
}; method, you must use the struct XXX var to declare the variable, and use the
typedef struct
{
The method can be written as xxx var;
But in C + + there is no such thing, no matter what kind of writing you can use the second way to declare variables, this should be regarded as the dross of C language.
Usage Summary
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."
The above information from: http://blog.sina.com.cn/s/blog_4826f7970100074k.html: Red dragon
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 problem 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 still 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 longdouble, the typedef will look 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>>.