C语言编程艺术--C语言中Union类型与指针

2016-08-26

在C语言中通过union数据类型可以方便地将不同的数据类型定义在同一段数据空间内,这样的用途可能用几个:
1)定义一个变量,在不同的场合当成不同的类型使用,两种场合没有任何联系,两次使用的值也没有任何联系;
2)定义一个变量,存储某一种多字节的数据类型,读取或者存取时可以通过其它类型的数据或变量部分地读取或修改(本文即介绍该用途)

如:

在Keil C51 7.50a中测试代码如下
union{
unsigned long ul;
unsigned int ui[2];
unsigned char uc[4];
}u;

void main(void)
{
unsigned int uitest;
unsigned char uctest;
unsigned long ultest;

u.ul = 0x12345678;
uitest = u.ui[0];  // uitest = 0x1234
uitest = u.ui[1];  // uitest = 0x5678
uctest = u.uc[0];  // uctest = 0x12
uctest = u.uc[1];  // uctest = 0x34
uctest = u.uc[2];  // uctest = 0x56
uctest = u.uc[3];  // uctest = 0x78

ultest = 0x12345678;
uitest = ((unsigned int*)(&ultest))[0];  // uitest = 0x1234
uitest = ((unsigned int*)(&ultest))[1];  // uitest = 0x5678;
uctest = ((unsigned char*)(&ultest))[0]; // uctest = 0x12
uctest = ((unsigned char*)(&ultest))[1]; // uctest = 0x34
uctest = ((unsigned char*)(&ultest))[2]; // uctest = 0x56
uctest = ((unsigned char*)(&ultest))[3]; // uctest = 0x78;

}
注释为在观察窗口看到的结果,注意优化等级应为3级或者以下,否则有些代码行会被优化掉

由代码示例可清楚地知道,通过指针可以方便地读取或者修改多字节数据类型的任意一个部分,通过强制类型转换和指针可以把一种数据类型所占的存储空间当成一个unsigned char的数组来操作,非常方便、灵活。但这样又是不安全的,特别是这些变量在中断中被使用的时候,可能造成意外的数据损坏,建议在进行这操作的时候关闭所有中断(或仅关闭对这些变量有操作的中断)。

两种方法虽然用法不一样,但效果完全一样,而且连Keil生成生代码都一样,从效率上没有什么优势,从代码的管理上似乎用指针也没有什么优势,这里或许只能从展示指针的妙用上及灵活性上说明点儿什么吧!
“不用指针,谁还用C写程序啊?”