网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
12月16日漏签0天
c语言吧 关注:801,523贴子:4,373,600
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 1 2 下一页 尾页
  • 26回复贴,共2页
  • ,跳到 页  
<<返回c语言吧
>0< 加载中...

c 语言源码探索之 linux 的创始人林纳斯的编辑器

  • 只看楼主
  • 收藏

  • 回复
  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
我们当然知道linux是c语言项目中最强的项目工程了,但是大家想过没有这么强的工程是用什么软件开发的呢?
VS studio? Vs code? Emacs? Vim? 都不是大名顶顶的linus使用的是一个简陋到了极点编辑器,没有代码高亮,没有自动补全,甚至没有撤销Ctrl-Z!这个编辑器叫uemacs,(https://github/torvalds/uemacs)这个工程只有36个c文件!17000行c代码。下了代码,10秒不到就编译完了整个项目,生成的二进制只有500K!连1M也没有,就是这个编辑器带来了linux世界!

进入项目,最简单的是一个Makefile,Makefile是c世界中常见的项目管理方案,在这里按下make,项目就开始了编译过程。uemacs是一个TUI编辑器,他是跑在命令行里的,可能很多人的观念是命令行就是scanf,然后读取一行,打印输出,命令行不只是这样用的!或者说命令行其实是一个小白的说法!它的真正名字叫做终端(terminal), 终端在以前是一个巨大的实体物理设备,程序会跟终端通信,读取输入以及输出字符(stdin以及stdout),但是后来随着图形界面的流行,终端就退出了历史舞台。但是虚拟终端一直都在,它变成了windows的那黑乎乎以及ubuntu那紫乎乎的命令行。虚拟终端完全虚拟了以前的实体终端,所以以前的上古程序今天也能跑。包括今天介绍的uemacs!

但是终端的有一问题是,终端有很多版本,不同类型的终端控制不一样。很多现代的c++程序员可能想到可以用多态,用虚类,用接口!但是这里是c,我们只需要函数指针!下面是uemacs的“终端接口”,可以看到所有"virtual"方法都被抽象化成了函数指针,这个结构体是一个抽象的终端!可以看到这个终端有启动,关闭,获取字符,以及写入字符的方法。uemacs程序的逻辑就是一个个字符从终端中读取,根据状态上下移动光标或者输出字符到显示器中。

这个接口的unix的实现实现在tcap.c,在具体实现中用到了一个外部库"#include <curses.h>",
这个是一个外部的终端库,如果c语言的爱好者想要在终端中做一个小游戏不妨也去了解下。
不过windows的使用者应该去了解ncurse,这个跨平台的版本。


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
源码链接打错了 https://github.com/torvalds/


2025-12-16 12:18:00
广告
不感兴趣
开通SVIP免广告
  • 神马大泥
  • 麻婆豆腐
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
大佬厉害


  • 笔盖-丢失者
  • 异能力者
    6
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
非常好科普,使我大脑旋转


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
介绍了终端,很多有经验的人应该知道了,这个程序应该是一个巨大的循环,读取用户按键输入,对按键输入进行处理,改变屏幕的状态。这么想程序会不会有BUG呢,有!如果用户输入太快了怎么办呢,用户输入的速度比程序处理速度还快,那么按键就会一直堆积,形成卡死。看看uemacs是怎么解决这个问题?
uemacs解决方法是建立一个输入缓冲区,每次读取输入,如果缓冲区有很多待处理的按键(使用typahead() 检测 ),那么只处理最新的按键,其他全部忽略!但是有例外,如果用户输入的是很多换行键或者tab键,因为这些处理比较快,所以就不忽略了。下图是代码,看出来使用了宏来控制是否启用这个输入缓冲模式,这里有个有趣的地方,这里有一个PKCODE的宏,这个不是什么黑魔法,这代表这是有一个叫PK的人的改进(Petri H. Kutvonen),我感觉是有点无语...第一次见以为是什么鬼东西。而在else中的部分是最原始的解决方案,不进行缓冲,直接读取按键,我估计是这个最简单的处理可能影响PK他的使用体验。


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
好了,现在我们程序已经拿到了一个用户的输入按键,该怎么进行处理呢?比如按下保存键文件就保存,按下寻找文件键就寻找某个文件,按下退出键就退出。小白可能会说用if 以及if else,老手可能会说要用switch!代码不能都是if else ,这是常识。对于这个问题,大师的做法是使用查表的方法,查出按键对应的处理函数。 一些学过设计模式的人可能很熟悉,这就是策略模式,但其实这是几十年前的人就想出的办法了,策略模式是后人为了出书想到的高级词汇。
具体的实现是在getbind函数中, 新手一看,这个函数怎么长得这么奇怪? 其实这是一个返回函数的函数,接收一个字符c返回函数类型为int xxx (int,int)的函数指针的函数。这个返回的函数是处理字符c输入的逻辑函数。

在函数内部,我们可以看到,具体的实现是通过了查表的方法,通过遍历全局变量keytab这张策略表,表本质是一个数组,通过循环来找到对应字符的处理函数。不过这里有一个小问题,这是通过循环的方法,会不会很慢啊,好像现代的编程语言一般是用哈希表?但其实在这里,如果表不大的话,可能数组比哈希表更简单,更快呢!


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
再向大家介绍以下我心目中的c语言之神 Linus Torvalds. linux的创始人

这个视频介绍了他开始写代码的故事,令人感动,希望能给大家带来启示。
在视频的1:13秒,本帖介绍的uemacs 也短暂上了电视呢!


  • SHOOTa4u
  • 异能力者
    6
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
会写文章多写的


2025-12-16 12:12:00
广告
不感兴趣
开通SVIP免广告
  • SHOOTa4u
  • 异能力者
    6
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
有懂英语的解释一下命名来源以及Linux命名为什么是嘲讽闭源的unix吗?


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
这里在介绍一下为什么linus会选择这个uemacs的编辑器。其实有一个有趣的现象,不论在什么时候都有很多人都在争论什么开发环境好。现在2024年大家的争论的是intellij Idea还是vscode。在以前大家争论的是vim还是emacs。对于linus来说,这些人的争论很愚蠢,所以他选择了自己维护的编辑器。


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
喜欢c语言的开发者喜欢从底层了解自己使用的工具,所以我一般自己编译自己的编辑器,我曾经很喜欢vscode,但是在我编译vscode的时候,我的天,vscode给我编译一晚上,下了一亿个包到我的node_modules。


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
在处理按键之前,我们还忘了一件事情,我们的文件还在硬盘里没读出来呢!没有文件自然是没办法编辑。在读文件之前首先要介绍UTF8编码和Unicode。Unicode是一种跨语言,跨地区的编码方案,它不但包含了英语字母,还包含了中文字符,日文字符以及最重要的emoji表情。在C语言中我们知道char可以用于表示一个字符容,但是char 8位表示的ASCII码不包括中文,A代表美国,所以ASCII码制定的时候根本没考虑我们这些非美国人!为了让地球人都用上计算机,后来又创造了Unicode(和unix有相同的前缀,uni代表统一)。Unicode 32位,4个字节,更int一个范围,表示什么鬼画符都够了。但是4个字节一个字符太长了,太浪费硬盘了,所以unix的创始人以及c语言和go语言的联合创始人肯汤普森(Ken Tompson)又发明了utf8编码,utf8可以理解为unicode的压缩形式。utf8 的英文1个字节,中文3个字节。但是utf8是文件格式,读到计算机内存,这种不一样长的字符太难处理了,我们一般处理中英文混合的字符串,我们用int来统一表示,因此emacs要将utf8流解压缩成所有字符为4个字节的字符。
下图是uemacs 中处理utf8转换的代码
可以看到所谓的unicode_t其实就是 unsigned int。而从文件读出的line的是原始的char* 字符串,只不过这个char* 不是普通c语言中的意义的一个char一个字符,在这里可能是两个char一个字符,三个char一个字符,utf8_to_unicode的任务就是将不定长的字符独立分割出来。


  • F5啊F5
  • 毛蛋
    1
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
插眼


  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
linus的名言是好的程序员关心数据结构和数据结构之间的关系,而差的程序员关心具体的实现。那让我们来看看uemacs内部的数据结构以及它们的关系吧!
如果是小白来设计文本编辑器,可能他的数据结构就是屏幕就是N*M行方格,然后文件的各个字符就在对应的方格里。这样的问题是,文件如果太大超过了N行该怎么办?一行超过了M格字符怎么办,我想切换编辑其他的文件该怎么办?


2025-12-16 12:06:00
广告
不感兴趣
开通SVIP免广告
  • c是世界最好的语言
  • 大能力者
    8
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
而在uemacs中有两个重要的数据结构可以很方便的解决问题,buffer和window,这两个数据结构可以将内容和实际显示分开处理,buffer负责文件所有信息的内容,window负责表示buffer当前可见的内容。 一个windows可显示不同文件的buffer,也可以显示一个文件buffer的不同区域。这样切换编辑文件的时候,只需要修改window中处理的指向的buffer就行了,而不用重新载入字符。



登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 1 2 下一页 尾页
  • 26回复贴,共2页
  • ,跳到 页  
<<返回c语言吧
分享到:
©2025 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示