Use of typedef function pointers in C

Source: Internet
Author: User

The syntax of a type definition boils down to a sentence: As long as you precede the variable definition with a TypeDef, you become a type definition. The thing that is supposed to be a variable here, it becomes the type.

int integer; Integer variable
int *pointer; Integer pointer variable
int array [5]; Integer array variable
int *p_array [5]; variable of an array of integer pointers
int (*array_pointer) [5];// variable for pointer to integer array
int function (int param);//function definition, function name can also be considered as a variable of a function
int *function (int param);//is still a function, but the return value is an integer pointer
Int (*function) (int param);//Now is the pointer to the function

to define the type, that is, the name of the type, which is the following form:
typedef int integer_t;                      //integral type
typedef int *pointer_t;    //int pointer type
typedef int ARRAY_T [5];//integer array type
typedef int *P_ array_t type of [5];   //int pointer array
typedef INT (*array_pointer_t) [5];//type of pointer to integer array
typedef int function_t (int param);    //function type
typedef int *function_t (int param);   // function type
typedef int (*function_t) (int param);//type of pointer to function
Note: The function type above may have an error in C, Because there is no function type in C, its function variables are automatically degenerate into function pointers, which seems to be possible in C + +. The main explanation here is the formal similarity.

The general form of the

typedef is:
typedef   type      definition name;
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.
In fact, when declaring a variable in the C language, there is a storage type indicator ( storage-class-specifier ), which includes the familiar extern, static, auto, register . When you do not specify a storage type indicator, the compiler automatically takes the default values according to the conventions. In addition, the location of the store type indicator is arbitrary (but before the variable name and pointer *), which means that the following lines of code are equivalent:
static const int i;
const static int i;
int const static i;
Const int static i;
According to the C language Specification, for syntax analysis, typedef and storage type indicators are equivalent ! Therefore, we replace the above used static with a typedef:
typedef const INT i;
const typedef int i;
Int const typedef i;
Const int typedef i;
The semantics of the preceding code is to define I as a type name with an equivalent type of const int. Later if we have i   a code, it is equivalent to const int A. The same is true for pointers, for example:
int const typedef *T; then code t   p. is equivalent to the int const *p.
Additionally, typedef cannot be used in conjunction with storage type indicators such as static, because each variable can have only one storage type, so the code: typedef static INT i;

There are two uses of typedef:
I. General form, define an alias of an existing type
typedef type definition name;
Second, create a new type
typedef returns a new type name for the value type (parameter list);

1) typedef int num[10];//declares an integer type

NUM n;//defines n as an integer array variable, where n[0]--n[9] is available

2) typedef char* string;//declaring STRING as character pointer type

STRING p,s[10];//p is a character pointer variable, s is an array of pointers

3) typedef int (*pointer) ();//declares POINTER as a pointer-type to a function that returns an integer value with no arguments

POINTER P1,P2;//P1,P2 is a pointer variable of type POINTER

Description

1) with typedef can declare various types of names, but not to define variables, with typedef can declare array type, string type, use more convenient.

For example: Define an array, originally used: Int a[10],b[10],c[10],d[10]; Since all are one-dimensional arrays and the same size, you can first declare this array type as a name:

typedef int ARR[10];

Then use ARR to define the array variables:

ARR A,b,c,d;//arr is an array type that contains 10 elements. So a,b,c,d is defined as a one-dimensional array with 10 elements. As you can see, typedef allows you to isolate array types and arrays of variables, and use array types to define multiple array variables. You can also define string types, pointer types, and so on.

2) A typedef simply adds a type name to an already existing type and does not create a new type.

3) typedef and # define have similarities, but in fact they are different, #define是在 pre-compile-time processing, it can only do simple string substitution, and typedef is processed at compile time. Instead of making a simple string substitution, it declares a type in the same way as a method that defines a variable.

For example: TypeDef int COUNT, and # define count int all use count to represent int, and the fact that they are different.

