阐释
一直在忙,最近终于有时间回顾以前所写过所学过的一些基础知识,发现受益匪浅,可以说是返璞归真吧!比如今天所说typedef,大部分应该用的很多,但是说出有哪些方面的好处,可以说不一定很全,今天就给自己做个笔记,以免以后忘记!在大多数C或者OC工程中,声明typedef主要是创建一个与其他C类型同名的名字,特别是结构体和指针,基本上可以用于大部分类型!
使用typedef主要有以下几点:
- 隐藏实现细节。
- 增加代码的可读性。
- 全面提高你的代码可移植性。
1.1 Typedef 与 可移植性
Typedef经常用在可移植的代码中。比如:你需要定义一个数据结构,这个数据结构必须在不同的平台中占用的内存大小必须相同。如果你的数据结构是一个整形,你可能会定义short或者long,相信这些类型总是会是占用二个或者四个字节。不幸的是ANSI C并没有完全承诺。特别是你定义一个long类型,当你在Digital UNIX上写一个字母时,你的程序将会中断,因为int是四个字节,long是8个字节。为了避免这类问题,你应该使用typedef和条件判断指令一起去决定和整形的相同的类型;在大多数平台中,这种四个字节的类型一般是long,但是在Alpha或者Digital UNIX是int:
#if defined(ALPHA)&& defined (DIGITAL_UNIX)
typedef int BYTE4_T;
#else
typedef long BYTE4_T;
#endif
实例:
定义一个四个字节的变量或者类型可以如下定义:
BYTE4_T field_name;
1.2 Typedef 和结构体
为了描述一个街道的地址,我们定义了一个结构体变量,你的代码可能象这样(如下),正如所期望的那样,用struct定义了一组结构体。一般情况下,我们可以利用typedef去定义一个与地址结构体相同的名字(如下)。
struct address_s {
char * street;
char * city;
char * region;
char * country;
};
static void print_address( struct address_s * address_info
);
static void print_an_address(void)
{
struct address_s address;
address.street = "";
print_address(&address);
}
1.2.1 Typedef和函数
回顾函数类型,就是一个函数的返回值,数个函数参数的类型和具体的值的组合。typedef在这里就能定义一个函数类型的别名。其中一个作用就是减少定义多个相同函数类型的工作量。例如:你想执行一个标准的排序算法,你必须去定义一个比较函数,特别是,一个函数用于比较对象的大小。传统上,一般我们这么定义:
/* Returns 1 if item1 is greater than *
* or equal to item2; 0 otherwise. */
static int is_greater_equal(
const void *item1,
const void *item2
);
struct address_s {
char * street;
char * city;
char * region;
char * country;
};
static void print_address( struct address_s * address_info
);
static void print_an_address(void)
{
struct address_s address;
address.street = "";
print_address(&address);
}
恰恰相反的是,我们可以定义一个和比较函数相同类型,然后使用这个类型去定义比较函数的原型。我们可以这么做:
typedef int COMPARE_PROC_t( const void *, const void * );
static COMPARE_PROC_t is_greater_equal;
这种方式极大的简化了上面复杂的定义过程。例如,假设我们必须去在一个结构体中定义一个指针或者比较函数将会怎么样?这是经常出现的情况,我们一般这么做:
typedef struct sort_data_s
{
int *sort_array;
int (*test_proc)( const void *item1, const void *item2 );
} SORT_DATA_t, *SORT_DATA_p_t;
在之前的例子中,如果你使用比较函数相同的类型,这将会使上面定义的更容易去写(或者读)。在下面例子中,延伸一下,我们使用函数指针类型。使用typedef的例子中极大的简化函数关系的定义,下例中signal是一个函数,有两个参数:第一个参数是int类型;第二个是一个带有一个int类型参数和无返回值的函数指针,signal原型是这样的:
void(*signal(int sig, void(*func)(int)))(int);
如果我们使用类型指针去定义函数,将会非常简单:
typedef void SIG_PROC_t(int);
typdedef SIG_PROC_t * SIG_PROC_P_t;
SIG_PROC_P_t signal(
int sig;
SIG_PROC_P_t func;
);
typedef int COMPARE_PROC_t( const void *, const void * );
typedef COMPARE_PROC_t *COMPARE_PROC_p_t;
typedef struct sort_data_s
{
int *sort_array;
COMPARE_PROC_p_t test_proc;
} SORT_DATA_t, *SORT_DATA_p_t;