Pre-processing commands and naming existing types with typedef, pre-processing typedef

Source: Internet
Author: User

Pre-processing commands and naming existing types with typedef, pre-processing typedef

Preprocessing command

It is mainly to improve the programming environment to improve programming efficiency. It is not part of the C language itself and cannot be compiled directly. It must be completed before compiling the program, perform "preprocessing" on these special commands in the program first ". For example, header files.

There are three types: macro definition, file inclusion, and Conditional compilation.

Macro definition (two types are available: with and without parameters)

The macro definition replaces a string with the macro name, which is also a simple replacement and does not check the correctness.

The macro definition is not a C statement and does not have to add points in the row;

# The define command appears outside the function in the program. The limited scope of the macro name is to define the command and end with the source file.

You can use the # undef command to terminate the macro-defined scope.

Do not replace the characters in the string enclosed by double apostrophes in the program.

The macro definition is different from the definition variable. It is only replaced by characters and no space is allocated;

Macro definition with parameters (not only simple string replacement, but also parameter replacement)

The macro definition with parameters is different from the function definition, mainly including the following:

When calling a function, first obtain the value of the real parameter expression, and then bring it into the form parameter. Macros only replace simple characters.

Function calls are processed when the program is running, and temporary memory units are allocated for the parameters. Macro expansion is performed before compilation. During expansion, memory units are not allocated, values are not transferred, and the concept of "return value" is not involved.

You must define the type for both the real parameters and the form parameters in the function. The two parameters must be consistent. The macro does not have a type problem, and the macro name does not have a type. When a macro is defined, a string can be any type of data.

You can call a function to obtain only one returned value, but use a macro definition to obtain several results.

When macros are used for a large number of times, the source code becomes longer after macros are expanded, but function calls do not.

Macro replacement does not take up the running time, but only the Compilation Time. Function calls occupy the running time (memory allocation, field reservation, and return value)

File Inclusion

