69,371
社区成员
发帖
与我相关
我的任务
分享
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,
不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换,
而typedef则是为一个类型起新名字。
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;
// 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;
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的指针。char *a, *b;
2.而如果定义了
char *a, b;
则是定义了一个指针,一个变量;
那么再汇过来理解题目就好理解了,#define只是进行了替换,这样就形成了上面2所示的例子,而用typedefine则是直接把一个类型定义成了另外一个类型,那么这时候就不是简单的替换了。