如果这听起来有点傻,我真的很抱歉。我刚读完《K&R》,我做了一些练习。今年夏天,对于我的项目,我正在考虑重新实现一个linux实用程序,以进一步扩展我对c的理解,因此我下载了gnu tar和sed的源代码,因为它们看起来都很有趣。然而,我很难理解它从哪里开始,主要实现在哪里,所有奇怪的宏都来自哪里,等等。
我有很多时间,所以这不是问题。为了理解程序,我应该先熟悉gnu工具链(即make、binutils等)吗?或者我应该从更小的东西开始(如果有这样的东西的话)?
如果这很重要,我对Java、C++和Python几乎没有什么经验。
谢谢!

最佳答案

GNU程序又大又复杂。GNU Hello World的大小表明,即使是最简单的gnu项目也需要围绕它进行大量的代码和配置。
对于初学者来说,自动工具很难理解,但阅读代码时不需要理解它们。即使修改了代码,大多数时候也可以运行make来编译更改。
要阅读代码,您需要一个好的编辑器(vim、emacs)或ide(eclipse)和一些工具来浏览源代码。tar项目包含一个src目录,这是一个很好的开始位置。程序总是从主函数开始,所以

grep main *.c

或者使用IDE搜索此函数。它在tar.c中。现在,跳过所有初始化的内容,直到
/* Main command execution.  */

在那里,可以看到子命令的开关。如果传递-x,它将执行此操作,如果传递-c,它将执行此操作,等等。这是这些命令的分支结构。如果想知道这些宏是什么,请运行
grep EXTRACT_SUBCOMMAND *.h

在这里你可以看到它们是共同的。
在下面的extract_子命令中,您可以看到一些有趣的内容:
read_and (extract_archive);

read_and()的定义(再次使用grep获得):
read_and (void (*do_something) (void))

单个参数是一个函数指针,类似于回调函数,因此read_应该读取一些内容,然后调用函数extract_archive。再来一次,格雷普,你会看到:
  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 ();

注意,真正的工作发生在调用fun时。fun又是一个函数指针,在prepare_to_extract中设置。fun可以指向extract_file,它执行实际的写入操作。
我希望我给你介绍了很多,并向你展示了我是如何浏览源代码的。如果您有相关问题,请随时与我联系。

关于c - 如何理解GNU源代码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3051091/

10-13 07:08