Two traps:

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".

How to use 1.typedef function pointers

(1) typedef is first used to define a new type, i.e typedef struct {...} MyStruct; When referenced later, you can use MyStruct to define your own structure, mystruct structname1,mystruct structname2.

(2) The common place of TypeDef, in defining function pointers, behaves like macro definitions, replaces synonyms with actual types, but differs: typedef is interpreted at compile time , so the compiler is able to cope with text substitution beyond the preprocessor's capabilities .

Case One:
in general, typedef are better than # define, especially where pointers are available. Take a look at the example:
typedef char *PSTR1;
#define PSTR2 char *;
pStr1 s1, S2;
PSTR2 S3, S4;
In the variable definition above, S1, S2, S3 are defined as char *, and S4 is defined as char, not the pointer variable we expect, the root cause is that # define is simply a string substitution and a typedef is a new name for a type.
Case Two:
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 *P1 = string;
Const PSTR P2 = string;
p1++;
p2++;
It was p2++ that made a mistake. This question reminds us again: TypeDef and # define are different, it is not a simple text substitution. The const PSTR P2 in the above code is not equal to the const char * p2. Const PSTR P2 and const long x are essentially no different, they are read-only restrictions on variables, except that the data type of the variable p2 is defined by ourselves rather than by the intrinsic type of the system. Therefore, the meaning of const PSTR P2 is that the variable P2 with the qualification data type char * is read-only and therefore p2++ error.

Usage One:

typedef return TYPE (* new type) (parameter table)

typedef INT (* MYFUNCTION) ( int,int ); This usage is typically defined in the function pointer MYFUNCTION is a function pointer type with two integer parameters, returning an integral type.

In the case of such a form, removing the TypeDef and aliases leaves the type of the original variable, such as int (*) (int, int); In the function pointer, the abstract look at the function, the function name is actually an address, the function name points to the function of the Code at the first address of the memory.

Usage Two: complex function declaration types

the following is a declaration of three variables using typedef how to do???

>1 int * (*a[5]) (void *,void *);

>2 void (*b[5]) (void (*) ());

>3 Float (*) () (*PA) [10];

The analysis is as follows:

>1 int * (*a[5]) (void *,void *);

Pfun is the type alias typedef int * (* pfun) created by itself (void *,void *); equivalent to int * (*a[5]) (void *,void *);

Pfun A[5]; A is an array that contains five elements, all of which are function pointers, and the function pointer refers to a function whose return value is an int with a pointer input parameter of two that are void *.

>2 void (*b[5]) ( Void (*) () );

First for the blue Declaration a new type typedef void (*pfunparam) ();

The whole declares a new type typedef void (*pfun) (Funparam);

//Using a new type of defined Declaration object is equivalent to Void (*b[5]) (void (*) ());

Pfun B[5]; b is an array of 5 elements, each of which is a function pointer, and the return value of the function pointer is void. The input parameter is another function pointer, and the function pointer has no parameters and the return value is null. A continuous function pointer is applied here. is itself a function pointer, and the parameter is a function pointer.

>3 Float (*) ()(*PA) [ten];

First declares a new type typedef float (*pfun) () for the above blue expression;

The whole declares a new type typedef pfun (* pfunparam) [10];

Use the new defined type to declare the object equivalent to float (*) () (*PA) [10];

The PA is a pointer to an array of 10 elements, the element of the array is a function pointer, and the function pointer refers to a function that has no input parameters and a return value of float.

**********************************************

use typedef to simplify complex variable declarations
1), define an array with 10 pointers pointing to a function that has an shaping parameter, and return an integral type?
First method: Int (*a[10]) (int);
The second method: TypeDef int (*PFUNC) (int);
             Pfunc a[10];
2), defines an array of 10 pointers that point to a function that has a function pointer (without parameters, a null return value), and returns NULL.
First method: void (*a[10]) (void (*) (void));
The second method: typedef void (*pfuncparam) (void);
               typedef void (*PFUNC) ( Pfuncparam);
