如果这听起来有点愚蠢,我真的很抱歉.我刚读完K&R并参与了一些练习.今年夏天,对于我的项目,我正在考虑重新实现一个linux实用程序,以进一步扩展我对C的理解,所以我下载了GNU tar和sed的源代码,因为它们看起来都很有趣.但是,我无法理解它的起始位置,主要实现的位置,所有奇怪的宏来自哪里,等等.
我有很多时间,所以这不是一个真正的问题.我是否应该首先熟悉GNU工具链(即make,binutils,..)才能理解程序?或者也许我应该从更小的东西开始(如果有这样的事情)?
如果重要的话,我对Java,C++和python有一点经验.
谢谢!
Sjo*_*erd 14
GNU程序大而复杂.GNU Hello World的大小表明即使是最简单的GNU项目也需要大量的代码和配置.
对于初学者来说,autotools很难理解,但是你不需要理解它们来阅读代码.即使您修改代码,大多数情况下您只需运行make来编译您的更改.
要阅读代码,您需要一个好的编辑器(VIM,Emacs)或IDE(Eclipse)以及一些用于浏览源代码的工具.tar项目包含一个src目录,这是一个很好的起点.程序总是从main函数开始,所以也是如此
grep main *.c
Run Code Online (Sandbox Code Playgroud)
或使用您的IDE搜索此功能.它在tar.c中.现在,跳过所有初始化的东西,直到
/* Main command execution. */
Run Code Online (Sandbox Code Playgroud)
在那里,您可以看到子命令的开关.如果你传递-x它会这样做,如果你传递-c它会这样做,等等.这是这些命令的分支结构.如果你想知道这些宏是什么,请运行
grep EXTRACT_SUBCOMMAND *.h
Run Code Online (Sandbox Code Playgroud)
在那里你可以看到它们列在common.h中.
在EXTRACT_SUBCOMMAND下面你会看到一些有趣的东西:
read_and (extract_archive);
Run Code Online (Sandbox Code Playgroud)
read_and()的定义(再次用grep获得):
read_and (void (*do_something) (void))
Run Code Online (Sandbox Code Playgroud)
单个参数是一个函数指针,就像一个回调,所以read_and应该读取一些内容,然后调用该函数extract_archive
.再次,grep就可以了,你会看到:
if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))
{
if (fun && (*fun) (current_stat_info.file_name, typeflag)
&& backup_option)
undo_last_backup ();
}
else
skip_member ();
Run Code Online (Sandbox Code Playgroud)
请注意,实际工作在调用时发生fun
.fun
又是一个函数指针,在prepare_to_extract中设置.fun
可能指向extract_file
,实际写作.
我希望我能通过这些方式为您提供很多帮助,并向您展示我如何浏览源代码.如果您有相关问题,请随时与我联系.
程序喜欢tar
和sed
双重问题(当然这只是我的意见!).首先,他们都很老了.这意味着他们多年来一直有多人维护它们,具有不同的编码风格和不同的个性.对于GNU实用程序,它通常非常好,因为它们通常强制执行合理一致的编码风格,但它仍然是一个问题.另一个问题是它们的携带方式令人难以置信.通常,"可移植性"被认为是一件好事,但是当它走极端时,这意味着你的代码库最终会充满一些小技巧,以解决特定硬件和系统中的模糊错误和角落问题.而对于节目的广泛移植为tar
和sed
,很多角落案例和模糊的硬件/编译器/操作系统都要考虑在内.
如果你想学习C,那么我想说最好的起点就是不去尝试别人写的代码.相反,尝试自己编写代码.如果您真的想从现有的代码库开始,请选择一个正在积极维护的代码库,您可以在其中查看其他人在制作代码时所做的更改,并在邮件列表的讨论中进行操作,等等.
有了这样完善的程序tar
和sed
,你看到的结果,将已经发生的讨论,但你不能看到软件的设计决策和变化进行实时正在取得进展.这只能通过积极维护的软件来实现.
当然,这只是我的意见,如果你愿意的话,你可以把它当作一粒盐:)
GNU Hello可能是最小、最简单的 GNU 程序并且易于理解。
归档时间: |
|
查看次数: |
2909 次 |
最近记录: |