Are typedef and #define the same in c?

2019-01-01 04:56发布

问题:

I wonder if typedef and #define are the same in c?

回答1:

No.

#define is a preprocessor token: the compiler itself will never see it.
typedef is a compiler token: the preprocessor does not care about it.

You can use one or the other to achieve the same effect, but it\'s better to use the proper one for your needs

#define MY_TYPE int
typedef int My_Type;

When things get \"hairy\", using the proper tool makes it right

#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);

void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */


回答2:

typedef obeys scoping rules just like variables, whereas define stays valid until the end of the file (or until a matching undef).

Also, some things can be done with typedef that cannot be done with define.

Examples:

typedef int* int_p1;
int_p1 a, b, c;  // a, b, and c are all int pointers.

#define int_p2 int*
int_p2 a, b, c;  // only the first is a pointer!

.

typedef int a10[10];
a10 a, b, c; // create three 10-int arrays

.

typedef int (*func_p) (int);
func_p fp // func_p is a pointer to a function that
          // takes an int and returns an int


回答3:

No, they are not the same. For example:

#define INTPTR int*
...
INTPTR a, b;

After preprocessing, that line expands to

int* a, b;

Hopefully you see the problem; only a will have the type int *; b will be declared a plain int (because the * is associated with the declarator, not the type specifier).

Contrast that with

typedef int *INTPTR;
...
INTPTR a, b;

In this case, both a and b will have type int *.

There are whole classes of typedefs that cannot be emulated with a preprocessor macro, such as pointers to functions or arrays:

typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20]; 
...
CALLBACK aCallbackFunc;        // aCallbackFunc is a pointer to a function 
                               // returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
                               // returning a pointer to a 20-element array
                               // of pointers to int

Try doing that with a preprocessor macro.



回答4:

#define defines macros.
typedef defines types.

Now saying that, here are a few differences:

With #define you can define constants that can be used in compile time. The constants can be used with #ifdef to check how the code is compiled, and specialize certain code according to compile parameters.
You can also use #define to declare miniature find-and-replace Macro functions.

typedef can be used to give aliases to types (which you could probably do with #define as well), but it\'s safer because of the find-and-replace nature of #define constants.
Besides that, you can use forward declaration with typedef which allows you to declare a type that will be used, but isn\'t yet linked to the file you\'re writing in.



回答5:

Preprocessor macros (\"#define\'s\") are a lexical replacement tool a la \"search and replace\". They are entirely agnostic of the programming language and have no understanding what you\'re trying to do. You can think of them as a glorified copy/paste mechanic -- occasionally that\'s useful, but you should use it with care.

Typedefs are a C language feature that lets you create aliases for types. This is extremely useful to make complicated compound types (like structs and function pointers) readable and handlable (in C++ there are even situations where you must typedef a type).

For (3): You should always prefer language features over preprocessor macros when that\'s possible! So always use typedefs for types, and constant values for constants. That way, the compiler can actually interact with you meaningfully. Remember that the compiler is your friend, so you should tell it as much as possible. Preprocessor macros do the exact opposite by hiding your semantics from the compiler.



回答6:

They are very different, although they are often used to implement custom data types (which is what I am assuming this question is all about).

As pmg mentioned, #define is handled by the pre-processor (like a cut-and-paste operation) before the compiler sees the code, and typedef is interpreted by the compiler.

One of the main differences (at least when it comes to defining data types) is that typedef allows for more specific type checking. For example,

#define defType int
typedef int tdType

defType x;
tdType y;

Here, the compiler sees variable x as an int, but variable y as a data type called \'tdType\' that happens to be the same size as an int. If you wrote a function that took a parameter of type defType, the caller could pass a normal int and the compiler wouldn\'t know the difference. If the function instead took a parameter of type tdType, the compiler would ensure that a variable of the proper type was used during function calls.

Also, some debuggers have the ability to handle typedefs, which can be much more useful than having all custom types listed as their underlying primitive types (as it would be if #define was used instead).



回答7:

No.
typedef is a C keyword that creates an alias for a type.
#define is a pre-processor instruction, that creates a text replacement event prior to compilation. When the compiler gets to the code, the original \"#defined\" word is no longer there. #define is mostly used for macros and global constants.



回答8:

AFAIK, No.

\'typedef\' helps you setup a \"alias\" to an existing data type. For eg. typedef char chr;

#define is a preprocessor directive used to define macros or general pattern subsitutions. For eg. #define MAX 100, substitutes all occurences of MAX with 100



回答9:

As everyone said above, they aren\'t the same. Most of the answers indicate typedef to be more advantageous than #define. But let me put a plus point of #define :
when your code is extremely big, scattered across many files, it\'s better to use #define; it helps in readability - you can simply preprocess all the code to see the actual type definition of a variable at the place of its declaration itself.