The so-called "File Inclusion" processing means that one source file can include all the content of another source file, that is, other files are included in this file. (# Include ...)

In addition to function prototype and macro definition, header files can also include struct type definition and global variable definition.

Conditional compilation

A part of the program must be compiled only when certain conditions are met, that is, the compilation conditions are specified for this part of content. This is Conditional compilation.

Conditional compilation has the following forms:

#ifdef identifier
     Network 1
#else
     Block 2
#endif
#if expression
     Network 1
#else
     Block 2
#endif
// conditional compilation
#include <stdio.h>
#define LETTER 1
void main ()
{
     char str [20] = "C Language", c;
     int i = 0;
     while ((c = str [i]! = '\ 0'))
     {
         i ++;
         #if LETTER
         if (c> = 'a' && c <= 'z')
         c = c-32;
         #else
         if (c> = 'A' && c <= 'Z')
         c = c + 32;
         #endif
         printf ("% c", c);
     }
     printf ("\ n");
  }

Use typedef to name existing types

 Trap 1:

Remember, typedef defines a new type of alias. Unlike macros, typedef is not a simple string replacement. For example:

First, define:

Typedef char * PSTR;

Then:

Int mystrcmp (const PSTR, const PSTR );

Is const PSTR actually equivalent to const char? No, it is actually equivalent to char * const.

The reason is that const gives the entire pointer itself constant, that is, the constant pointer char * const is formed.

Simply put, remember that when const and typedef appear together, typedef won't simply replace strings.

  Trap 2:

Typedef syntax is a storage class keyword (such as auto, extern, mutable, static, register, etc.), although it does not really affect the storage features of objects, such:

Typedef static int INT2; // not feasible

Compilation will fail, and the system will prompt "more than one storage class is specified ".

  1. Usage of typedef

In C/C ++, typedef is often used to define an alias for an identifier and a keyword. It is part of the language compilation process, but it does not actually allocate memory space, such:

Typedef int INT;

Typedef int ARRAY [10];

Typedef (int *) pINT;

Typedef enhances program readability and the flexibility of identifiers, but it also has disadvantages such as "non-intuitive.

  2. # define usage

# Define is a macro definition statement. It is usually used to define constants (including non-parameters and parameters), and to implement macros that are "superficial and kind, long strings behind them, it is not carried out in the compilation process, but completed before (preprocessing), but it is difficult to find potential errors and other code maintenance problems, its instance is like:

# Define INT int

# Define TRUE 1

# Define Add (a, B) (a) + (B ));

# Define Loop_10 for (int I = 0; I <10; I ++)

In clause 1 of Scott Meyer's Objective C ++, we have analyzed the disadvantages of # define statements and good alternatives. For more information, see.

  3. Differences between typedef and # define

From the above concepts, we can also understand that typedef is just a new name (only an alias) for the identifier to increase readability, and # define is originally used to define constants in C, the emergence of C ++, const, enum, and inline has gradually become an alias tool. Sometimes it is easy to figure out which one should be used for typedef and which one should be used, for example, a statement such as # define INT int, which one can be used for the same purpose? The idea is to use typedef, because in many early C compilers, this statement was invalid, but the current compiler has expanded. To be as compatible as possible, # define is generally followed to define "readable" constants and macro statement tasks, while typedef is often used to define keywords and lengthy type aliases.

Macro definition is just a simple string replacement (in-situ extension), while typedef is not in-situ extension, and its new name has a certain encapsulation, so that the new name identifier has a more convenient function to define variables. See the third line of the first code:

Typedef (int *) pINT;

And the following line:

# Define pINT2 int *

Same effect? Actually different! In practice, see the difference: pINT a, B; has the same effect as int * a; int * B; indicates that two integer pointer variables are defined. PINT2 a, B; has the same effect as int * a, B; indicates defining an integer pointer variable a and an integer variable B.

1. First, the execution time of the two is different.

The keyword typedef is valid in the compilation phase. Because it is in the compilation phase, typedef has the type check function.

Define is a macro definition, which occurs in the preprocessing phase, that is, before compilation. It only performs simple and mechanical string replacement without any check.

# Define usage example:

#define f(x) x*x  
main( )  
{  
int a=6,b=2,c;  
c=f(a) / f(b);  
printf("%d \n",c);  
} 

The output result of the program is: 36. The root cause is that # define is a simple string replacement, and should be enclosed in brackets "(X * X )".

2. Different Functions

Typedef is used to define the type alias. These types include not only internal types (int, char, etc.), but also custom types (such as struct), which can be used to make the type easy to remember.

For example:

  1. Typedef int (* PF) (const char *, const char *);

Define the Data Type PF of a pointer to a function. The return value of the function is int and the parameter is const char *.

Another important purpose of typedef is to define machine-independent types. For example, you can define a floating point type called REAL. On the target machine, it can obtain the highest precision:

  1. Typedef long double REAL;

On a machine that does not support long double, the typedef looks like the following:

  1. Typedef double REAL;

In addition, on a machine that does not support double, the typedef looks like this:

  1. Typedef float REAL;

# Define can not only take aliases for types, but also define constants, variables, and compilation switches.

3. different scopes

# Define has no scope restrictions. As long as it is a previously predefined macro, it can be used in future programs. Typedef has its own scope.

  1. void fun ()
    {
    #define A int
    }
    void gun ()
    {
    // A can also be used here, because macro replacement has no scope,
    // But if typedef is used above, then A cannot be used here, but generally typedef is not used in functions
    }
    

4. pointer operations

They have different functions when modifying the pointer type.

  1. Typedef int * pint;
    #define PINT int *
    Const pint p; // p can not be changed, the content pointed to by p can be changed, which is equivalent to int * const p;
    Const PINT p; // p can be changed, and the content pointed to by p cannot be changed, which is equivalent to const int * p; or int const * p;
    pint s1, s2; // s1 and s2 are both int pointers
    PINT s3, s4; // equivalent to int * s3, s4; only one is a pointer 

In fact, the labels at the end of typedef and define are also different. I hope you will not ignore this. Through the analysis in this article, I believe you have understood the difference between the two. After understanding the difference, it will be more flexible to use.


Related Article

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.