当前位置: 首页 > news >正文

C语言 - 智谱


第一阶段:夯实基石 —— 数据在内存中的真实面貌

OS是管硬件的,你必须清楚C语言的每一种数据在内存里到底占多少空间。

  • 1. 基础数据类型的尺寸与对齐
    • 知识点:char (1字节)、short (2字节)、int (4字节)、long/指针 (在32位系统是4字节,在64位系统是8字节,这个极其重要)。
    • OS关联:OS在分配内存页(通常4KB)、划分内核数据结构时,对字节数极其敏感。
  • 2. 整数的unsigned与signed本质
    • 知识点:计算机底层没有符号之分,全是补码。unsigned 的溢出是回绕(比如 0 - 1 会变成极大的正数)。
    • OS关联:内核中大量的计数器、时间戳、物理地址,全都是 unsigned,因为物理地址不可能为负数。
  • 3. 枚举与宏常量
    • 知识点:enum 的本质就是整型;#define 的纯文本替换。
    • OS关联:OS中充满了状态机。比如进程状态:TASK_RUNNING = 0, TASK_INTERRUPTIBLE = 1。内核源码里极少用硬编码的数字,全是宏和枚举。

第二阶段:灵魂核心 —— 指针与内存地址的绝对控制

上一节课我们入门了指针,为了看OS源码,你需要掌握指针的进阶形态。

  • 1. 指针的类型与步长(指针运算)
    • 知识点:int *p + 1 实际上地址加了4;char *p + 1 地址加1。
    • OS关联:遍历页目录表、进程描述符链表时,全靠指针加减法来移动。
  • 2. void * 泛型指针
    • 知识点:void * 可以接收任意类型的地址,但不能直接解引用(因为不知道它指向多大空间)。
    • OS关联:内核最爱用的指针! 比如内核的 kmalloc() 分配内存函数,返回的就是 void *,因为内核分配时根本不管你要存int还是存结构体,只管给你一块纯净的内存地址。
  • 3. 函数指针
    • 知识点:指向代码区(函数)的指针,可以通过指针调用函数。
    • OS关联:这是OS实现“多态”和“回调”的唯一手段。比如Linux内核中的中断向量表文件系统的VFS(虚拟文件系统),就是用一堆函数指针数组实现的(struct file_operations 里面全是函数指针)。
  • 4. 指针与数组彻底等价
    • 知识点:a[i] 完全等价于 *(a + i)
    • OS关联:内核中绝对不会用数组下标去访问大块内存,全是用指针解引用,因为指针解引用生成的汇编代码更短、更快。

第三阶段:捏泥巴 —— 手工组装数据结构(结构体进阶)

