user-0 提问: typedef 问题的疑惑

回复:
user: user-1
content: 引用 26 楼 ituling 的回复:谢谢大家的讲解，真的都很不错，对我也很有用，真的感谢各位在学习工作之余不耐其烦为我讲的这些东西，你们的回帖我都认真的看了，收益很大。谢谢了各位。这个帖子应该可以结了，假如大家都没有什么问题了。通过这个问题，我看出了自己对C和C++知识掌握的薄弱地方，或者说理解不是很深刻，大家假如有什么好书，必读之书的话，推荐给我啊 ，谢谢 C开发者这辈子总要抽时间通读一遍MSDN中和C开发相关的所有内容哪怕象征性一遍的。 MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl

user: user-0
content: 谢谢大家的讲解，真的都很不错，对我也很有用，真的感谢各位在学习工作之余不耐其烦为我讲的这些东西，你们的回帖我都认真的看了，收益很大。谢谢了各位。这个帖子应该可以结了，假如大家都没有什么问题了。通过这个问题，我看出了自己对C和C++知识掌握的薄弱地方，或者说理解不是很深刻，大家假如有什么好书，必读之书的话，推荐给我啊 ，谢谢

user: user-0
content: 引用 20 楼 lm_whales 的回复:[quote=引用 17 楼 ituling 的回复:] [quote=引用 6 楼 lm_whales 的回复:] typedef char Line[10]; 表示 Line 是 char[10] 这个类型； 可以这么理解 先 撇开char Line[10];  Line 是个10个元素的 char 数组--->也就是char  [10] 类型的数据； typedef char Line[10] ; Line 就是10个元素的 char 数组 类型。 2. typedef int (*p)(char*,char*); int (*p)(char*,char*);  *p 是个返回值为 int,两个参数都是 char * 的函数 所以 p是个函数指针，指向的函数类型为 ：返回值为 int 类型,两个参数都是 char * 类型的函数 p 是个返回值 为int 类型,两个参数都是 char * 类型的函数指针变量； 加上 typedef 后，p从 变量定义，转换为类型定义 它的类型就是：     返回值 为int 类型 ,两个参数都是 char * 类型的函数（的）指针 类型  分析 typedef 的时候， 先撇开typedef ， 那么这就是一个数据（对象）定义（或者声明）， C++可能还包括函数定义（或者声明） 看看后面定义（或者声明）的数据（对象） 是个什么类型的数据（对象） 然后 加上 typedef  改为 定义类型 ； 上一步得到的数据（对象）的 类型，就是 typedef   定义的 类型。 引用 14 楼 chehw_1 的回复:[quote=引用 13 楼 ituling 的回复:] 说实话 pint 不会拆开为 int * 而是 作为一个int *类型 这句话不是特别特别理解 ，有些模糊  举个例子：  typedef int * PINT; PINT m, n; // 此时，m, n均为（int * ）类型。 m = n; // 可以，同为int * 类型的指针   #define PINT int *  PINT m, n; // 此时，m为（int *)类型，而n为（int)类型。因为宏展开后，该行实际为 int * m, n; m = n; // 编译器会警告类型不匹配 m = &n; // 可以 [/quote]    引用 4 楼 lm_whales 的回复:typedef int * pint; const pint x; pint 不会拆开为 int * 然后和 const 组合成 const int * 而是 作为一个int *类型 那么 const pint  就是 pint const, 也就是 int *const;  诸如此类  谢谢你们的耐心讲述，我差不多明白了typedef和#define的区别，我不理解的是下面，这个在C++primer中也讲过，不是特别理解，还能相信讲一下么 typedef int * pint; const pint x; pint 不会拆开为 int * 然后和 const 组合成 const int * 而是 作为一个int *类型 那么 const pint  就是 pint const, 也就是 int *const;  为啥 const pint 就成了 int *const; 因为pint 不会拆开为 int * 他这样确实就是一个int指针为啥被const修饰之后就成了 int *const;[/quote]  对一个类型 T const  T a; 和  T const a； 都是 定义 T 类型常量  int *const a; //a 这个int类型指针是常量；这是指针常量，指针本是是常量。 const  int *a; // *a;这个 int 类型的对象是常量。a这是常量指针。指向常量的指针                        //单独的const int * 这三个符号放在一起，编译器会根据运算符结合性，优先级，                          以及各个符号的顺序，解释定义（声明）的对象的类型 。   const pint a;     /// pint 对象a, 也就是 int 指针（int*）a， 是个常量； 这就是类型 pint 不再拆分为 int *两个符号的含义。                            /// pint 是 int 指针 （int*）最先得到解释 ，不再是 const int * 三个符号，放在一起处理后解释了。 pint  const a;    ///a 是个 int 指针（int*） 并且是指针常量，也是先解释 pint 再解释 pint const ; 这样，pint  const a;  int *const a;定义的对象，就是同一个类型的对象了。这算是巧合。  int *const a； 是四个符号（包括标识符 a）， 一起解释。 这个语句解释成定义指针常量 a; 这样 int *const 这个类型，就是指针常量类型；  [/quote]  引用 21 楼 SXJIAKE 的回复:声明语句： char IntArray[10]; int Function(char *, char *);  前面加 typedef 后定义出新类型： typedef char IntArrayType[10]; typedef int (*FunctionType)(char *, char *); 这里 IntArrayType 即代表上述声明中 IntArray 的类型，FunctionType 同理。  使用新类型来完成声明语句，与开头的声明语句作用相同： IntArrayType IntArray; FunctionType Function; 这里有个特例，函数指针类型声明要加 (*Typename) 而非直接写 Typename。  由于 C 语言书写的时候，下面三组形式的意义是一样的： FunctionType pfn = Function; FunctionType pfn = &Function; Function(str1, str2); (*Function)(str1, str2); pfn(str1, str2); (*pfn)(str1, str2);  实际上函数名也是一个指针，按下面的书写方式就不难理解了。 typedef int (*FunctionType)(char *, char *); int (*Function)(char *, char *); FunctionType pfn = Function; (*Function)(str1, str2); (*pfn)(str1, str2); 引用 22 楼 zhao4zhong1 的回复:针对 宏 可以查看其展开后的效果：VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898  typedef好象不行。  宏的本质是字符串替换 #与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC   typedef是定义一个别名 typedef typedef type-declaration synonym;  The typedef keyword defines a synonym for the specified type-declaration. The identifier in the type-declaration becomes another name for the type, instead of naming an instance of the type. You cannot use the typedef specifier inside a function definition.  A typedef declaration introduces a name that, within its scope, becomes a synonym for the type given by the decl-specifiers portion of the declaration. In contrast to the class, struct, union, and enum declarations, typedef declarations do not introduce new types — they introduce new names for existing types.  Example  // Example of the typedef keyword typedef unsigned long ulong;  ulong ul;     // Equivalent to "unsigned long ul;"  typedef struct mystructtag {    int   i;    float f;    char  c; } mystruct;  mystruct ms;   // Equivalent to "struct mystructtag ms;"  typedef int (*funcptr)();  // funcptr is synonym for "pointer                            //    to function returning int"  funcptr table[10];   // Equivalent to "int (*table[10])();" 更深的理解了下

