1.结构体和位运算

1.结构体

数组是一组具有相同类型的数据的集合。但在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,年龄为整数,所在的学习小组为字符,成绩为小数,因为数据类型不同,显然不能用一个数组来存放。

在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据。结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员(Member)。

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
};

结构体数组,是指数组中的每个元素都是一个结构体。在实际应用中,结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生、一个车间的职工等。更多

2.枚举

C语言提供了一种枚举(Enum)类型,能够列出所有可能的取值,并给它们取一个名字。

例如,列出一个星期有几天:

enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun };

枚举值默认从 0 开始,往后逐个加 1(递增);也就是说,week 中的 Mon、Tues ...... Sun 对应的值分别为 0、1 ...... 6

可以指定枚举的每个值及它的初始值

enum week{ Mon = 1, Tues = 2, Wed = 3, Thurs = 4, Fri = 5, Sat = 6, Sun = 7 };
enum week1{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };

枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。我们可以将枚举理解为编译阶段的宏。更多

3.位域

有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。

在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。请看下面的例子:

struct bs{
    unsigned m;
    unsigned n: 4;
    unsigned char ch: 6;
}

:后面的数字用来限定成员变量占用的位数。成员 m 没有限制,根据数据类型即可推算出它占用 4 个字节(Byte)的内存。成员 n、ch 被:后面的数字限制,不能再根据数据类型计算长度,它们分别占用 4、6 位(Bit)的内存。更多

4 大小端及判别方式

计算机中的数据是以字节(Byte)为单位存储的,每个字节都有不同的地址。现代 CPU 的位数(可以理解为一次能处理的数据的位数)都超过了 8 位(一个字节),PC机、服务器的 CPU 基本都是 64 位的,嵌入式系统或单片机系统仍然在使用 32 位和 16 位的 CPU。

对于一次能处理多个字节的CPU,必然存在着如何安排多个字节的问题,也就是大端和小端模式。以 int 类型的 0x12345678 为例,它占用 4 个字节,如果是小端模式(Little-endian),那么在内存中的分布情况为(假设从地址 0x 4000 开始存放):

内存地址0x40000x40010x40020x4003
存放内容0x780x560x340x12


如果是大端模式(Big-endian),那么分布情况正好相反:

内存地址0x40000x40010x40020x4003
存放内容0x120x340x560x78

我们的 PC 机上使用的是 X86 结构的 CPU,它是小端模式;51 单片机是大端模式;很多 ARM、DSP 也是小端模式(部分 ARM 处理器还可以由硬件来选择是大端模式还是小端模式)。更多

5. 联合体

结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员。在C语言中,还有另外一种和结构体非常类似的语法,叫做联合体(Union)

结构体和联合体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而联合体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),联合体占用的内存等于最长的成员占用的内存

#include <stdio.h>

union data{
    int n;
    char ch;
    short m;
};

int main(){
    union data a;
    printf("%d, %d\n", sizeof(a), sizeof(union data) );
    a.n = 0x40;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.ch = '9';
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.m = 0x2059;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.n = 0x3E25AD54;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
   
    return 0;
}

运行结果:

4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

上述代码不但验证了共用体的长度,还说明共用体成员之间会相互影响,修改一个成员的值会影响其他成员。更多

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
结构体、共用体和位运算是C语言中的重要概念。下面是对这些概念的介绍和演示: 1. 结构体(Structures): 结构体是一种用户自定义的数据类型,它可以包含多个不同类型的成员量。结构体的定义使用关键字`struct`,并且可以在其中定义多个员变量。结构体的成员变量可以是基本数据类型、数组、指针等。结构体的成员变量可以通过`.`运算符来访问。 ```c #include <stdio.h> // 定义一个结构体 struct Person { char name[20]; int age; }; int main() { // 创建一个结构体变量 struct Person person1; // 访问结构体的成员变量并赋值 strcpy(person1.name, "John"); person1.age = 25; // 输出结构体的成员变量 printf("Name: %s\n", person1.name); printf("Age: %d\n", person1.age); return 0; } ``` 2. 共用体(Unions): 共用体是一种特殊的数据类型,它允许在同一内存位置存储不同的数据类型。共用体的定义使用关键字`union`,并且可以在其中定义多个成员变量。共用体的成员变量共享同一块内存空间,因此修改其中一个成员变量会影响其他成员变量的值。共用体的成员变量可以通过`.`运算符来访问。 ```c #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 = 3.14; printf("data.f: %f\n", data.f); strcpy(data.str, "Hello"); printf("data.str: %s\n", data.str); // 输出共用体的不同成员变量 printf("data.i: %d\n", data.i); printf("data.f: %f\n", data.f); printf("data.str: %s\n", data.str); return 0; } ``` 3. 位运算(Bitwise Operations): 位运算是对二进制数进行操作的运算。常见的位运算操作符有与(`&`)、或(`|`)、异或(`^`)、取反(`~`)、左移(`<<`)和右移(`>>`)。位运算常用于对二进制数据的位进行操作,例如设置某一位的值、获取某一位的值等。 ```c #include <stdio.h> int main() { unsigned int a = 60; // 二进制表示为 0011 1100 unsigned int b = 13; // 二进制表示为 0000 1101 int result = 0; // 位与运算 result = a & b; // 二进制表示为 0000 1100 printf("a & b = %d\n", result); // 位或运算 result = a | b; // 二进制表示为 0011 1101 printf("a | b = %d\n", result); // 位异或运算 result = a ^ b; // 二进制表示为 0011 0001 printf("a ^ b = %d\n", result); // 位取反运算 result = ~a; // 二进制表示为 1100 0011 printf("~a = %d\n", result); // 左移运算 result = a << 2; // 二进制表示为 1111 0000 printf("a << 2 = %d\n", result); // 右移运算 result = a >> 2; // 二进制表示为 0000 1111 printf("a >> 2 = %d\n", result); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值