OS是由无数个庞大的结构体组成的(比如Linux的 task_struct 进程控制块有几百行)。

  • 1. 结构体(struct)的声明与指针引用
    • 知识点:用 -> 运算符通过指针访问结构体成员(p->name 等价于 (*p).name)。
    • OS关联:内核中传递实体太浪费栈空间,传递结构体指针是唯一做法,所以源码里满天飞的都是 ->
  • 2. 结构体内存对齐
    • 知识点:编译器会在结构体内部塞入空白字节,让数据按其自身大小对齐(比如4字节的int必须放在4的倍数地址上)。
    • OS关联:极其重要! 因为CPU读内存是按块读的,不对齐会导致性能下降甚至硬件异常。OS设计结构体必须精心排布成员顺序来节省内存。
  • 3. 联合体(union
    • 知识点:所有成员共享同一块内存空间,同一时间只能用一个。
    • OS关联:常用于“类型强转”的优雅替代。比如,想看一个32位整数的最高8位是什么,不用去移位,直接定义一个union包含 intchar[4],直接读char即可。
  • 4. 位域
    • 知识点:在结构体里,用冒号指定某个成员占几个 bit(如 unsigned int mode : 3;)。
    • OS关联:硬件的寄存器控制字都是按位划分的(比如第0-1位控制电源状态,第3位控制中断)。OS通过位域直接映射硬件寄存器,极度节省空间。

第四阶段:直击硬件 —— 位操作与底层修饰符

这是C语言能写OS的根本原因:C语言能直接操作二进制位,并能干预编译器的行为。

  • 1. 纯熟掌握位操作符
    • 知识点:& (清零/屏蔽)、| (置位)、^ (翻转)、~ (取反)、<< (左移,相当于乘2)、>> (右移)。
    • OS关联:每天的日常。比如要把一个寄存器的第3位置1:reg |= (1 << 3);把第3位清0:reg &= ~(1 << 3)。操作系统的页表项(PTE)全是用位操作设置的。
  • 2. volatile 关键字(极其关键)
    • 知识点:告诉编译器:“这个变量的值可能会在你看不见的地方改变,绝对不准优化,每次必须老老实实去内存里重新读!
    • OS关联:
      1. 内存映射I/O(MMIO): 当OS要读写外设(如网卡、串口)时,外设的寄存器被映射到内存地址。OS读写这个地址,实际上是在跟物理硬件通信,硬件会自己改变里面的值,编译器不知道,不用 volatile 就会读出脏数据。
      2. 多线程/中断: 中断服务程序可能会修改主程序里的变量,也必须加 volatile
  • 3. 内联汇编基础(了解即可)
    • 知识点:在C代码中嵌入 asm volatile("...")
    • OS关联:有些操作C语言做不了,比如关中断、读写特定的控制寄存器(CR0, CR3),必须用汇编。OS中C和汇编是混合编写的。

第五阶段:内存的底层真相 —— 变量的生命周期

OS本身就是一个“内存分配器”,你必须知道C语言程序的内存是怎么划分的。

  • 1. 全局变量/静态变量(.data.bss 段)
    • 知识点:在程序编译时就确定了大小,存在于整个程序生命周期。
    • OS关联:内核里的全局配置、驱动程序的全局状态,都放在这里。
  • 2. 局部变量(栈区 Stack)
    • 知识点:函数调用时分配,函数结束时销毁。由CPU的栈指针(ESP/RSP)自动管理。
    • OS关联:OS需要为每个进程/线程分配独立的“内核栈”。理解栈溢出对写内核驱动极其重要。
  • 3. 动态内存(堆区 Heap)
    • 知识点:mallocfree
    • OS关联:不要只知道用 malloc你要去思考 malloc 底层是怎么实现的? 它实际上是向操作系统申请内存(通过系统调用如 brkmmap)。学习OS,就是要去实现 malloc 背后的那个分配器(比如伙伴系统、Slab分配器)。

第六阶段:C语言的编译与链接(连接OS的桥梁)

OS源码不是一整个文件,而是成千上万个 .c 文件编译链接而成的。

  • 1. 预处理与条件编译
    • 知识点:#ifdef, #ifndef, #if
    • OS关联:Linux内核要支持几十种CPU架构(x86, ARM, RISC-V),怎么做到一份代码兼容所有硬件?全靠条件编译。比如:#ifdef CONFIG_X86 ... #elif CONFIG_ARM ...
  • 2. 链接器脚本基础
    • 知识点:了解C语言编译后的 .text(代码段)、.rodata(只读数据段)、.data(数据段)。
    • OS关联:写OS时,你需要告诉链接器:“把我的内核代码放在内存的 0x100000 地址,把我的栈放在 0x900000 地址”。这需要写特殊的 .ld 链接脚本。

第七阶段:脱离标准库生存

在应用层,我们用 printf 打印,用 fopen 读文件。
但在刚写出的OS内核里,根本没有标准库(没有stdio.h),你什么都没有!

  • 1. 字符串的底层本质
    • 知识点:字符串就是以 \0 结尾的字符数组。
  • 2. 手写底层基础函数
    • 知识点:自己实现 strlen, strcpy, strcmp, memset, memcpy
    • OS关联:Linux内核源码里有一个专门的文件夹叫 lib/,里面全是内核自己实现的字符串和内存拷贝函数,因为内核不能依赖外部的C标准库。
  • 3. 可变参数函数
    • 知识点:stdarg.h 里的 va_list, va_start, va_arg 宏。
    • OS关联:内核里也要打印日志(如 printk),所以你必须知道 printf 是怎么做到接收 "hello %d", num 这种不定参数的。
http://www.jsqmd.com/news/681714/

相关文章:

  • Photon-GAMS光影包:让你的Minecraft画面实现电影级飞跃的完整指南
  • 从PCF8591电压检测到通用报警系统设计:蓝桥杯IIC应用背后的编程思维
  • AutoSubs架构深度解析:本地AI字幕生成的技术革命
  • 2026西安企业搬家哪家好?双生新时代领航,技术市场双维度考量 - 深度智识库
  • 好用又能打!建筑机器人哪家技术实力更顶? - 行业深度观察
  • C语言学习笔记 - 4.C概述 - C的特点
  • BetterNCM-Installer:3步解决网易云音乐PC版插件安装难题
  • 别再被SystemExit: 2搞懵了!Python argparse在Jupyter Notebook里的正确打开方式
  • 告别LabelImg和Labelme?深度对比CVAT与主流标注工具,帮你选对2024年的标注平台
  • 今日学习--MySql
  • 告别照搬代码:用STM32CubeMX重新理解正点原子OV2640驱动的DCMI与DMA配置逻辑
  • STM32F103ZET6串口调试翻车实录:换了串口助手才解决,德飞莱尼莫M3S开发板避坑指南
  • 断舍离新方式,盘活你手里闲置的大润发购物卡 - 团团收购物卡回收
  • 如何构建智能四足机器人:openDogV2完整实战指南与深度技术解析
  • 最长有效括号-leetcode
  • Linux进程间通信新姿势:用sigaction和sigqueue实现带数据的信号传递(C语言实战)
  • 别再死记硬背了!手把手带你用UVM实战AHB2APB Bridge验证(附完整代码与面试高频题解析)
  • 从表情包到技术栈:用C语言和libgif库手把手解析一个GIF文件(附完整源码)
  • 从加工到仿真:手把手教你解读光学面形检测报告与Zemax波前分析结果
  • 专业的江门口腔医院 - 行业深度观察
  • 车间参观通道设计公司怎么选?从惟妙设计看现代工厂视觉升级的“隐形工程” - 企师傅推荐官
  • 2026贵阳装修公司深度横评:旧房改造与室内装修哪家好 - 年度推荐企业名录
  • 【技术图解】一图胜千言:用生活场景彻底搞懂TP/FP/TN/FN!
  • 2026年京津冀地区夹胶玻璃靠谱供应商有哪些,哪家口碑好 - 工业品牌热点
  • 那些被你放过期的微信立减金,其实能变成实打实的零钱 - 团团收购物卡回收
  • 2026年贵阳装修公司对比:绿豆家装vs华浔品味vs生活家vs乐享装饰全面评测 - 年度推荐企业名录
  • 从SVM到投资组合:拉格朗日乘子法在机器学习与金融中的三个实战案例解析
  • 告别内存碎片:用JeMalloc优化你的C++服务端程序(附性能对比测试)
  • 沙河市润都金属制品可信度高吗,山东市场口碑排名情况 - 工业品牌热点
  • Android动画观影终极指南:Hanime1Plugin如何彻底改变你的追番体验