1) #define是预处理指令, in the compilation preprocessing simple substitution, does not make the correctness check, does not have the meaning whether correctly still brings in, only when compiles the already expanded source program only then discovers the possible error and error. For example:
#define PI 3.1415926
In the program: Area=pi*r*r will be replaced with 3.1415926*r*r
If you write the number 9 in the # define statement as the letter G preprocessing is also brought in.
2) A typedef is processed at compile time. It gives an alias to an already existing type within its scope, but you cannot use the typedef specifier inside a function definition.
3) typedef int * INT_PTR;
And
#define INT_PTR int *
The function is to use INT_PTR to represent the int *, but the two are different, as mentioned earlier, a simple substitution #define在预处理, whereas a typedef is not a simple substitution, but rather a type declared as a method of defining a variable. That is
Refer to (Xzgyb (Damour))
#define INT_PTR int *
INT_PTR A, B; equivalent to int * A, B; Just a simple macro replacement
typedef int* INT_PTR;
INT_PTR A, B; A, B is a pointer to int, and TypeDef introduces a new mnemonic for int*.
This also explains why the following ideas are set up
Qunkangli (Maintenance cost proportional to the square of Programmer's creativity)
typedef int * PINT;
#define PiNT int *
So:
Const pint p;//p cannot be changed, but P points can be changed
The const PINT p;//p can be changed, but the content that P points to cannot be changed.
Pint is a pointer-type const pint p is a pointer to the lock p cannot be changed
The const PINT p is a const int * p Lock that is the object referred to by the pointer p.
3) Perhaps you have noticed that # define is not a statement do not add a semicolon at the end of the line, or a semicolon is replaced.
--------------------------------------------------------------------------------------------------
Usage and differentiation of 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 those "seemingly benign, behind a long string" of macros, which are not
The translation process, but before this (the pre-processing process) has been completed, but it is also difficult to identify potential errors and other code maintenance problems, 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's easy to figure out which one is better with TypeDef, like # define
int int Such a statement, with a typedef can be done, with which good? I contend with TypeDef, because this statement is illegal in many of the earlier C compilers, but today's
The compiler also expands. 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 TypeDef is often used to define keywords, redundant
The alias of the long type.
A macro definition is simply a string substitution (in-place extension), and a typedef is not an in-place extension, its new name has a certain encapsulation, so that the new named identifier has a more easily defined change
The function of the volume. Take a look at the third line of the first big point of the code above:
typedef (INT*) PINT;
and the following line:
#define PINT2 int*
Same effect? It's 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;
Indicates that an integer pointer variable A and integer variable B are defined.
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);
is const PSTR 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".
C + + typedef and define