C语言标识符之define,typedef,union,struct和位域的综合理解

前言:

标题有些长,是因为在实践中遇到的一个问题包含了多个知识点的综合应用,索性就一起说说。

目标代码如下:

typedef union{
unsigned int Byte;
struct
{
    unsigned a : 1;
    unsigned b : 1;
    unsigned c : 1;
	unsigned d : 1;
} Bits;
}tFault;   

目标代码包含了typedef,union,struct及位域等标识符和知识点。

typedef和define

C 语言 typedef 与 #define 比较
typedef与define在功能上有部分重合,但二者也有显著不同,typedef是对数据类型的重定义,define是对字符串的简单替换,前者是编译阶段进行,后者是预处理阶段就执行了。
直接上代码:
typedef是对类型的重定义,且不可再加类型修饰

#define INTERGE int;
unsigned INTERGE n;  //没问题
typedef int INTERGE;
unsigned INTERGE n;  //错误,不能在 INTERGE 前面添加 unsigned

对于指针类型来说,可以理解为define只是简单的做了字符替换,而typedef相当于用括号把后面的包含了

#define PTR_INT int *
PTR_INT p1, p2;        //p1、p2 类型不相同,宏展开后变为int *p1, p2;
typedef int * PTR_INT
PTR_INT p1, p2;        //p1、p2 类型相同,它们都是指向 int 类型的指针。

typedef 由于是编译时执行,所以其有类型检查功能,并且typedef有作用域,而define没有.

void func1()
{
    #define HW "HelloWorld";
}
 
void func2()
{
    string str = HW;
    cout << str << endl;
}
void func1()
{
    typedef unsigned int UINT;
}
 
void func2()
{
    UINT uValue = 5;//error C2065: 'UINT' : undeclared identifier
}

union联合体

又名共用体,字面意思,修饰的成员变量共用同一块内存,因此对其中某一成员的修改会覆盖其他成员的值。union在结构和用法上与struct基本一样,不同之处在于struct成员变量使用不同的内存,一块struct结构体的内存要略大于其成员变量内存总和。
union的理解如下:
初始时:
在这里插入图片描述
执行断点1后可见变量都发生了改变
在这里插入图片描述
最终运行结果:
4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

struct结构体

struct 修饰的语句为结构体成员,若做类比的话,结构体就如一张固定的图纸,结构体定义的变量就像图纸里的元件
同一个结构体定义的变量具有相同的特性
结构体具有字节对齐特性,以其包含的最长类型为模板对齐。比如一个结构体变量包含int ,char,long类型,则此结构体大小为12字节,
4+4(char本为1,被对齐为4)+4

struct结构体使用如下:

struct test
{
    /* data */
    int a;
    char b;
};
struct test A;//C++不需要加struct
A.a=1;

struct
{
    /* data */
    int a;
    char b;
}T,W;
T.a=1;W.b='c';//只能使用这两个结构体变量,不能再struct新结构体变量

特殊点的:

typedef struct tagNode
{
    char *pItem;
    struct tagNode *pNext;
} *pNode;

struct不允许用结构体定义成员变量,但允许定义指针,因为指针大小可以确认。

位域

位域详解
先看一个例子:

struct {                                                  
         unsigned mode:8;          //bit[0,7]:模式选择
         unsigned en:1;            //bit[8]   :使能选择
         unsigned reserved:1;      //bit[9]    :保留reserved  (也可以写成unsigned reserved:1;)
         unsigned clk_select:4;    //bit[10,13]:时钟选择
         unsigned ch_select:3;     //bit[14,15]:通道选择
}reg11;            //定义一个reg11变量,不声明结构体的好处在于确保变量唯一性

位域可单独操作某一寄存器数据位,比如对bit[8]赋值:reg11.en = 1;

位域越界:
当赋值:reg11.en=5; 时
系统会保留最低位,此时 en = 1;
当 reg11.en=6; 时 en = 0;

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值