1.常量

程序在运行过程中 我们无法修改的数据 使用常量可以确保数据不会被改变。

1.1字面常量

数字常量  100

字符串常量  "ABCD"

字符常量   'A'

 1.2宏定义常量

#define 常量名 常量数据

#define MAX_LEVEL100

 2.变量

解释:程序在运行过程中,数据会发生改变的数据容器,就像是可以重复擦写的标签,数值的变化需要一个容器来存,怎么解释这个容器:我们需要向系统申请一个用来存放数据的空间,这个空间像一个盒子,给这个盒子起名(定义数据类型和数据名字,这个名字其实就是这个盒子在整个存储空间的地址),这样我们就可以把数据存放到这个盒子,也可以从盒子中取出数据。

3.数据类型

不同类型的数据需要不同的容器(也就是不同的空间)去存储(整数,小数,文字)。

3.1整型(存放整数)

短整型(short)

整型(int)

长整型(long) 

 3.2浮点型(存放小数)

单精度(float)

双精度(double)

 3.3字符型(存放单个字符)

char great  = a;

 4.运算符

一张图总结

 4.1基本运算符

+ - * /最基本的运算符 但是需要注意两点

1.对于+、-、*、/来说 如果操作符的两个操作数其中一个操作数是小数 则执行小数运算,如果都为整数 则进行整数运算。

2.%的两个操作数必须都为整数,否则会报错。

 4.2移位操作符

注意:<<是向左移位、>>是向右移位 移位操作符不能移动负数位

4.3位操作符

&表示都 两个条件都要满足

|表示或 有一个条件不行就不成立

^表示取反 ^的值和&的相反

 4.4赋值运算符

赋值运算符和符合运算符 = +=、-=、*=、/=、%=、>>=、<<=、&=、|=、^=

int a = 0;
int b = 8;
a+=b;			//相当于a = a+b   	所以a=8
a-=b;			//相当于a = a-b	因为a=8,a-b为0
//其他运算符同理,这种复合运算符可以使代码更加简洁

4.5单目操作符

! (逻辑反操作)

- (负值)

+ (正值)

& (取地址)

sizeof (操作数的类型长度(以byte为单位))

~ (对数值的二进制位取反)

- (前置后置- -)

++ (前置后置++)

* (解引用操作符)

 演示代码

#include <stdio.h>
int main()
{
int a = -10;
int *p = NULL;
printf("%d\n", !2);		//逻辑反操作,逻辑上一个值不是真就是假,非0即为真,!就是对一个数进行反操作2是真,!2即为假就是0
printf("%d\n", !0);		//0是假,!0为真,就是1
a = -a;					//原来的a为-10,-a就是10
p = &a;					//&就是取a的地址
printf("%d\n", sizeof(a));					//a的长度就是int类型的长度为4byte
printf("%d\n", sizeof(int));				//int的长度为4byte
printf("%d\n", sizeof a);                   //sizeof后面跟变量可以不写括号
return 0;
}
//++和--运算符
//前置++和--
#include <stdio.h>
int main()
{
	int a = 10;
	int x = ++a;
	//先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。
	int y = --a;
	//先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10;
	return 0;
}
//后置++和--
#include <stdio.h>
int main()
{
	int a = 10;
	int x = a++;
	//先对a先使用,再增加,这样x的值是10;之后a变成11;
	int y = a--;
	//先对a先使用,再自减,这样y的值是11;之后a变成10;
	return 0;
}
#include	<stdio.h>
int main()
{
    a = 10;
	int* b = &a;
    printf("%d",b);		//在c语言中我们常常会用到指针,如果不对其进行解引用,那么输出的值是a的地址。
    printf("%d",*b);	//解引用后值为10
}

