Chinaunix首页 | 论坛 | 博客
  • 博客访问: 535820
  • 博文数量: 181
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1498
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-22 15:17
个人简介

用发呆的时间来理清自己的思绪

文章存档

2015年(7)

2014年(134)

2013年(40)

分类: 嵌入式

2014-09-10 16:30:37

一、tpyedef
    typedef是C语言语句,其功能是用户为已有数据类型取“别名”,并没有创建一个新的类型,只是已有类型的一个代理而已,目的是为了达到简化代码,见名知意的目的。
例如: 
typedef int INT;
则INT就是int的代理,此时要定义两个int型的变量,则可以使用如下语句:
INT a,b;  《===》int a,b;
当使用typedef定义数组、指针、结构体类型时,将带来很大的方便,使程序书写简单,而且意义明确,达到见名知意的效果,例如:
1.定义数组
typedef int STR[32]; //相当于给int a[32]取了一个别名,此时若要定义3个同样的变量,方法如下:
STR a,b,c; //等价于:int a[32],b[32],c[32]
2.定义指针
typedef void (*P)(int a,int b) //表示p是一种指向void (int a,int b)型的指针,若此时我还需要定义5个这样的变量,有两种方法:
第一种方法:
void (*p1)(int a,int b)
void (*p2)(int a,int b)
void (*p3)(int a,int b)
void (*p4)(int a,int b)
void (*p5)(int a,int b)
第二种方法:
P p1,p2,p3,p4,p5  //效果和上面的一样,但是写法简单了很多,当函数指针更加复杂时,这种优点体现的就会越明显
3.定义结构体
typedef struct{
    char *name;
    int age;
    char *sex;
}STUDENT;
现在根据需要,要定义5个学生结构体类型,做法如下:
STUDENT s1,s2,s3,s4,s5;  
以上语句完全等价于:
struct{
    char *name;
    int age;
    char *sex;
}s1; 
……
struct{
    char *name;
    int age;
    char *sex;
}s5;
    总结:由以上的分析可以看出,typedef就是给已有的基本类型和自己定义的类型取个别名,然后利用这个别名就可以方便的定义出更多的相同类型的变量,使代码的书写方便,意义明确。
二、#define
    define是c/c++语言提供的三种预处理(宏定义、文件包含、条件编译)功能当中的一种,比如:
    #define SIZE 1024
    则在编译预处理时,对程序中所有出现的宏名(在这里是SIZE),都会用宏定义中的字符串(在这里是1024)去代换,这称为宏代换或者红展开,此时并不进行任何语法检查,字符串是什么,他就自动替换为什么。其中宏定义是在源程序中通过宏定义完成的,而宏替换是在预处理过程中由预处理程序进行替换的。
    宏定义的优点:
    1.方便程序的修改
    比如才源程序中将很多的常量都使用宏定义,当需要改变常量时,不需要对整个程序进行修改,只需要修改宏定义的字符串即可,这样就做到了牵一发而动全身的效果,也就是一改全改。同时,当常量比较长时,我们可以用比较短的有意义的标示符来写程序,这样会更加的方便,而且见名知意,对程序的可读性和可维护性作出了重大的贡献,在Linux内核中,我们会发现大量宏定义的使用,其带来的好处相信大家已经体会到了,试想想如果没有宏定义,我们的程序代码将会变成什么样子?
    2.提高程序的运行效率
    使用带参数的宏定义可以完成函数调用的功能,比如:
    #define MAX(a,b) (a>b? a : b)
    就是一个典型的带参数的宏定义,它的功能是求出a,b之间较大的一个数,这个函数完全可以使用一个独立的函数完成,但是由于这个函数本身代码量比较小,因此利用宏定义会更加的方便。原因如下:
    我们知道,c语言中的函数可以使程序更加模块化,便于组织,代码可以重复利用,但是这也是需要付出一些代价:在函数发生调用时,需要保护现场,函数执行完后需要恢复现场,这个保护现场和恢复现场肯定是需要一段时间,因此函数调用的系统的开销比较大,尤其是当函数比较小的时候,比如上面就两个数中最大值的这个函数,调用函数本身就仅仅只有一行代码,可以为了调用这个函数,我们需要保护现场,恢复现场,这些保护现场恢复现场的程序代码加起来其实已经远远超过了真正执行函数本身的代码量,因此,如果所有的函数的代码都非常的短,执行的时间也非常的短,那么我们要是频繁的调用我们的比较短的这些函数时,系统会频繁的进行保护现场、恢复现场……保护现场、恢复现场,这样的开销对系统来书绝对是一个负担,那该怎么办呢?
    宏定义帮我们解决了这个问题,在预处理的时候,预处理器就会把宏定义的地方使用宏定义后面的字符串全部代替,这时候不就不存在函数调用的问题了,当然也就没有保护现场、恢复现场的系统开销了。当然这样做的也有一个缺点,那就说如果程序中有1000个位置都使用了则个宏,那么预处理器就会把这1000个地方都全部替换掉,这样所带来的问题就是代码的体积肯会增大,而且宏定义越多,代码的体积会越大,因此,在考虑代码体积和程序运行效率的情况下,到底是使用宏定义还是使用函数,程序员根据需要可以自己选择,另外,宏定义只能完成简单的一些操作,对于更加复杂的操作还是由函数调用来完成。
    通过以上对typedef和define的分析,对两者的区别在做如下总结:
    1.二者的执行时间不同
    define是宏定义,在预处理阶段起作用,也就是在编译之前,它只是进行了简单而机械的字符串替换,并不进行任何语法检查,哪怕你写错了,它也照样给你替换过去,而typedef是在编译阶段有效,因此typedef有类型检查的功能。
    2.二者的功能功不同
    前面已经解释过了,typedef是定义类型的别名,而define仅仅是宏替换
    3.二者的作用域不同
    #define没有作用于的限制,只要是在之间预定义过的宏,在后面的程序中都可以使用,而typedef有自己的作用域, 本质上,typedef是一个类型的代理,由于使用类型定义一个变量时存在作用域的问题,typedef的作用域也就理所当然了。
   4.二者在程序代码中的属性不同
   宏定义并不是c语言语句,因此宏定义的最后绝对不能加分号“;”结尾,否则会出现一些很隐蔽的错误,初学者在这个问题上经常犯错误,而typedef是c语言的语句,因此必须以“;”结尾,否则编译器会报错。
   5.二者对指针修饰时,最终的效果会不同
   二者修饰指针类型时,作用不同,例如:
   typedef int * pint;//注意:结尾有分号
   #define PINT int *  //注意:结尾没有分号
   
   const pint p; //此时p不能更改,p指向的内容即:*p可以改变《===》int * const p
   const PINT p; //这条语句展开后《===》const int *p《===》 int const *p;此时p可以改变,但是p指向的内容不能改变

   pint p1,p2;   //此时p1和p2都是int *型的指针变量
   PINT p1,p2;   //此时p1是int *的变量,相当于int * p1,p2;只有一个是int *的变量。
阅读(551) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~