user: user-2
content: typedef后面新定义的标识符当作除typedef外的类型的别名 例如: 1. typedef char Line[10];     标识符Line是char [10]的别名 2. typedef int (*p)(char*,char*);    标识符p是 int (*)(char *,char *)的别名,即:指向参数为(char *, char *)返回值为int的函数的指针

user: user-1
content: 理解和讨论之前请先学会如何观察！  建议楼主参考gcc源代码中typedef处理相关片断。

user: user-1
content: 针对 宏 可以查看其展开后的效果：VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898  typedef好象不行。  宏的本质是字符串替换 #与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC   typedef是定义一个别名 typedef typedef type-declaration synonym;  The typedef keyword defines a synonym for the specified type-declaration. The identifier in the type-declaration becomes another name for the type, instead of naming an instance of the type. You cannot use the typedef specifier inside a function definition.  A typedef declaration introduces a name that, within its scope, becomes a synonym for the type given by the decl-specifiers portion of the declaration. In contrast to the class, struct, union, and enum declarations, typedef declarations do not introduce new types — they introduce new names for existing types.  Example  // Example of the typedef keyword typedef unsigned long ulong;  ulong ul;     // Equivalent to "unsigned long ul;"  typedef struct mystructtag {    int   i;    float f;    char  c; } mystruct;  mystruct ms;   // Equivalent to "struct mystructtag ms;"  typedef int (*funcptr)();  // funcptr is synonym for "pointer                            //    to function returning int"  funcptr table[10];   // Equivalent to "int (*table[10])();"