int main()
{
    float a = 10.3;
    printf("%d",(int)a);	//在实际中如果某个数我们定义成一个类型,但是输出时又想用另一个类型输出,那么我们就可以对其进行强制类型转换,使其强转为你想要的值,但谨慎使用!!!容易出错!!!
}
#include <stdio.h>
void test1(int arr[])
{
    //这里arr被形参接手之后已经是首地址了,所以sizeof(arr)为8(在64位环境下,32位环境为4)
	printf("%d\n", sizeof(arr));		
}
void test2(char ch[])
{
    //同上,ch接受过来已经是首地址了,所以地址的大小为8(64位环境下,32位环境为4)
	printf("%d\n", sizeof(ch));
}
int main()
{
	int arr[10] = {0};
	char ch[10] = {0};
	printf("%d\n", sizeof(arr));		//整个数组的大小为40
	printf("%d\n", sizeof(ch));			//整个数组的大小为10
	test1(arr);
	test2(ch);
	return 0;
}

4.6关系运算符

​ >  >=  <  <=  !=(不等于) ==(等于)关系运算符就是进行比较,没什么太多细节,结果为真返回1,结果为假返回。

4.7逻辑运算符

&&(逻辑与) ||(逻辑或)

int main()
{
    printf("%d",1&2);		//0,对二进制进行与操作,对应的二进制位都为真,结果为真
    printf("%d",1&&2);		//1,对数值进行与操作,都为真,结果为真
    printf("%d",1|2);		//3,对二进制位进行或操作,对应的二进制位只要有一个为真,结果为真
    printf("%d",1||2);		//1,对数值进行或操作,只要有一方为真,结果为真
}

 4.8条件操作符

​ a ? b : c

int main
{
    if(a>10)
        b = 5;
    else
        b =	-1;
    
   //等价于
    a>10 ? b=5 : b=-1;
}

4.9逗号表达式

(a, b, c, …n)

逗号表达式只不过就是用逗号隔开的表达式 从左到右 依次执行 整个表达式的结果为最后一个表达式的结果 注意一定要用括号括起来。

int main()
{
    int a = 1;
    int b = 3;
    int c = (a++,b++,a+b);
    printf("%d",c);
    //c = 6 ,从左到右执行返回最右面的表达式
    //等价于
    //a++;
    //b++;
    //int c = a+b;
}

 4.10下标引用、函数调用和结构成员

​ []下标引用操作符  ()函数调用操作符   . 结构体   成员 -> 结构体指针->成员名

4.10.1[]下标引用

[ ] 需要两个操作数:数组名 [ 下标值 ]

int arr[10] = {0};		//定义数组
arr[8] = 8;   	//用于找到下标

4.10.2()操作数

()操作数最少要有一个函数名 剩下的操作数看形参的数量 : 函数名(形参1,形参2…)

void test()
{
    printf("asdfa");
}
void test(int a)
{
	printf("%d",a);
}
int main()
{
    int a=0;
    test();			//一个操作数 test
    test(a);		//两个操作数 test、a
    //以此类推还可以有很多操作数,由形参的数量决定
}

4.10.3访问结构体的操作符

. 和->访问结构体

struct Stu
{
	char name[10];
	int age;
};
void set_age1(struct Stu stu)
{
	stu.age = 18;
}
void set_age2(struct Stu* pStu)
{
	pStu->age = 18;				//结构成员访问
}
int main()
{
	struct Stu stu;
    struct Stu* pStu = &stu;	//结构成员访问
	stu.age = 20;				//结构成员访问
	set_age1(stu);
	pStu->age = 20;				//结构成员访问
	set_age2(pStu);
	return 0;
}

5.if语句

5.1基本用法

示例代码

if (条件表达式) {
    // 条件为真时执行的代码
}

int age = 18;
if (age >= 18) {
    printf("已成年\n");
}
//------------------------------------------------------------------------------
if (条件表达式) {
    // 条件为真时执行
} else {
    // 条件为假时执行
}

int score = 85;
if (score >= 60) {
    printf("及格\n");
} else {
    printf("不及格\n");
}
//-----------------------------------------------------------------------------
if (条件1) {
    // 条件1为真时执行
} else if (条件2) {
    // 条件2为真时执行
} else {
    // 所有条件均不满足时执行
}

int score = 75;
if (score >= 90) {
    printf("优秀\n");
} else if (score >= 80) {
    printf("良好\n");
} else if (score >= 60) {
    printf("及格\n");
} else {
    printf("不及格\n");
}
//------------------------------------------------------------------------------

5.2进阶用法

5.2.1如果代码块只有一行,可以省略 {}



