When I read the program these two days, I found that typedef is widely used in many places, such as structure definition and some arrays. But some places are not very clear, so I want to study them this afternoon. I searched online and found a lot of information. To sum up:
Source code 1: use typedef to suppress error codes.
Typedef declarations help create platform-independent types and even hide complex and incomprehensible syntax. In any case, using typedef can bring unexpected benefits to the code. Through this article, you can learn to use typedef to avoid defects, thus making the code more robust.
Typedef declaration, typedef for short, creates a new name for an existing type. For example, people often use typedef to write more beautiful and readable code. The so-called beauty is that typedef can hide clumsy grammar structures and platform-related data types, thus enhancing portability and future maintainability. This article will try to reveal the powerful functions of typedef and how to avoid some common pitfalls.
How to create platform-independent data types and hide clumsy and incomprehensible syntax?
Use typedefs to create synonyms for existing types.
Define an easy-to-remember type name.
Typedef is most commonly used to create easy-to-remember type names for archiving programmers' intentions. The type appears in the declared variable name to the right of the "typedef" keyword. For example:
typedef int size
This declaration defines a synonym for the size named int. Note that typedef does not create new types. It just adds a synonym to an existing type. You can use size in any context that requires int:
Null metric (size * PSZ);
Size array [4];
size len = file . getlength();
STD::vector vs;
Typedef can also mask matching types, such as pointers and arrays. For example, you don't have to define an array with 8 1 character elements repeatedly, as follows:
Char line [81];
char text[8 1];
Define a typedef. Whenever you want to use an array of the same type and size, you can do this:
Typedef character line [81];
Line text, second line;
Getline (text);
Similarly, pointer syntax can be hidden 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 of type "constchar *". Therefore, it may mislead people to declare mystrcmp () as:
int mystrcmp(const pstr,const pstr);
This is not right. In order, "constpstr" is interpreted as "char * const" (const pointer to char) instead of "const char *" (pointer to constant char). This problem is easy to solve:
typedef const char * cpstr
int mystrcmp(cpstr,cpstr); //It is correct now.
Remember: whenever you declare a typedef for a pointer, you should add a const to the last typedef name, so that the pointer itself is a constant, not an object.
Code simplification
Typedef discussed above behaves a bit like a #define macro, replacing synonyms with its actual type. The difference is that typedef is interpreted at compile time, so the compiler is allowed to deal with text substitution beyond the preprocessor's ability. For example:
typedef int (*PF) (const char *,const char *);
This declaration introduces PF type as a synonym for function pointer, which has two parameters of const char * type and a return value of int type. This typedef is necessary if you want to use the following form of function declaration:
PF register (pf pf);
The parameter of Register () is a callback function of PF type, which returns the address of the function with the same name signature as that registered before. Take a deep breath. Let me show you how we implemented this declaration without typedef:
int(* Register(int(* pf)(const char *,const char *))
(const char *,const char *);
Few programmers understand what this means, let alone the risk of errors caused by this incomprehensible code. Obviously, using typedef here is not a privilege, but a necessity. Skeptics may ask, "well, can anyone write such code?" Take a quick look at the header file that shows the signal () function, which has the same interface.
Typedef and storage class descriptors.
Isn't this a bit surprising? Typedef is a storage class keyword, similar to auto, extern, mutable, static and register. This does not mean that typedef will really affect the storage characteristics of objects; It just means that the typedef declaration looks like static, extern and other types of variable declarations in terms of sentence composition. The following will lead to the second trap:
Typedef register int FAST _ COUNTER// error.
Compilation failed. The problem is that there cannot be more than one storage class keyword in the declaration. Register (or any other storage class keyword) cannot be used in the typedef declaration, because the symbol typedef has occupied the location where the storage class keyword is stored.
Promote cross-platform development
Typedef also has an important purpose, which is to define types that have nothing to do with machines. For example, you can define a floating-point type called REAL, which can get the highest precision on the target machine:
Typedef long double real number;
On machines that do not support long double, typedef will look like this:
Typedef double real number;
In addition, on a machine that doesn't even support double, typedef will look like this:
typedef float REAL
You can compile the application with real types on any platform without making any changes to the source code. The only thing to change is typedef itself. In most cases, even this small change can be realized automatically through wonderful conditional compilation. Isn't it? Typedef is widely used by standard libraries to create such platform-independent types: size_t, ptrdiff and fpos_t are examples. In addition, typedef such as std::string and std::ofstream also hide lengthy and difficult-to-understand template specialized syntax, such as: basic_string, allocator >;; And basic _ ofstream >; .
Brief introduction of the author
Danny Kalev is an authentication system analyst and software engineer, specializing in C++ and formal language theory. From 1997 to 2000, he was a member of the C++ Standards Committee. Recently, he finished his master's thesis in general linguistics with excellent results. In his spare time, he likes listening to classical music, reading Victorian literature and learning natural languages such as Hittite, Basque and Irish Gaelic. Other interests include archaeology and geography. Danny often goes to some C++ forums and regularly writes articles for different C++ websites and magazines. He also teaches programming languages and applied languages in educational institutions.
Source 2: (/bbs/dispbbs.asp? boardid = 30 & amp; id=4455)
Usage of typedef in c language
1. Basic explanation
Typedef is a keyword in C language, which is used to define a new name of a data type. The data types here include internal data types (int, char, etc. ) and user-defined data types (struct, etc. ).
Typedef is generally used in programming for two purposes, one is to give variables a new name that is easy to remember and has a clear meaning, and the other is to simplify some complicated type declarations.
As for the subtlety of typedef, please look at the specific explanations of several problems.
2. Typedef & structural problems
The compiler reported an error when defining a structure with the following code. Why? C is not allowed to include pointers to itself in the structure? Please guess first, and then read the following instructions:
Typedef structure tag node
{
char * pItem
pNode pNext
} * pNode
Answers and analysis:
The simplest usage of 1 and typedef
Typedef long byte _ 4;
Give the known data type long a new name called byte_4.
2.typedef is combined with structure.
typedef struct tagMyStruct
{
int iNum
Long length;
} MyStruct
This statement actually completes two operations:
1) defines a new structure type.
Structural marker structure
{
int iNum
Long length;
};
Analysis: tagMyStruct is called "tag", that is, "tag", which is actually a temporary name. The struct keyword and tagMyStruct together constitute this structural type, and this structure exists with or without typedef.
We can use struct tagMyStruct varName to define variables, but it is wrong to use tagmysterious Varname to define variables, because struct and tag mystery can represent a structural type together.
2) typedef gave this new structure a name, called MyStruct.
typedef struct tagmy struct my struct;
So MyStruct is actually equivalent to struct tagMyStruct, and we can use MyStruct varName to define variables.
Answers and analysis
Of course, the C language allows structures to contain pointers to themselves. In the realization of data structures such as linked list, we can see countless such examples. The fundamental problem of the above code lies in the application of typedef.
According to what we have explained above, we can know that the declaration of the pNext field is encountered in the process of building a new structure, and the type is pNode. You should know that pNode stands for the new name of the type, so the new name of this type does not exist before the type itself is established, which means that the compiler does not know pNode at this time.
There are many ways to solve this problem:
1)、
Typedef structure tag node
{
char * pItem
struct tagNode * pNext
} * pNode
2)、
typedef struct tagNode * pNode
Structural marker node
{
char * pItem
pNode pNext
};
Note: in this example, you use typedef to give a new name to a type that is not fully declared. C language compiler supports this practice.
3), standard practice:
Structural marker node
{
char * pItem
struct tagNode * pNext
};
typedef struct tagNode * pNode
3. Typedef & # Definition problem
There are two ways to define the pStr data type. What's the difference between them? Which is better?
typedef char * pStr
# define pstrchar *;
Answers and analysis:
Generally speaking, typedef is better than #define, especially when there are pointers. Look at this example:
typedef char * pstr 1;
# define pstr2char *;
pStr 1 s 1,S2;
pStr2 s3、S4;
In the above definition of variables, s 1, s2, s3 are all defined as char *, while s4 is defined as char, which is not the expected pointer variable. The root cause is that #define is just a simple string substitution, and typedef gives a new name to the type.
Examples of usage of #define:
# Define f(x) x*x
Master ()
{
int a=6,b=2,c;
c = f(a)/f(b);
printf("%d \\n ",c);
}
The output of the following program is: 36.
For this reason, in many C language programming specifications, when using #define definition, if the definition contains expressions and brackets must be used, the above definition should be defined as follows:
# Define f(x) (x*x)
Of course, if typedef is used, there is no such problem.
4. another example of 4.typedef & amp#define
The compiler will report an error in the following code. Do you know which statement is wrong?
typedef char * pStr
char string[4]= " ABC ";
const char * p 1 = string;
const pStr p2 = string
p 1++;
p2++;
Answers and analysis:
P2++ is wrong. This question reminds us once again that typedef is different from #define, and it is not a simple text replacement. Constpsttrp2 in the above code is not equal to const char * p2. There is no difference between const pStr p2 and const long x in essence. They are all read-only restrictions on variables, but the data type of variable p2 here is defined by ourselves, not the type inherent in the system. So const pStr p2 means that the variable p2 with data type char * is limited to read-only, so p2++ is wrong.
On the extension of #define and typedef
1) #define macro definition has a special advantage: you can use #ifdef, #ifndef, etc. Make a logical judgment, or use #undef to cancel the definition.
2) typedef also has a special advantage: it conforms to the scope rule. The scope of the variable type defined by typedef is limited to the defined function or file (depending on the location of the variable definition), but the macro definition does not have this feature.
5. Typedef & complex variable declaration
In programming practice, especially when reading other people's code, we often encounter complex variable declarations. Simplification with typedef has its own value, such as:
The following are the declarations of three variables. I want to define aliases for them with typdef. What should I do?
& gt 1:int *(*a[5])(int,char *);
& gt2:void(* b[ 10])(void(*));
& gt3.doube(*)(* * pa)[9];
Answers and analysis:
The method of establishing type aliases for complex variables is very simple. You just need to replace the variable name in the traditional variable declaration expression with the type name, and then add the keyword typedef at the beginning of the statement.
& gt 1:int *(*a[5])(int,char *);
//pFun is the type alias we built.
typedef int * *(pFun)(int,char *);
//Declare an object with a defined new type, which is equivalent to int *(a[5])(int, char *);
pFun a[5];
& gt2:void(* b[ 10])(void(*));
//First declare a new type for the blue part of the above expression.
typedef void(* pfun param)();
//Declare a new type as a whole.
typedef void(* pFun)(pFun param);
//Declare an object with a defined new type, which is equivalent to void (* b [10]) (void (*));
pFun b[ 10];
& gt3.doube(*)(* * pa)[9];
//First declare a new type for the blue part of the above expression.
typedef double(* pFun)();
//Declare a new type as a whole.
typedef pFun(* pFun param)[9];
//Declare an object with a defined new type, which is equivalent to doube (*) (* pa) [9];
pFunParam pa