user: user-3
content: 声明语句： char IntArray[10]; int Function(char *, char *);  前面加 typedef 后定义出新类型： typedef char IntArrayType[10]; typedef int (*FunctionType)(char *, char *); 这里 IntArrayType 即代表上述声明中 IntArray 的类型，FunctionType 同理。  使用新类型来完成声明语句，与开头的声明语句作用相同： IntArrayType IntArray; FunctionType Function; 这里有个特例，函数指针类型声明要加 (*Typename) 而非直接写 Typename。  由于 C 语言书写的时候，下面三组形式的意义是一样的： FunctionType pfn = Function; FunctionType pfn = &Function; Function(str1, str2); (*Function)(str1, str2); pfn(str1, str2); (*pfn)(str1, str2);  实际上函数名也是一个指针，按下面的书写方式就不难理解了。 typedef int (*FunctionType)(char *, char *); int (*Function)(char *, char *); FunctionType pfn = Function; (*Function)(str1, str2); (*pfn)(str1, str2);

user: user-4
content: 在声明变量X为类型 T 的语句前加上 typedef, 就是声明 X 为 类型 T 的别名。  char Line[10]; 是声明 Line 为 类型 char[10] 。 typedef char Line[10]; 声明 Line 为 类型 char[10] 的别名。

user: user-5
content: 很好理解！ 先理解 char Line[10];        //Line是一变量 加上typedef后， typedef char Line[10];       //此时，Line成为了一种类型

user: user-6
content: 引用 5 楼 fl_beijing 的回复:1. typedef char Line[10]; 2. typedef int (*p)(char*,char*)  这是2种语法 1 typedef char Line[10]   表示  Line  就是  char[10] 2 typedef int (*p)(char*,char*)  这是定义了一个函数指针 p,   p 是一个指针， p指向的是一个函数， 这个函数有2个  char* 参数和一个 int 返回值  自己写个demo 验证一下就行了

user: user-7
content: 引用 17 楼 ituling 的回复:[quote=引用 6 楼 lm_whales 的回复:] typedef char Line[10]; 表示 Line 是 char[10] 这个类型； 可以这么理解 先 撇开char Line[10];  Line 是个10个元素的 char 数组--->也就是char  [10] 类型的数据； typedef char Line[10] ; Line 就是10个元素的 char 数组 类型。 2. typedef int (*p)(char*,char*); int (*p)(char*,char*);  *p 是个返回值为 int,两个参数都是 char * 的函数 所以 p是个函数指针，指向的函数类型为 ：返回值为 int 类型,两个参数都是 char * 类型的函数 p 是个返回值 为int 类型,两个参数都是 char * 类型的函数指针变量； 加上 typedef 后，p从 变量定义，转换为类型定义 它的类型就是：     返回值 为int 类型 ,两个参数都是 char * 类型的函数（的）指针 类型  分析 typedef 的时候， 先撇开typedef ， 那么这就是一个数据（对象）定义（或者声明）， C++可能还包括函数定义（或者声明） 看看后面定义（或者声明）的数据（对象） 是个什么类型的数据（对象） 然后 加上 typedef  改为 定义类型 ； 上一步得到的数据（对象）的 类型，就是 typedef   定义的 类型。 引用 14 楼 chehw_1 的回复:[quote=引用 13 楼 ituling 的回复:] 说实话 pint 不会拆开为 int * 而是 作为一个int *类型 这句话不是特别特别理解 ，有些模糊  举个例子：  typedef int * PINT; PINT m, n; // 此时，m, n均为（int * ）类型。 m = n; // 可以，同为int * 类型的指针   #define PINT int *  PINT m, n; // 此时，m为（int *)类型，而n为（int)类型。因为宏展开后，该行实际为 int * m, n; m = n; // 编译器会警告类型不匹配 m = &n; // 可以 [/quote]    引用 4 楼 lm_whales 的回复:typedef int * pint; const pint x; pint 不会拆开为 int * 然后和 const 组合成 const int * 而是 作为一个int *类型 那么 const pint  就是 pint const, 也就是 int *const;  诸如此类  谢谢你们的耐心讲述，我差不多明白了typedef和#define的区别，我不理解的是下面，这个在C++primer中也讲过，不是特别理解，还能相信讲一下么 typedef int * pint; const pint x; pint 不会拆开为 int * 然后和 const 组合成 const int * 而是 作为一个int *类型 那么 const pint  就是 pint const, 也就是 int *const;  为啥 const pint 就成了 int *const; 因为pint 不会拆开为 int * 他这样确实就是一个int指针为啥被const修饰之后就成了 int *const;[/quote]  对一个类型 T const  T a; 和  T const a； 都是 定义 T 类型常量  int *const a; //a 这个int类型指针是常量；这是指针常量，指针本是是常量。 const  int *a; // *a;这个 int 类型的对象是常量。a这是常量指针。指向常量的指针                        //单独的const int * 这三个符号放在一起，编译器会根据运算符结合性，优先级，                          以及各个符号的顺序，解释定义（声明）的对象的类型 。   const pint a;     /// pint 对象a, 也就是 int 指针（int*）a， 是个常量； 这就是类型 pint 不再拆分为 int *两个符号的含义。                            /// pint 是 int 指针 （int*）最先得到解释 ，不再是 const int * 三个符号，放在一起处理后解释了。 pint  const a;    ///a 是个 int 指针（int*） 并且是指针常量，也是先解释 pint 再解释 pint const ; 这样，pint  const a;  int *const a;定义的对象，就是同一个类型的对象了。这算是巧合。  int *const a； 是四个符号（包括标识符 a）， 一起解释。 这个语句解释成定义指针常量 a; 这样 int *const 这个类型，就是指针常量类型；