if (条件) printf("条件成立\n");

 5.2.2可以在 if 条件中赋值,并检查赋值后的值



int num;
if ((num = get_value()) > 0) {  // 赋值并判断
    printf("num = %d\n", num);
}

 5.2.3组合条件

&&(逻辑与):所有条件必须同时成立。

||(逻辑或):任意一个条件成立即可。

!(逻辑非):取反条件。

int age = 20;
bool is_student = true;

if (age >= 18 && is_student) {
    printf("成年学生\n");
}

if (age < 12 || age > 65) {
    printf("可享受优惠\n");
}

if (!is_student) {
    printf("非学生\n");
}

 5.2.4三目运算符(?:)

替代简单 if-else 如果只是简单的条件赋值,可以使用三目运算符


int a = 10, b = 20;
int max = (a > b) ? a : b;  // 等效于 if-else

 6.switch语句

6.1基本用法

switch (表达式) {
    case 常量1:
        // 代码块1
        break;
    case 常量2:
        // 代码块2
        break;
    default:
        // 默认代码块(可选)
}

int day = 3;
switch (day) {
    case 1: printf("周一\n"); break;
    case 2: printf("周二\n"); break;
    case 3: printf("周三\n"); break;
    default: printf("无效日期\n");
}

 6.2进阶用法

6.2.1case 穿透(Fall-through)

故意省略 break 让多个 case 执行同一段代码

int month = 2;
switch (month) {
    case 1:
    case 3:
    case 5:
        printf("31天\n"); break;
    case 2:
        printf("28天\n"); break;
    default:
        printf("30天\n");
}

 6.2.2switch 嵌套


switch (x) {
    case 1:
        switch (y) {
            case 10: printf("x=1, y=10\n"); break;
        }
        break;
}

7.for循环

7.1基本用法

for (初始化; 条件; 更新) {
    // 循环体
}

for (int i = 0; i < 5; i++) {
    printf("%d ", i);
}

7.2进阶用法

7.2.1无限循环


for (;;) {  // 相当于 while(1)
    printf("无限循环\n");
}

7.2.2多变量循环


for (int i = 0, j = 10; i < j; i++, j--) {
    printf("i=%d, j=%d\n", i, j);
}

7.2.3遍历数组


int arr[] = {1, 2, 3};
for (int i = 0; i < 3; i++) {
    printf("%d ", arr[i]);
}

8.while循环

8.1基本用法

先判断条件,再执行循环体(可能一次都不执行)


while (条件) {
    // 循环体
}


int i = 0;
while (i < 5) {
    printf("%d ", i++);
}

8.2进阶用法

8.2.1break 和 continue

break:立即退出循环 continue:跳过本次循环,进入下一次。


int i = 0;
while (i < 10) {
    i++;
    if (i == 5) break;     // 当 i=5 时退出循环
    if (i % 2 == 0) continue;  // 跳过偶数
    printf("%d ", i);
}

8.2.2while 读取输入


char ch;
while ((ch = getchar()) != '\n') {  // 读取字符直到回车
    printf("%c", ch);
}

9.do-while

9.1基本用法

先执行循环体,再判断条件(至少执行一次)

do {
    // 循环体
} while (条件);

int i = 0;
do {
    printf("%d ", i++);
} while (i < 5);

9.2进阶用法

在宏定义中使用 do-while(0) 可以避免宏展开时的语法错误


#define SAFE_PRINT(msg) do { \
    printf("%s\n", msg); \
    log_to_file(msg); \
} while (0)

// 调用
if (flag)
    SAFE_PRINT("Hello");  // 宏展开后不会因缺少大括号而出错

10.数组

数组是由基本数据类型按照一定规则组成的,称其为构造数据类型。

构造数据类型包括数组,结构体,共用体等,使用构造数据类型可以求解更为复杂的问题。

数组是最基本的构造类型,是相同类型数据的有序集合。

数组中的元素在内存中连续存放,用数组名和下标可以唯一地确定数组元素。

10.1定义与初始化

10.1.1一维数组

// 定义数组(未初始化)
int arr1[5];  // 包含5个int元素的数组

// 定义并初始化
int arr2[3] = {1, 2, 3};  // 完全初始化
int arr3[] = {1, 2, 3};   // 自动推断长度为3
int arr4[5] = {0};        // 全部初始化为0

 10.1.2二维数组

