1、typedef
C语言的关键字,其作用是给一种已有的数据类型取别名。这里的数据类型包括基本数据类型(int,char等)和自定义的数据类型(struct等)。
使用typedef目的:一是给变量一个易记且意义明确的新名字,二是简化一些比较复杂的类型声明。
2、#define
宏,在C或C++语言中,“宏”分为有参数和无参数两种。
使用#define的好处:一是方便程序的修改。使用简单宏定义的常量,在需要改变该常量时,不用对整个程序进行修改,只需修改宏定义的字符串即可;二是提高程序的运行效率。使用带参数的宏定义可完成函数调用的功能,能减少系统开销,提高运行效率。
3、typedef和#define的基本用法:
#define pi 3.14159 //无参宏:预编译时pi被替换为3.14159
#define f(x) ((x)*(x)) //有参宏:宏函数可以减小系统开销
typedef int btye_4; //给已知数据类型 int 起个别名,叫 byte_4
typedef struct _node
{
int data;
struct _node *next;
}node; //给struct _node结构体,起个别名叫 node
引申:#define 宏定义可以使用 #ifdef ,#ifndef等进行逻辑判断,还可以使用#undef来取消定义。
4、typedef 和 #define的区别
(1)与#define不同,typedef创建的别名只受限于类型,不能用于值。
(2)#define是宏定义,在预处理阶段就已经替换完成;而typedef是以;结尾的语句参与编译,由编译器解释。
(3)在受限范围内,typedef比 #define更加灵活。
(4)宏定义作用域为宏定义命令起到源程序结束,typedef作用域限制在所定义的函数或者文件内(取决于此定义的位置)。
5、使用typedef 和 #define时应该注意的问题
(1)在定义指针变量的时候,typedef 和 #define的区别
#include <stdio.h>
#define pStr2 char* //使用#define
int main()
{
typedef char* pStr1; //使用typedef
pStr2 c, d;
printf("a = %d, b= %d\n", sizeof(a), sizeof(b));
printf("c = %d, d= %d\n", sizeof(c), sizeof(d));
return 0;
}
结果如下:
分析:在上述变量的定义中,a,b,c都被定义为char *类型,占4个字节,而d则被定义成为char类型,只占一个字节,得到的变量d并不是我们所预期的指针变量。根本原因就在于#define只是简单的字符串替换,而typedef则是为一个类型起新名字。
(2)我们再通过例子来看typedef 和 #define的区别:
typedef char* pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++; //这个地方出错了
分析:上述代码中const pStr p2并不代表const char * p2,因此后面p2++报错了。(这个例子再一次提醒我们:typedef不是简单的文本替换,和#define不同。)
此例中const pStr p2的含义是:限定数据类型为char *的变量p2为只读,而且不管是写成const pStr p2还是pStr const p2,本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是自己定义的而已。
(3)#define使用中要注意:如果定义中包含表达式,尽可能使用括号,否则可能出错
#include <stdio.h>
#define f(x) x+x
int main()
{
int a = 2,b = 4,c;
c = f(a)*f(b); //想要的结果 4*8 = 32
printf("c = %d\n", c); //实际得到 2+2*4+4 =14
return 0;
}
分析:因为#define是简单的替换,替换后可能出现结合顺序变化,所以上述定义应为:#define f(x) ((x)+(x))。