user-0 提问: typedef 与 #define区别中的理解？

回复:
user: user-1
content: ypedef char *pStr1; #define pStr2 char *; pStr1 s1, s2; pStr2 s3, s4; 上述的变量定义中，s1、s2、s3都被定义为char *，而s4则定义成了char， 不是我们所预期的指针变量，根本原因就在于#define只是简单的字符串替换， 而typedef则是为一个类型起新名！  说的很清楚了啊！容易理解！  pStr2直接替换成了 char*就就可以了！ pStr2 s3, s4; 等价于 char* s3,s4; s4就是一个char的类型  而typedef却不是替换！ pStr1 s1, s2;  注意pStr1是一个类型了，代表了char*，不是替换的关系，而是代表，或者说定义了，typedef就是重定义一样！ pStr1 s1, s2;  这句话的意思是定义了一个pStr1类型的两个变量s1,s2 ；

user: user-2
content: 其实很好理解，使用typedef 表示给一个类型起了一个别名你可以理解为一个新类型。而#define只是简单替换，所以你的定义语句等价为   char *s1;char *s2;   char *s3 ,s4;（与char *s3;char s4;等价）这样你清楚了吗？

user: user-3
content: 其实不用想太复杂 一个是宏定义，简单的字符替换  另外一个是类型别名，跨平台开发用

user: user-4
content: 一个是替换 一个是类型定义

user: user-5
content: 1. 对于变量类型，以下规则适用： 变量类型 变量名1, 变量名2; ==> 变量类型 变量名1; 变量类型 变量名2; int i1, i2;    ==> int i1;   int i2; char *s1, *s2; ==> char *s1; char *s2; char *s3, ch;  ==> char *s3; char ch;在上述例子中，如果你将 * 和 s1、s2、s3 当作整体，和 i1、i2 比较一下，可以看出几乎一样。 星号的书写是应该放在类型名后面还是变量前面，一直争执不断。我个人喜欢靠近变量，原因如上。  例如，定义新类型 PTRCHAR 如下：typedef char * PTRCHAR;几个声明语句可以按照如下方式展开理解：PTRCHAR s1, s2;  ==> PTRCHAR s1; PTRCHAR s2;  ==> char *s1; char *s2; PTRCHAR s3, *s4; ==> PTRCHAR s3; PTRCHAR *s4; ==> char *s3; char **s4;2. 对于宏，仅仅是文字层面的替换，此时尚未进行对语法分析的层面。 例如，定义宏 CHARPTR 如下：#define CHARPTR char *几个声明语句可以按照如下方式展开理解：CHARPTR s1, s2;  ==> char *s1, s2;  ==> char *s1; char s2; CHARPTR s3, *s4; ==> char *s3, *s4; ==> char *s3; char *s4;

user: user-5
content: // PTRCHAR 像“int”一样是新类型 typedef char *PTRCHAR; // CHARPTR 是“char *”的简单替换 #define CHARPTR char *  int i1, i2; PTRCHAR s1, s2; // -> int i1; int i2; PTRCHAR s1; PTRCHAR s2; // -> int i1; int i2; char *s1; char *s2;  int *i3, i4; CHARPTR s3, s4; // -> int *i3, i4; char * s3, s4; // -> int *i3; int i4; char * s3; char s4;

user: user-6
content: typedef 定义了一种新的类型，编译器会对这种类型做必要的检测  #define只是定义了一个替换规则，编译器不检测，只做简单替换

user: user-7
content: typedef char *pStr1; #define pStr2 char *; pStr1 s1, s2; pStr2 s3, s4;  你可以理解成 char *s3,s4； 也就是 char *s3; char s4;  你可以改成 pStr2 s3;pStr2 s4;这样s4就被定义成指针。 归根原因是typedef  是将定义类型做了个别名，#define 只是替换相应字符；

user: user-8
content: 建议群主去看Microsoft定义的一系列头文件，看看里面什么时候用#define什么时候用typedef。看多了就懂了。 我就是这样学习的。

user: user-9
content: 理解和讨论之前请先学会如何观察！  搜“盲人摸太阳”

user: user-10
content: 吃透了这句话就可以了。  根本原因就在于#define只是简单的字符串替换， 而typedef则是为一个类型起新名字。

user: user-11
content: 这么简单还问…… 你根本没理解如何声明指针。 如果char *s3,*s4;  s3 s4 都被声明为char类型指针。 如果char s3,s4;  s3 s4都被声明为char类型普通变量。 如果char *s3,s4;  则s3被声明为char类型指针，s4为char类型普通变量。 既然你知道#define只是替换，那你把第二个语句中的替换就好了啊，替换完是不是我写的第二个如果中的情况？ 好好读读书

user: user-12
content: 樓主，11樓和13樓都說的沒錯，#define pStr2 char *，首先後面沒有分號；其次你仔細看就會發現char和*之間有個空格， 當定義pStr2 S3,S4時，由於是#define,pStr2會被替換成char空格*，就是執行的實際是char *S3，S4。意思就是#define 只是個替換的作用，編譯之前#define定義的所有pStr2代碼部分就被替換掉了，

user: user-13
content: 宏的作用是 把你后面写得或长或短的东西 直接用一个名词替代 其作用和你直接把后面那堆敲进去在编译器来看是一个样的  typedef仅仅只是把一个已知的名称类型 定义成为另外一个名称而已。 两者作用差得老远了

user: user-14
content: typedef 出来的标识符，具备类型检查

user: user-15
content: #define就是查找替换 其实一替换就很清楚了  char * s1, s2 请问s2是什么类型？

user: user-16
content: typedef 相当于是给一个类型 取了个别名 代号 就像是 class {}class1, 这样。 而define只是替换 一个值，不能替换类型的

user: user-17
content: 这也是一个编程规范了，一般我们都是一个变量一个变量的声明，这样可以避免一个笔误，如char *p1,p2;你写成char *p1; char *p2 就不会了

user: user-18
content: 既然帖子被标为推荐，朕也来说几句。 关于# define，楼主是明白的，不解释。 关键字typedef的作用是将一个标识符定义为它被声明的那种类型。它被声明为什么类型，它就是那种类型的别名。比如： typedef int Integer; typedef char * PCHAR; typedef int F (int); 以上，标识符Integer是int类型的别名，F是一个函数类型的别名，该函数接受一个int类型的参数，返回类型是int。在此之后，就可以声明这两种类型的其它标识符，例如： int f (int x) {/* ... ... */} void g (const char * s1, const char * s2) {/* ... ... */}  int main (void) {     Integer x = 0;    //S1     F f;                    //S2     PCHAR s1 = "House of cards", s2 = s1;    //S3     g (s1, s2);     return f (x); } 以上，在S1中，x的类型是Integer，Integer是int的别名，所以x的类型是int；在S2中，f的类型是F，F是函数类型int (int)的别名，所以S2等价于 int f (int); 在S3中，s1和s2的类型都是PCHAR，PCHAR是指针char *的别名，所以s1和s2都是char *类型。即，都是指向char的指针。

user: user-19
content: 其实要理解这个例子只需要理解指针的定义， 1.当定义两个指针时，这样定义： char *a, *b; 2.而如果定义了 char *a, b; 则是定义了一个指针，一个变量；  那么再汇过来理解题目就好理解了，#define只是进行了替换，这样就形成了上面2所示的例子，而用typedefine则是直接把一个类型定义成了另外一个类型，那么这时候就不是简单的替换了。