#include <stdio.h>
#include <stdlib.h>  // 用于动态内存分配

int main() {
    // 1. 静态初始化(固定大小)
    int static_matrix[3][4] = {
        {1, 2, 3, 4},    // 第一行
        {5, 6, 7, 8},    // 第二行
        {9, 10, 11, 12}  // 第三行
    };

    // 2. 部分初始化(未初始化的元素自动为0)
    int partial_matrix[3][4] = {
        {1, 2},      // 第一行:1,2,0,0
        {5, 6, 7},   // 第二行:5,6,7,0
        {9}         // 第三行:9,0,0,0
    };

    // 3. 连续内存初始化(编译器自动填充)
    int flat_matrix[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

    // 4. 动态分配(运行时确定大小)
    int rows = 3, cols = 4;
    int **dynamic_matrix = (int **)malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++) {
        dynamic_matrix[i] = (int *)malloc(cols * sizeof(int));
        // 可选:初始化动态分配的内存
        for (int j = 0; j < cols; j++) {
            dynamic_matrix[i][j] = i * cols + j + 1;  // 示例数据
        }
    }

    // 打印示例(静态数组)
    printf("Static matrix:\n");
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%2d ", static_matrix[i][j]);
        }
        printf("\n");
    }

    // 释放动态内存
    for (int i = 0; i < rows; i++) {
        free(dynamic_matrix[i]);
    }
    free(dynamic_matrix);

    return 0;
}

10.2访问数组元素

打印数组元素

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};  // 定义并初始化数组
    int size = sizeof(arr) / sizeof(arr[0]);  // 计算数组长度

    printf("数组元素为:");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

数组名是元素的首地址

int arr[3] = {1, 2, 3};
int *p = arr;       // p指向arr[0]
printf("%d\n", *p); // 输出: 1

数组作为函数参数

void printArray(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
}

int main() {
    int arr[] = {1, 2, 3};
    printArray(arr, 3);  // 输出: 1 2 3
}

动态数组(堆内存分配)

int *arr = (int *)malloc(5 * sizeof(int));  // 分配5个int的空间
if (arr != NULL) {
    arr[0] = 10;  // 使用
    free(arr);     // 释放内存
}

10.3数组的常见操作

10.3.1遍历数组

int arr[] = {1, 2, 3};
for (int i = 0; i < 3; i++) {
    printf("%d ", arr[i]);
}

 10.3.2排序

void bubbleSort(int arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
//冒泡排序

 10.3.3查找

int linearSearch(int arr[], int size, int target) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == target) {
            return i;  // 返回下标
        }
    }
    return -1;  // 未找到
}
//线性查找

11.函数

C语言中的函数是一段独立的代码块,用于执行特定的任务。函数可以接受输入参数,执行一系列操作,并返回结果。

11.1函数定义

返回类型 函数名(参数列表) {
    // 函数体
    return 返回值; // 非void类型必须返回
}

int add(int a, int b) {
    return a + b;
}

11.2函数声明与调用


返回类型 函数名(参数类型列表);

int add(int, int); // 声明

int result = add(3, 5); // 调用

11.3参数的传递

//值传递(默认方式)

void modify(int x) {
    x = 10; // 不影响实参
}
//指针传递(地址传递)

void modify(int *x) {
    *x = 10; // 修改实参的值
}
//数组参数

void printArray(int arr[], int size) {
    // 数组名退化为指针
}

11.4函数的返回值

//基本类型返回

int getValue() {
    return 42;
}

//返回指针

int* createArray(int size) {
    int *arr = malloc(size * sizeof(int));
    return arr;
}

//无返回值(void)

void printHello() {
    printf("Hello\n");
}

 11.5函数特性

//递归函数

int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

//内联函数(C99)

inline int max(int a, int b) {
    return a > b ? a : b;
}

// 可变参数函数

#include <stdarg.h>
int sum(int count, ...) {
    va_list args;
    va_start(args, count);
    int total = 0;
    for (int i = 0; i < count; i++) {
        total += va_arg(args, int);
    }
    va_end(args);
    return total;
}