user: user-6
content: 1. typedef char Line[10]; 2. typedef int (*p)(char*,char*)  这是2种语法 1 typedef char Line[10]   表示  Line  就是  char[10] 2 typedef int (*p)(char*,char*)  这是定义了一个函数指针 p,   p 是一个指针， p指向的是一个函数， 这个函数有2个  char* 参数和一个 int 返回值

user: user-7
content: typedef char Line[10]; 表示 Line 是 char[10] 这个类型； 可以这么理解 先 撇开char Line[10];  Line 是个10个元素的 char 数组--->也就是char  [10] 类型的数据； typedef char Line[10] ; Line 就是10个元素的 char 数组 类型。 2. typedef int (*p)(char*,char*); int (*p)(char*,char*);  *p 是个返回值为 int,两个参数都是 char * 的函数 所以 p是个函数指针，指向的函数类型为 ：返回值为 int 类型,两个参数都是 char * 类型的函数 p 是个返回值 为int 类型,两个参数都是 char * 类型的函数指针变量； 加上 typedef 后，p从 变量定义，转换为类型定义 它的类型就是：     返回值 为int 类型 ,两个参数都是 char * 类型的函数（的）指针 类型  分析 typedef 的时候， 先撇开typedef ， 那么这就是一个数据（对象）定义（或者声明）， C++可能还包括函数定义（或者声明） 看看后面定义（或者声明）的数据（对象） 是个什么类型的数据（对象） 然后 加上 typedef  改为 定义类型 ； 上一步得到的数据（对象）的 类型，就是 typedef   定义的 类型。

user: user-7
content: typedef int * pint; const pint x; pint 不会拆开为 int * 然后和 const 组合成 const int * 而是 作为一个int *类型 那么 const pint  就是 pint const, 也就是 int *const;  诸如此类

user: user-0
content: 引用 1 楼 lm_whales 的回复:typedef 以后，不是什么替换 而是把这个类型名作为一个整体处理，不再接收分割分析  这个类型名作为一个整体处理 这是啥意思？

user: user-7
content: #define 是宏替换，替换后，预编译器就不管了 然后交给编译器去分析 这些符号是些什么东东  如果 替换后的结果是个类型，或者几个类型相关符号的组合  那么，分析类型的时候， 包含宏的代码，宏展开后，他的每个成分， 都是单独处理的，然后加以组合， 其中可以组成类型 的部分，构成一个完整的类型信息

user: user-7
content: typedef 以后，不是什么替换 而是把这个类型名作为一个整体处理，不再接收分割分析

