共用体、typedef、位运算

共用体

定义

  • 共用体是一个用户自定义的类型,包含多个不同类型的成员,但在同一时间只能存储其中一个成员的值。
  • 共用体的声明类似于结构体,但使用关键字 union
union Example {
    int i;
    float f;
    char c;
};

 

内存分配

  • 共用体的大小等于其最大成员的大小。例如,如果共用体包含一个 int(4字节)、一个 float(4字节)和一个 char(1字节),则共用体的大小为4字节。
  • 这种存储方式允许不同类型的数据在同一块内存区域中存储,从而节省内存。

访问成员

  • 可以通过使用点运算符(.)访问共用体的成员。由于所有成员共享同一内存,因此在任何时候只能访问最后写入的成员。
  • 访问未定义的成员值是未定义行为
union Example e;
e.i = 42;
printf("%d\n", e.i); // 输出:42
e.f = 3.14f;
printf("%f\n", e.f); // 输出:3.140000

用途

  • 节省内存:在内存有限或需要高效内存使用的嵌入式系统中,共用体非常有用。
  • 类型转换:共用体可以用来在不同类型之间进行低级别的类型转换。例如,可以通过共用体将浮点数的位模式解释为整数类型。

共用体与结构体的区别

  • 内存分配:结构体的大小是其所有成员的大小总和,而共用体的大小是其最大成员的大小。
  • 成员访问:结构体中的所有成员都有独立的内存空间,可以同时访问;共用体只能同时存储一个成员的值。

 

#include <stdio.h>

union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    union Data data;
    
    data.i = 10;
    printf("data.i : %d\n", data.i);
    
    data.f = 220.5;
    printf("data.f : %f\n", data.f);
    
    strcpy(data.str, "C Programming");
    printf("data.str : %s\n", data.str);
    
    return 0;
}

 共用体 Data 依次存储了整数、浮点数和字符串。最后访问的成员 data.str,覆盖了之前的值。

typedef

typedef 是 C 语言中的一个关键字,用于为现有的数据类型定义新的类型名称。它的主要目的是提高代码的可读性、可维护性和简化复杂类型的使用

typedef existing_type new_type_name;
  • existing_type 是已经存在的类型,可以是基本数据类型(如 intfloat)或复合类型(如结构体、共用体、指针等)。
  • new_type_name 是新的类型名,用户可以在代码中使用它来替代 existing_type

简化复杂类型的定义

  • 对于复杂的类型声明(如指向函数的指针),使用 typedef 可以使代码更简洁和易读
    typedef void (*func_ptr)(int, int);
    

  • 上述定义创建了一个新的类型 func_ptr,它表示一个指向以两个 int 作为参数、返回类型为 void 的函数的指针。

  • 提高代码的可读性

  • 使用 typedef 可以为类型创建更具描述性的名称,从而使代码更易于理解。
    typedef unsigned long ulong;
    

    unsigned long 类型定义为 ulong,使其在使用时更加简洁

  • 提高代码的可维护性

  • 在需要改变类型定义的情况下,只需修改 typedef 的定义,而不需要修改代码中所有出现该类型的地方。
    typedef int size;
    size x, y;
    

    若以后需要将 size 类型改为 long,只需修改 typedef int size;typedef long size;

 

与结构体、共用体和枚举配合使用

  • 使用 typedef 可以为结构体、共用体和枚举类型定义新的名称,简化它们的使用。
typedef struct {
    int x;
    int y;
} Point;

Point p1;

定义了一个结构体类型 Point,并使用它来声明变量 p1。 

  • typedef 仅仅是创建了类型的别名,它不会创建新的类型。类型别名在编译器看来与原类型完全相同。
  • typedef 的定义通常放在头文件中,以便在多个源文件中共享。

 位运算

位运算符

  1. 按位与 (&)

    • 对应位都为1时,结果为1;否则为0。
    • 常用于清零操作、保留某些位。
    int a = 5; // 0101
    int b = 3; // 0011
    int result = a & b; // 结果:0001,即1
    

    2.按位或 (|)

  1. 对应位有一个为1,结果即为1。常用于设置某些位。

int a = 5; // 0101
int b = 3; // 0011
int result = a | b; // 结果:0111,即7

按位异或 (^)

  • 对应位不同则结果为1,相同则为0。
  • 常用于翻转某些位、比较两个值是否不同。

 

int a = 5; // 0101
int b = 3; // 0011
int result = a ^ b; // 结果:0110,即6

 

按位取反 (~)

  • 对每个二进制位进行取反操作,即0变1,1变0。
int a = 5; // 0101
int result = ~a; // 结果:1010(补码表示-6)

左移 (<<)

  • 将位向左移动指定的位数,右边补0。
  • 相当于乘以2的若干次幂。
int a = 5; // 0101
int result = a << 1; // 结果:1010,即10
int a = 5; // 0101
int result = a >> 1; // 结果:0010,即2
  • 将位向右移动指定的位数。
  • 如果是无符号数,左边补0;如果是有符号数,行为依赖于编译器(有符号位扩展和逻辑右移两种可能)。

笔记详解 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值