Pfunc a[10];
3), a pointer to an array of 10 function pointers (with no arguments, with a double return value)
The first method: Double (*) (void) (*P) [x];
The second method: TypeDef double (*PFUNC) (void);
             typedef pfunc (*pfuncparam) [10];
             Pfuncparam p;

From the variable name, first to the right, then to the left, encountered a round bracket to reverse the direction of reading, after the analysis in parentheses out of parentheses, or the first right after the left order, so loop, until the entire declaration analysis is complete. 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 indicates that func is a pointer; then jump out of the parenthesis, look to the right, and then encounter parentheses, which means (*func) is a function,

So func is a pointer to such a function, the function pointer, which has a int* type of formal parameter, and the return value type is int.
Int (*func[5]) (int *);
The right side of the Func is a [] operator, which indicates 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 modifier func[5],

The reason is that [] operator precedence is higher than *, and Func is preceded by []. Jumping out of this parenthesis, looking to the right, and then encountering parentheses, stating that the element of the Func array is a pointer to the function type, and that the function it points to has a int* type of formal parameter.

The return value type is int.
You can also remember 2 modes:
Type (*) (...) function pointers
Type (*) [] array pointer

**********************************************

Finally

The most common use of TypeDef is to create easy-to-remember type names, which are used to archive programmers ' intentions. The type is in the name of the variable being declared and is located to the right of the ' typedef ' keyword. For example:
typedef int size; This declaration defines a synonym for int, named size. Note typedef does not create a new type. It simply adds a synonym to the 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 mask conforming types, such as pointers and arrays. For example, you do not have to define an array of 81-character elements as follows:
Char Line[81];char text[81]; Defines a typedef that can be used whenever you want to use an array of the same type and size:
typedef char LINE[81]; Line text, secondline;getline (text); Again, 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 * ' type parameters. 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) instead of ' const char * ' (pointer to a constant char). This question iseasy 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 a #define macro, substituting its actual type for synonymous words. The difference is that the TypeDef is interpreted at compile time, so the compiler is able to cope with the text substitution beyond the preprocessor's capabilities. For example:
typedef int (*PF) (const char *, const char *); This declaration introduces the PF type as a synonym for the function pointer, which has two const char * type parameters and a return value of type int. This typedef is essential if you want to use the following form of function declaration:
PF Register (pf pf); The parameter of register () is a PF-type callback function that returns the address of a function whose signature is the same as the name previously registered. Take a deep breath. Let me show you how we can implement this statement without a 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 error caused by this convoluted code. Obviously, using a typedef here is not a privilege, but a necessity. Skeptics may ask, "OK, does anyone else write such a code?" , a quick look at the header file that reveals the signal () function <csinal&gt, a function with the same interface.
typedef and Storage class keywords (storage class specifier)
This is not a bit surprising, typedef like auto,extern,mutable,static, and register, is a storage class keyword. This is to say that the typedef really affects the storage characteristics of the object; it simply says that in the statement composition, the typedef declares a variable declaration that looks like a static,extern type. The following will take you to a second trap:
typedef register INT Fast_counter; Error compiling pass. The problem is that you cannot have more than one storage class keyword in a 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.
Promote cross-platform development
typedef has another important purpose, 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 get the highest precision:
typedef long double REAL; On a machine that does not support a long double, the typedef looks like this:
typedef double REAL; And, on a machine that is not even supported by a double, the typedef looks like this:
typedef float REAL; You can compile this application using the REAL type on each platform without making any changes to the source code. The only thing to change is the typedef itself. In most cases, even this tiny change can be done automatically with 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, typedef like std::string and Std::ofstream also hide long, incomprehensible template-specific grammars, such as: Basic_string<char, Char_traits<char> Allocator<char>> and Basic_ofstream<char, char_traits<char>>.

Use of typedef function pointers in C

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.