11.6指针函数

//定义函数指针

int (*funcPtr)(int, int); // 指向返回int,接受两个int的函数

//使用函数指针

funcPtr = add; // 指向add函数
int result = funcPtr(3, 5); // 通过指针调用

//回调函数

void process(int (*callback)(int)) {
    int result = callback(10);
    // 处理结果
}

11.7作用域规则


void func() {
    int x = 10; // 局部变量
}

int global = 100; // 全局变量

void func() {
    global++; // 可访问
}

void counter() {
    static int count = 0; // 只初始化一次(静态变量)
    count++;
}

12.指针(C语言灵魂)

12.1什么是指针?

指针是一个存储内存地址的变量。它指向内存中的某个位置,通过这个地址可以访问或修改该位置的数据。

int a = 10;    // 在酒店开一个房间(房间号是a),让10先生入住(这个房间是int型单人房)
int *p = &a;   // p是一个特殊的遥控器,它存储的是房间a的房卡信息
  • &:取地址运算符

  • *:解引用运算符(通过地址访问值)

做个比喻

整个计算机内存就像一个大酒店

每个变量(如a)就是酒店里的一个房间

每个房间都有唯一的门牌号(内存地址)

10就是住在房间a里的客人

房间类型int表示这是单人房(只能住一个整数客人)

p是一个特殊的遥控器

&a操作相当于查询房间a的门牌

int *p = &a;表示:把房间a的门牌号存储到遥控器p里 这个遥控器专门用于开a房间的门

当10先生要退房时:用p遥控器开门让10先生离开

当11先生要入住时:用p遥控器开门让11先生住进去

*p = 11; // 用遥控器p开门,让11先生入住

现在房间a里住的是11先生(a的值变为11)

 此外,在简单说一下int *p 和*p的分别是什么。

  • int *p:声明一个指针变量 p(它专门用于存储 int 类型数据的地址)

  • *p:解引用操作(访问 p 指向的内存位置的实际值)

int a = 10;    
int *p = &a;  

printf("%p", p);  // 输出a的房间号(地址)
printf("%d", *p); // 输出开门取出的值:10

*p = 11; // 用遥控器p开门,让11先生入住

 12.2指针三要素

12.2.1指针的类型

int *p;      // p的类型是 int*
char *cp;    // cp的类型是 char*
double *dp;  // dp的类型是 double*

12.2.1指针所指向的类型

指针类型只能指向同一种类型,void* 可以指向任何一种类型。

指针声明            指针类型          指向类型
int *p                       int*                  int
char **pp                char**             char*
int (*func)(void)    函数指针        函数类型

int num = 10;
void *vp = &num; // 合法

// 但解引用前必须转换类型
printf("%d\n", *(int*)vp);

12.2.1指针的值

指针存储的实际内存地址值,决定了:

  1. 指针指向的内存位置

  2. 指针是否有效(NULL或野指针)

比如

int num = 10;
printf("%p\n", (void*)&num);

需要注意几点

说明
NULL 空指针,指向地址0
未初始化值 野指针(危险)
已释放内存地址 悬空指针(危险)

 12.3指针的算数运算

数组名是数组的首地址!!!

int arr[3] = {10, 20, 30};
int *ptr = arr;

printf("%d\n", *ptr);   // 10
printf("%d\n", *(ptr + 1)); // 20(移动4字节,int大小)

12.4函数指针

int add(int a, int b)
{
  return a + b;
}

int (*funcPtr)(int, int) = add; // 函数指针(函数单独内存占用一段空间,把函数的地址赋给函数指针)

printf("%d\n", funcPtr(2, 3)); // 输出: 5

12.5指针的类型转换

指针类型转换不改变内存中的实际数据,只改变编译器解释这些数据的方式

目标类型 *指针名 = (目标类型 *)原指针;

int num = 0x12345678;  // 4字节整数
int *ip = &num;
char *cp = (char*)&num; // 转换为char指针

printf("%x\n", *ip);   // 输出: 12345678
printf("%x\n", *cp);   // 输出: 78 (小端序)

注意事项

