Let's look at a few examples
(1) struct{int x; int y;} Test1;
Well, define the structure test1,
test1.x and test1.y can be used in the statement.
(2) struct test {int x; int y;} Test1;
Well, define the structure test1,
test1.x and test1.y can be used in the statement. Compared
with 1, the province wrote Test
(3)
typedef struct TEST
{int x; int y;
} TEXT1,TEXT2;
Only said that the structure of the (type) name Text1 or called Text2
really want to use it, but also write:
Text1 test1;
Then use test1.x test1.y
or write Text2 test1;
Then use test1.x test1.y
(4) type struct {int x; int y;} Test1;
This is not possible.
change typedef ... You can do it.
but also the same as (3), but also to write:
test1 my_st;
To use My_st.x and My_st.y.
Specific detailed differences between typedef and define
I. Usage of typedef
A typedef is commonly used to define an identifier and an alias for a keyword in the C + + language, which is part of the language compilation process, but it does not actually allocate memory space, such as:
typedef int INT;
typedef int ARRAY[10];
typedef (INT*) PINT;
typedef can enhance the readability of the program, as well as the flexibility of identifiers, but it also has a "non-intuitive" and other shortcomings.
Second, #define的用法
#define为一宏定义语句, it is commonly used to define constants (including parametric and parametric), and to implement macros that are "seemingly benign, behind a long string", which is not itself in the process of compiling, but before (the pre-processing process) is completed. However, it is also difficult to identify potential errors and other code maintenance problems, and its examples are as follows:
#define INT int
#define TRUE 1
#define ADD (b) ((a) + (b));
#define LOOP_10 for (int i=0; i<10; i++)
In article 1 of effective C + + of Scott Meyer, there is an analysis of the drawbacks of the # define statement, as well as a good alternative, as you can see.
Three, the difference between typedef and # define
From the above concept can also be basically clear, TypeDef is only to increase readability and the identifier for the new name (just an alias), and # define was originally in C in order to define constants
, the advent of C++,const, enum, and inline made it a tool for aliases. Sometimes it is easy to figure out which one is better with typedef, such as # define int int, which can be done with a TypeDef, which is good. I contend with TypeDef, because this statement is illegal in many of the earlier C compilers, but today's compilers are expanded. To be as compatible as possible, it is common to follow a # define definition of "readable" constants and the tasks of some macro statements, whereas a typedef is often used to define keywords, lengthy types of aliases.
A macro definition is simply a string substitution (in-place extension), whereas a typedef is not an in-place extension, and its new name has a certain encapsulation so that the newly named identifier has the ability to define variables more easily. For example
typedef (INT*) PINT;
and the following line:
#define PINT2 int*
The effect is the same. actually different. See the difference in practice: PINT A, B, the effect with int *a; An int *b that defines two integer pointer variables. And pINT2 A, B; the effect is the same as int *a, b. The expression defines an integer pointer variable A and integer variable B.
typedef int * PINT;
#define PINT int *
then:
the const PINT p;//p cannot be changed, but the contents of P point can change the
const PINT p;//p can be changed, but the contents of P point cannot be changed.
Pint is a pointer-type const pint P is to lock the pointer to P cannot be changed
and the const pint p is a const int * p Lock is the object that the pointer p refers to.
Four. Four uses of typedef and two traps
Use one:
Defines an alias for a type, 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; The majority does not conform to our intent, it only declares a pointer to a character variable,
and a character variable;
The following are possible:
typedef char* PCHAR; General capitalization
PCHAR PA, PB; It is possible to declare two pointers to a character variable
Although:
Char *pa, *PB;
Also feasible, but relatively not in the form of TypeDef intuitive, especially in the need of a large number of pointers, the way typedef is more convenient.
Use two:
Used in the old C code (specific How old is not checked), to help the struct. In the previous code, when declaring a struct new object, you had to bring a struct with the form: struct struct name Object name, such as:
struct TAGPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;
In C + +, you can write directly: the name of the struct name object, which is:
TagPOINT1 P1;
It is too much trouble to think that someone often writes a struct, so they invent:
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 large use of time
Perhaps, in C + +, this use of TypeDef is not very large, but understanding of it, to master the old code is still helpful, after all, we may encounter in the project earlier legacy code.
Use three:
Use typedef to define platform-independent types.
For example, to define a floating-point type called REAL, on the target platform one, let it represent the highest precision type:
typedef long double REAL;
On platform two that does not support long double, replace the following:
typedef double REAL;
On three platforms that are not supported by double, replace the following:
typedef float REAL;
That is, when cross-platform, just change the typedef itself, do not make any changes to other source code.
This technique is widely used by the standard library, such as size_t.
In addition, because typedef defines a new alias for a type, it is not a simple string substitution, so it is more robust than a macro (although using macros can sometimes accomplish the above purposes).
Use four:
Define a new, simple alias for a complex claim. The method is: in the original declaration gradually replaced with the alias part of a complex declaration, so loop, the part with the variable name to the last substitution, get the original declaration of the most simplified version. Example:
1. Original declaration: Int * (*A[5]) (int, char*);
The variable name is a, and replacing a with a new alias Pfun is possible:
typedef int * (*PFUN) (int, char*);
The most streamlined version of the original statement:
Pfun A[5];
2. Original declaration: void (*b[10]) (void (*) ());
The variable name is B, replace the right part in parentheses, and Pfunparam as alias one:
typedef void (*pfunparam) ();
Replace the left variable B,pfunx with the alias two:
typedef void (*PFUNX) (Pfunparam);
The most streamlined version of the original statement:
Pfunx B[10];
3. Original declaration: Doube (*) () (*e) [9];
Variable named E, replace the left part first, Pfuny as alias one:
typedef double (*pfuny) ();
Replace the right variable E,pfunparamy with the alias two
typedef PFUNY (*pfunparamy) [9];
The most streamlined version of the original statement:
Pfunparamy e;
Understand the "right-left" rule that is available for complex declarations: from the variable name, to the right, then to the left, the direction of the reading is reversed when the parentheses are analyzed, the parentheses are popped out of the brackets, or the left-to-right sequence is followed, until the entire declaration is parsed. Example:
Int (*func) (int *p);
First find the variable name func, there is a pair of parentheses outside, and the left is a * number, which means that func is a pointer, then jump out of this parenthesis, first look to the right, and also encounter parentheses, which means (*func) is a function, so func is a pointer to such a function, that is, a function pointer, Such functions have a formal parameter of type int*, and the return value type is int.
Int (*func[5]) (int *);
The right side of the Func is a [] operator, stating that Func is an array with 5 elements, and the left side of the Func has a *, stating that the element of Func is a pointer (note that this is not the modifier func, but the func[5], because [] operator precedence is higher than *, and Func is preceded by [] Combined). Jumping out of this parenthesis, looking to the right, and encountering parentheses, the element of the Func array is a pointer to the function type, which points to a function that has a int* type parameter and a return value of type int.
You can also remember 2 modes:
Type (*) (...) function pointers
Type (*) [] array pointer
---------------------------------
Trap One:
Remember, TypeDef is a new alias that defines a type, unlike macro, which is not a simple string substitution. Like what:
Define first:
typedef char* PSTR;
And then:
int mystrcmp (const PSTR, const PSTR);
The const PSTR is actually equivalent to a const char*. No, it's actually equivalent to char* Const.
The reason is that const gives the entire pointer itself to be constant, that is, to form a constant pointer char* const.
Simply put, remember that when the const and typedef appear together, the typedef will not be a simple string substitution.
Trap Two:
A typedef is syntactically a keyword that stores a class (such as auto, extern, mutable, static, register, and so on), although it does not really affect the storage characteristics of an object, such as:
typedef static INT INT2; Not feasible
The compilation will fail with the hint "more than one storage class has been specified".
A const basis
If the const keyword does not involve pointers, we understand very well that the following is a case involving pointers:
int b = 500; Const int* A = &b; [1] int const *A = &b; [2] int* const A = &b; [3] Const int* CONST A = &b; [4]
If you can distinguish between the above four situations, then, congratulations, you have taken a welcome step. I don't know, it doesn't matter, we can refer to the practice on effective C + + ITEM21, if the const is on the left side of the asterisk, the const is used to decorate the variable pointed to by the pointer, that is, the pointer is constant, if the const is on the right side of the asterisk, A const is a modifier of the pointer itself, i.e. the pointer itself is a constant. Thus, [1] and [2] are the same, all pointers to the content is constant (const placed in the position of the variable declarator independent), in this case, the content is not allowed to change operations, such as *a = 3; [3] for the pointer itself is a constant, and the pointer to the content is not a constant, In this case, you cannot make a change to the pointer itself, such as a++ is wrong; [4] is a constant for both the pointer itself and the pointed content.
Another powerful feature of the const is its application in function declarations. In a function declaration, a const can modify the return value of a function, or a parameter, and for a member function, it can be decorated as an entire function. There are a few situations where the following is a gradual explanation of usage:
a& operator= (const a& A); void Fun0 (const A * A); void fun1 () const; FUN1 () is a class member function Const A FUN2 ();
two initialization of the const
Let's take a look at the const variable initialization.
1) Non-pointer const constant initialization:
A b; Const A = b;
2) The pointer (reference) const constant Initializes the case:
A * d = new A (); CONST * C = D; OR: const A * c = new A (); Reference: A F; Const a& e = f; To do so, E can only access functions declared as const, and cannot access the general member functions;
[Think 1]: Is this the correct way to assign the following values?
Const * C=new A ();
A * e = C;
[Think 2]: Is this the correct way to assign the following values?
A * Const C = new A ();
A * b = c;
Three const modifiers for parameters and return values
In fact, whether it is a parameter or return value, the reason is the same, when the parameter is passed in and when the function returns, the initialization of the const variable
1 const of the modified parameter, such as void fun0 (const * A); void fun1 (const a& A);
When the function is called, the const constant is initialized with the corresponding variable, and in the function body, the part that is modified by the const is often quantified, such as the parameter is a const * A, the contents of the pointer passed in can not be changed, and the content pointed to by the original pointer is protected, if the parameter is const A & A, you cannot change the referenced object that is passed in, protecting the properties of the original object.
[Note]: The parameter const is usually used in cases where the parameter is a pointer or reference;
2 modifier Returns the const of the value, such as const A fun2 (); Const * FUN3 ();
Once the return value is declared, the const is decorated in accordance with the "cosmetic principle" and acts as a protective function.
Const Rational operator* (const rational& LHS, const rational& RHS) {return rational (lhs.numerator () * Rhs.numerat or (), Lhs.denominator () * Rhs.denominator ()); }
The return value is modified with a const modifier to prevent such an operation from being allowed to occur:
Rational A, B; Radional C; (a*b) = C;
It is common to use the const-decorated return value as the object itself (non-reference and pointer) when it is used to overload functions of the two-mesh operator and to produce new objects.
[Summary] In general, when the return value of a function is an object, if it is declared as const, it is used more than an overload of the operator. In general, it is not recommended to use the const-modifier function's return value type as an object or as a reference to an object.
The reasons are as follows:
If the return value is const for an object (const A test = A instance) or a reference to an object is const (const a& test = A instance), the return value has a const property, The return instance can only access the public (protected) data members and the const member functions in Class A, and it is not allowed to be assigned operations, which is rarely used in general cases.
[Think 3] : Can you define an assignment operator overload function like this?
Const a& operator= (const a& A);
Use of const in four class member functions
Generally placed in the function body, such as: void Fun () const;
If a member function does not modify a data member, it is best to declare it as const, because the const member function does not allow modifications to the data member, and if modified, the compiler will give an error, which greatly improves the robustness of the program.
v. Some suggestions for using the const
1 The bold use of const, which will bring you endless benefits, but only if you have to understand the cause;
2 to avoid the most general assignment error, such as the const variable assignment, the concrete visible study questions;
3 using const in parameters should use a reference or pointer instead of a generic object instance for the same reason;
4 const in the member function of the three kinds of usage (parameters, return values, functions) to be very good use;
5 do not easily set the return value type of the function as const;
6 In addition to overloading operators generally do not set the return value type as a const reference to an object;
Chapter One: the difference between typedef struct and struct
1. Basic explanations
A typedef is a C-language keyword that defines a new name for a data type. The data types here include the internal data type (INT,CHAR, etc.) and the custom data type (struct, etc.).
The purpose of using TypeDef in programming is generally two, one is to give the variable a new name that is easy to remember and meaning, and the other is to simplify some more complex type declarations.
As to what is so subtle about typedef, you should continue to look at the specific aspects of the problem.
2. typedef & Structure Issues
When defining a structure with the following code, the compiler reported an error. is the C language not allowed to include pointers to its own in the structure? Please guess first, then read the following explanation:
typedef struct TAGNODE
{
Char *pitem;
Pnode Pnext;
} *pnode;
Answers and Analysis:
1, the most simple use of typedef
typedef long BYTE_4;
Give the known data type long a new name, called Byte_4.
2, typedef and structure in combination with the use
typedef struct TAGMYSTRUCT
{
int iNum;
Long llength;
} mystruct;
This statement actually accomplishes two things:
1) Define a new type of structure
struct TAGMYSTRUCT
{
int iNum;
Long llength;
};
Analysis: Tagmystruct called "tag", or "tag", is actually a temporary name, the struct keyword and tagmystruct together, constitute this structure type, regardless of whether there is a TypeDef, this structure exists.
We can use struct tagmystruct varname to define variables, but it is important to note that it is wrong to use tagmystruct varname to define variables, because structs and tagmystruct together can represent a struct type.
2) typedef has a name for this 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 is of course allowed to include pointers to its own structure, and we can see countless examples of the implementation of data structures such as linked lists, and the fundamental problem with this code is the application of typedef.
According to our above description can know: The process of building a new structure encountered 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 established, the type of the new name also does not exist, That means the compiler doesn't know Pnode at all.
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 is not yet fully declared. The C language compiler supports this practice.
3), Standard practice:
typedef uint32 (* adm_readdata_pfunc) (uint16*, UInt32);
This has not been seen before, the personal think is Yu define a uint32 pointer function, uint16*, uint32 as a function of two parameters; should be equivalent to # define UINT32 (* adm_readdata_pfunc) (uint16*, UInt32);
Structs are common in two forms of code:
struct A
{
//...
};
struct
{
//...
A
This is actually two completely different uses:
The former is called "struct type definition", meaning: the structure in the definition {} is a struct with a name of "a".
This usage is typically in a typedef:
typedef struct TAGA//deliberately give a different name, as the real names of the struct body
{
//...
A The alias of the struct.
The latter is a struct variable definition, meaning: A variable named "a" is defined with the structure in {}. The struct here is called an anonymous struct and cannot be directly referenced.
You can also create an alias for an anonymous struct through a typedef so that it can be referenced:
typedef struct
{
//...
A Defines an anonymous struct with an alias of a
Chapter Two: differences between struct and typedef structs in C and C + +
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 error
struct {
int data;
int text;
} S3;
This method does not define a structure, but rather defines a s3 structure variable, and the compiler will be 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 to define the variable that defines the structure itself in the structure.
struct S6 {
s6* ptr;
};
This notation 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 salvation" method
typedef struct tags8{
TagS8 * PTR;
} S8;
Article III: struct and typedef structs
Three blocks to tell:
1 First:
Define a struct type in C to use typedef:
typedef struct STUDENT
{
int A;
} Stu; The
then declares the variable when it can: Stu stu1;
If you do not have a TypeDef, you must use struct Student stu1 to declare
Stu is actually the alias of the struct Student.
In addition here can also not write Student (so also can't struct Student stu1;)
typedef struct
{
int A;
}stu;
But in C + + It's simple, directly
struct Student
{
int A;
};
Therefore, the structure type student is defined, and the variables are declared directly student stu2.
===========================================
2 Second:
If you use typedef in C + +, it will make a difference:
struct Student
{
int A;
}STU1;//STU1 is a variable
typedef struct STUDENT2
{
int A;
}STU2;//STU2 is a struct type
Direct access to stu1.a when used
But the STU2 must first STU2 S2;
Then s2.a=10;
===========================================
3 Master the above two, but in the end we'll talk about 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 this?
I personally observe the understanding of the compiler (VC6), which is equivalent to
typedef struct
{
int num;
int age;
}AAA;
typedef AAA BBB;
typedef AAA CCC;
That is to say, AAA,BBB,CCC are all structural types. Any one can be used to declare a variable, as is the case in C + +. But what you should note is that in C + + if the typedef keyword is written out, then AAA,BBB,CCC will be a distinct three object.
Fourth: The use of typedef structs and structs in C + +
struct _X1 {...} X1; and typedef struct _x2{...} x2; What's the difference.
In fact, the former is an object instance x1 that defines classes _x1 and _x1, which is the class name _x2 that defines classes _x2 and x2,
So they are used in the process of taking something else. See Example 1.
[Knowledge Point]
Structs are also a type of data that can be used with structural variables, so, like other types of variables, they are defined first when using structural variables.
The general format for defining structure variables is:
struct structure name
{
Type variable name;
Type variable name;
...
} structure variables; Variables of the structure body
The struct name is the identifier of the struct, not the variable name.
Another common format is:
typedef struct struct Name
{
Type variable name;
Type variable name;
...
} structure alias; struct alias: Just the identifier of the struct-struct type
Also note: In C, a struct cannot contain a function. In C + +, structs are extended and can contain functions.