user: user-8
content: 引用 17 楼 ituling 的回复:为啥 const pint 就成了 int *const; 因为pint 不会拆开为 int * 他这样确实就是一个int指针为啥被const修饰之后就成了 int *const;  先看一下这个例子：  const int m = 0; // 告诉编译器，m 为一个int类型的常量 m = 1; // 编译器会报错，因为m这个int数值不能（应）修改  当你把'int'替换为 'PINT'时，  int n; const PINT m = NULL; // 告诉编译器，m 为一个PINT类型的常量， 即m这个int *指针是个常量 // const 修饰的是PINT, 相当于是“ const  (int *) ”, 不过C中没有这种写法， 等价的写法是int * const m  = &n; //编译器会报错，因为 m 这个指针值不能（应）修改

user: user-9
content: 引用 10 楼 paschen 的回复: #define int_ptr1 int* typedef int* int_ptr2;  int_ptr1 a,b,c; //等价于int* a,b,c，只有a是int*，b,c是int int_ptr2 d,e,f; //d,e,f都是int*  这个回复好，顶一个~ 试试把下面代码编译一下看看，研究一下就明白了。 PS：函数指针挺常见，C也可以动态加载，函数指针就可以实现。 typedef char Line[10]; typedef int(*p)(char*, char*);  int func(char *pcDest, char *pcSrc) { 	printf("pcDest = %s\n", pcDest); 	printf("pcSrc = %s\n", pcSrc); 	return 100; } void getNums(void) { 	Line l = {0}; 	l[5] = 2; 	p pf = func; 	for (int i = 0; i < 10; i++) 	{ 		printf("l[%d] = %d\n", i, l[i]); 	} 	pf("dest", "src"); }

user: user-0
content: 引用 6 楼 lm_whales 的回复:typedef char Line[10]; 表示 Line 是 char[10] 这个类型； 可以这么理解 先 撇开char Line[10];  Line 是个10个元素的 char 数组--->也就是char  [10] 类型的数据； typedef char Line[10] ; Line 就是10个元素的 char 数组 类型。 2. typedef int (*p)(char*,char*); int (*p)(char*,char*);  *p 是个返回值为 int,两个参数都是 char * 的函数 所以 p是个函数指针，指向的函数类型为 ：返回值为 int 类型,两个参数都是 char * 类型的函数 p 是个返回值 为int 类型,两个参数都是 char * 类型的函数指针变量； 加上 typedef 后，p从 变量定义，转换为类型定义 它的类型就是：     返回值 为int 类型 ,两个参数都是 char * 类型的函数（的）指针 类型  分析 typedef 的时候， 先撇开typedef ， 那么这就是一个数据（对象）定义（或者声明）， C++可能还包括函数定义（或者声明） 看看后面定义（或者声明）的数据（对象） 是个什么类型的数据（对象） 然后 加上 typedef  改为 定义类型 ； 上一步得到的数据（对象）的 类型，就是 typedef   定义的 类型。 引用 14 楼 chehw_1 的回复:[quote=引用 13 楼 ituling 的回复:] 说实话 pint 不会拆开为 int * 而是 作为一个int *类型 这句话不是特别特别理解 ，有些模糊  举个例子：  typedef int * PINT; PINT m, n; // 此时，m, n均为（int * ）类型。 m = n; // 可以，同为int * 类型的指针   #define PINT int *  PINT m, n; // 此时，m为（int *)类型，而n为（int)类型。因为宏展开后，该行实际为 int * m, n; m = n; // 编译器会警告类型不匹配 m = &n; // 可以 [/quote]    引用 4 楼 lm_whales 的回复:typedef int * pint; const pint x; pint 不会拆开为 int * 然后和 const 组合成 const int * 而是 作为一个int *类型 那么 const pint  就是 pint const, 也就是 int *const;  诸如此类  谢谢你们的耐心讲述，我差不多明白了typedef和#define的区别，我不理解的是下面，这个在C++primer中也讲过，不是特别理解，还能相信讲一下么 typedef int * pint; const pint x; pint 不会拆开为 int * 然后和 const 组合成 const int * 而是 作为一个int *类型 那么 const pint  就是 pint const, 也就是 int *const;  为啥 const pint 就成了 int *const; 因为pint 不会拆开为 int * 他这样确实就是一个int指针为啥被const修饰之后就成了 int *const;