转换类型 安全性 使用场景
T* → void* 安全 泛型编程
void* → T* 较安全 恢复具体类型
T* → U* 危险 低级内存操作
函数指针转换 非常危险 系统编程
整数指针互转 极端危险 硬件操作

 13.结构体

13.1什么是结构体

结构体是C语言中自定义复合数据类型的核心工具,允许将多个不同类型的数据组合成单一实体。它在数据封装、内存管理和系统编程中至关重要。

 13.1.1结构体定义


struct Point {   // 定义结构体类型
    int x;       // 成员变量
    int y;
};              // 注意分号

13.1.2结构体变量声明


// 方式1:独立声明
struct Point p1;

// 方式2:定义时声明
struct Point {
    int x;
    int y;
} p2, p3;       // 同时声明p2和p3

13.1.3结构体初始化


// 顺序初始化
struct Point p1 = {10, 20};

// 指定成员初始化(C99)
struct Point p2 = {.x = 5, .y = 15};

// 结构体数组初始化
struct Point points[3] = {
    {1, 2}, 
    {3, 4}, 
    {5, 6}
};

13.2结构体的基础结构

13.2.1先定义结构体类型,在定义结构体变量

 struct   student //结构体类型 或 结构体名
{       
 int num;
 char  name[20];     //结构体成员
 char sex;
 int age; 
 float score;
 char addr[30];
 };
 struct student stu1,stu2;       //结构体变量

13.2.2定义结构体的同时定义变量

 struct   data   // 结构体类型 或结构体名
 {      
  int day int month;   //结构体成员
  int year
 }time1,time2;   //结构体变量

13.2.3直接定义结构体变量

 struct     // 结构体类型
{
 char name[20];
 char sex; 
 int num;        //结构体成员
 float score[3] 
 }person1,person2;  //结构体变量 

注意事项

只有结构体变量才分配地址,而结构体的定义是不分配空间的

结构体中各成员的定义和之前的变量定义一样,但在定义时也不分配空间

结构体变量的声明需要在主函数之上或者主函数中声明,如果在主函数之下则会报错

 13.3结构体操作

13.3.1成员访问

struct Student {
    char name[20];
    int age;
};

struct Student s;
strcpy(s.name, "Alice");  // 使用.访问成员
s.age = 20;

13.3.2 结构体指针

struct Student *ptr = &s;
printf("Name: %s\n", ptr->name);  // 使用->访问指针成员
ptr->age = 21;

13.3.3.结构体赋值

struct Point a = {1, 2};
struct Point b = a;  // 合法!C语言支持结构体整体复制

13.4结构体的基本用法

13.4.1结构体嵌套


struct Date {
    int year;
    int month;
    int day;
};

struct Person {
    char name[20];
    struct Date birthday;  // 嵌套结构体
};

struct Person alice = {
    "Alice", 
    {2000, 5, 20}  // 嵌套初始化
};

13.4.2结构体与函数

// 传值(产生副本)
void printPoint(struct Point p) {
    printf("(%d, %d)\n", p.x, p.y);
}

// 传指针(高效)
void movePoint(struct Point *p, int dx, int dy) {
    p->x += dx;
    p->y += dy;
}

13.4.3结构体包含数组

struct Matrix {
    int rows;
    int cols;
    double data[3][3];  // 固定大小数组
};

13.4.4动态结构体

struct Student *createStudent(const char *name, int age) {
    struct Student *s = malloc(sizeof(struct Student));
    if (s) {
        strncpy(s->name, name, sizeof(s->name)-1);
        s->age = age;
    }
    return s;
}

// 使用后需free()

13.5结构体与共用体(Union)

共用体本质

  • 所有成员共享同一块内存

  • 大小由最大成员决定

  • 同一时间只能使用一个成员

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

struct Variant {
    int type;  // 类型标识
    union {
        int intValue;
        float floatValue;
        char *stringValue;
    } data;    // 共用体成员
};

13.6结构体与其他类型对比

特性 结构体(struct) 数组(array) 共用体(union)
成员类型 可以不同 必须相同 可以不同
内存占用 所有成员之和+填充 元素类型×数量 最大成员的大小
同时访问成员 支持 支持 一次只能访问一个成员
主要用途 数据聚合 同质数据集合 类型转换/节省内存

 14.内存管理

暂无笔记

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