C语言15-构造数据类型、位运算符、内存管理

发布于:2025-07-31 ⋅ 阅读:(17) ⋅ 点赞:(0)

摘要:文章系统介绍了C语言中结构体、共用体、枚举和位运算等核心概念。重点讲解了结构体的定义、初始化、内存对齐规则及传参方式;对比了共用体与结构体的存储差异;阐述了枚举类型的特性及位运算符的使用场景。同时涵盖了堆区内存管理、内存泄漏等关键问题,通过示例代码演示了各种数据结构的实际应用,为C语言开发者提供了全面的参考指南。

一、结构体

1、结构体类型定义

                struct 结构体名 {
                        数据类型1 成员变量1;
                        数据类型2 成员变量2;
                        数据类型3 成员变量3;
                                ...
                 };

2、结构体元素初始化

(1)全部初始化:struct student stu = {"zhangsan", 'm', 18, 90};

(2) 局部初始化:没有给定初值的元素都被赋值为0

        struct student stu = {
                .name = {"zhangsan"},
                .score = 90,
        };

3、 结构体成员访问

.    :结构体变量类型访问成员变量 .
->  :结构体指针类型访问成员变量 ->


结构体访问成员变量最终的类型由成员变量的类

4、结构体的存储(内存对齐)

(1)结构体成员必须存放在内存地址为自身类型长度整数倍的内存单元中

(2)结构体的大小必须为自身最大类型长度的整数倍

(3)示例:

struct student {
        char name[32];        //1字节
        char sex;                 //1字节(下面4个字节,借3个字节构成4个字节)
        int age;                    //4字节
        int score                  //4字节
};

共13字节

5、结构体的传参

- 传地址更好,因为实参将8字节拷贝给形参,避免结构体大空间的拷贝

(1)传值

void fun(struct student tmp)

(2)传地址

void fun(struct student *ptmp)

6、示例

(1)示例1:

(2)示例2:

二、结构体数组

1、结构体数组基本形式

数据类型 数组名[元素个数];                //数组元素个数必须是常量

2、结构体数组初始化 

struct student s[3] = {
         {"zhangsan", 'm', 19, 100},
         {"lisi", 'f', 18, 90},
         {"wanger", 'm', 19, 60},
};

struct student s[3] = {
           [1] = {
                        .name = "zhangsan",
                        .score = 90,
                     },
};

3、 结构体数组传参

int fun(struct student *pstu, int len);

4、示例 

三、共用体

1、共用体基本形式

union 共用体名 {
        数据类型1 成员变量1;
        数据类型2 成员变量2;
        数据类型3 成员变量3;
        ...
};

2、共用体使用概要

 (1)共用体也称为联合体

(2)共用体每个成员变量的空间共享的

(3)结构体每个成员变量的空间是独立的

(4)多用于函数传参使用

3、利用共用体判断内存大小端

(1)内存低地址存放低数据位,内存高地址存放高数据位,内存小端

(2)内存低地址存放高数据位,内存高地址存放低数据位,内存大端

(3)基本示例形式

#include <stdio.h>
union s {
        char a;
        int b;
};
int main(void)
{
        union s s1;


        s1.b = 1;
        if(s1.a)
        printf("小端存储\n");
        else
        printf("大端存储\n");


        return 0;
}

(4)代码实现

四、枚举

1、枚举定义

        枚举定义一些枚举变量

2、枚举基本形式

enum 枚举类型 {
        常量1,
        常量2,
        常量3,
...
};

3、枚举特性

(1)枚举常量均为int类型,且第一个枚举常量的值默认为0,后续枚举常量的值总是前一个常量的值+1;

(2)枚举常量可以在定义时被赋值;

4、示例1

        常量1默认为0,也可以赋值,其后的常量的值在赋值基础上加1;

        switch 的‘  :’后没有条件会顺移直至有条件,所以条件相同时就可以写成下面所示;

示例2:

        一次只能接受一个数据,被再次赋值后之前那个数据便会消失,所以打印出来的是随机值或者乱码;

五、位运算符

1、位运算符

运算符 含义 作用
& 按位与 有0则0
| 按位或 有1则1
^ 按位异或 同为0异为1
~ 按位取反 取反
<< 左翼 放大数(放大2^n倍)
>> 右移 缩小数(所需2^n倍)

2、位运算符优先级

        移位运算符优先级高于其余位运算符

3、位运算符使用场景

(1)将一个数据第n位置1:        num |= (1 << n);

(2)将一个数据某位置0:          num &= ~(1 << n);

4、三种数据置换的方法

(1)不使用中间tmp的按位异或法

(2)使用中间变量tmp

(3)sum和减法

六、内存管理

1、C语言运行划分的数据段

2、堆区空间操作

(1)malloc函数:

        功能:申请一段堆区空间

        返回值:成功返回申请堆区空间首地址,失败返回NULL

(2)free函数:

         功能:释放空间

3、内存泄漏

(1)只申请空间,使用完毕,不释放空间,导致可用空间越来越少,这样就会产生内存泄漏。内存不足程序就会崩溃。

4、示例

(1)*p = ''hello" 只是将字符串中第一个元素‘h’赋值给了*p,这在字符串中是不可取的

(2) p = "hello'' 将字符串地址给了p,但是之前那个p地址将消失找不到,将无法释放空间


网站公告

今日签到

点亮在社区的每一天
去签到