《UNIX环境高级编程》APUE源码使用方法

 

 
 

一、《UNIX环境高级编程》第一版源码编译

Installation Guide of Example Source Code
1. Download SourceCode.zip 2. Type command: unzip SourceCode.zip
3. Type command: cd SourceCode
4. Type command: cp -f Make.def.rhlin Make.defines
5. Type command: cd lib.rhlin
6. Modify Makefile, delete the target strerror.o, replace the leading spaces with a TAB character at
line 58
7. Type command: make redhat60linux
8. Modify the path information in Make.defines at line 11 and line 19
9. Done

10.示例代码位置见Sourcefiles文件

1.1          file/ls1.c
1.2          mycat/mycat.c
1.3          mycat/getcputc.c

二、《UNIX环境高级编程》第二版源码编译

1.在http://www.apuebook.com下载(我是在学校网下)

2.解压缩,并认真阅读REAME并设置目录.

To build the source, edit the Make.defines.* file for your system and set

WKDIR to the pathname of the tree containing the source code.         Then just

run "make"

不幸我Make时有两个错误出现,但没关系,能在lib文件夹里生成一个库文本libapue.a即可

3. 把C源码中的#include "apue.h"改成#include "../include/apue.h或合适的路径。

4. gcc sourcefile.c ../lib/libapue.a
5. 应该有更好方法,但这个方法可以成功。这么麻烦可能是因我Make时有两个错误出现吧:(

修正说明(现在成功了^_^):

1.在http://www.apuebook.com下载(我是在学校网下)

2.解压缩,并认真阅读REAME并设置目录.
To build the source, edit the Make.defines.* file for your system and set
WKDIR to the pathname of the tree containing the source code.         Then just
run "make"


3.我的系统是RedHat 修改Source\Make.define.linux 文件如下
WKDIR=/home/thx/apue.2e
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS)
LDDIR=-L../lib
LDLIBS=../lib/libapue.a $(EXTRALIBS)
CFLAGS=-DLINUX -ansi -I$(WKDIR)/include -Wall -D_GNU_SOURCE $(EXTRA)
###taohx modify 2008-6-18
CPPFLAGS=-I/home/thx/apue.2e/include/

# Our library that almost every program needs.
LIB=../libapue.a

# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out typescript*


4.运行make. 因为我加了CPPFLAGS语句,指出了apue.h文件的位置。现在该正确了^_^


5.若不想重新全部编译,只编译某目录下的源文件.(以source\file目录为例)
#cd file
#cp linux.mk Makefile
#make


6.现在不用再把C源码中的#include "apue.h"改成#include "../include/apue.h ^_^

                                   

《UNIX环境高级编程》源码编译方法  
            来源:http://www.cublog.cn/u/33048/showart_256254.html

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  最近在学习《UNIX环境高级编程》(Advanced Programming in the UNIX Environment, 简称APUE,以下使用简称)。该书的作者是W.Richard.Stevens,国际知名的UNIX和网络专家。我看的是该书的第一版,尤晋元翻译的。网上有的评论该书翻译的比较差劲,有的说还行。我个人觉得,这本书的翻译还可以。并且,如果本身就有一定的UNIX/Linux基础的话,读起来应该不是很吃力。同时我也下了该书的第二版(英文版),有什么看不懂的地方,再对照英文版看一下,辅助理解。
                                                            这里要谈到的一个问题就是该书中的源代码编译的问题。此书中差不多每个历程中,都会有这样一行源码:
                                                #include "ourhdr.h"
                                                   
                                                在第二版中改为:
                                                #include "apue.h"
                                               
                                                             这个头文件是作者把把每个例程中常用的标准头文件,一些常用的出错处理函数(err_**()之类的函数)和一些常用的宏定义给整理在一个头文件中。这个可以省去在每个例程中录入较多的重复代码,这样可以减少每个例程的长度。但是,这样就给读者带来了不少麻烦。因为我们还要去搞明白如和把这个头文件编译,然后做成库文件,添加到我们的系统中。特别读于初学者,本来满怀信心的,结果在编译第一个程序的时候就出现了问题。我也没有搞明白如何把 "ourhdr.h"静态的编译到系统中。
                                               
                                                             不过,不明白如何使用"ourhdr.h"这个头文件,并不会影响我们学习APUE,也不会影响我们编译和运行每一个例程。其实,简单的想一下,如果一个 C程序要能顺利的编译和运行,除了我们要语法正确等方面外,最根本的是要保证我们程序中所调用的函数以及宏等等都要有完整的来源,也就是必须包含所有调用函数和宏所在的头文件。对于一个具体的源程序,如果我们正确的包含了头文件,那么剩下的就是程序本生语法方面应该注意的事项。
                                               
                                                             如何确定系统调用函数包含在那个头文件中呢?这在Unix/Linux系统下并非一件难事。Unix/Linux下命令man可以帮助我们找到。man命令不仅可以帮助我们查找一般命令的用法,同时提供不同层次的帮助诸如系统调用或者管理员级别的命令等等(譬如FreeBSD6.1中,man 1是用户专用手册,man 2是系统调用,man 3是库函数查询等等)。
                                               
                                                             下面我们就以APUE书中程序1-1 (实现ls命令部分功能)为例,来说明如何将书中的程序改编成全部使用标准头文件的程序。其中,操作系统用的是FreeBSD6.1,经过相应的修改可以在书中所说的几个Unix系统及Linux系统中运行,我也曾在Debian Linux下成功编译和运行该程序。书中1-1.c的原始代码如下:
                                               
                                                #include <sys/types.h>
                                                #include <dirent.h>
                                                #include "ourhdr.h"
                                               
                                                int
                                                main(int argc, char *argv[])
                                                {
                                                             DIR                         *dp;
                                                             struct dirent             *dirp;
                                               
                                                             if (argc != 2)
                                                                 err_quit("usage: ls directory_name");
                                               
                                                             if ((dp = opendir(argv[1])) == NULL)
                                                                 err_sys("can't open %s", argv[1]);
                                                             while ((dirp = readdir(dp)) != NULL)
                                                                 printf("%s\n", dirp->d_name);
                                               
                                                             closedir(dp);
                                                             exit(0);
                                                }
                                               
                                                    从书后面的附录中可以看到"ourhdr.h"的内容比较多,包含了比较多的常用头文件,一些宏定义和一些常用函数和出错函数的定义。其实,对于每一个具体的程序,我们只需要找到该程序中用到的头文件即可。
                                               
                                                             该1-1.c中所用到的系统函数调用有:opnedir(),readdir(),printf(),closedir()和exit()。
                                                其中,对于常用的函数prinft()和exit(),它们所在的头文件一般都知道,分别是<stdio.h>和<stdlib.h>。而对于opnedir (),readdir()和closedir(),我们可以通过man opendir,man readdir,man closedir得到这三个关于目录操作的函数所在的头文件都是:<sys/types.h>和<dirent.h>。这两个头文件在源程序中也已经列出。
                                               
                                                             其次,1-1.c中还用到了作者自定义的两个函数:err_quit()和err_sys()。这两个函数主要使用来进行出错处理的。当然,使用这两个函数对错误信息的处理是比较完善的。但是,作为我们学习来讲,了解程序的核心功能是首要的,我们可以将出错处理简化一点,即当遇到错误的时候,我们只简单的使用printf()函数来提示一下有错误发生。当然,用printf()来进行出错处理并不是一种很合理的方法,而且往往我们看不到更关键的错误信息,但对于我们仅仅作为学习来用还是可以接受的。毕竟我们要理解的核心部分是程序的功能实现,出错处理在于其次。
                                               
                                                            通过以上的说明,我们可以将1-1.c修改为如下内容:
                                               
                                                #include <sys/types.h>
                                                #include <dirent.h>
                                                #include <stdio.h>
                                                #include <stdlib.h>
                                                int main(int argc, char* argv[])
                                                {
                                                             DIR *dp;
                                                             struct dirent *dirp;
                                                    
                                                             if(argc != 2)
                                                             {
                                                                 printf("You need input the directory name.\n");
                                                                 exit(1);   //该行代码不要也可  
                                                             }
                                                    
                                                             if((dp = opendir(argv[1])) == NULL)
                                                             {
                                                                 printf("cannot open %s\n", argv[1]);
                                                                 exit(1);    //该行代码不要也可
                                                             }
                                               
                                                             while ((dirp = readdir(dp)) != NULL)
                                                                 printf("%s\n", dirp->d_name);
                                               
                                               
                                                             closedir(dp);
                                               
                                                             exit(0);
                                                }
                                               
                                                    这样修改后的程序已经与作者的头文件"ourhdr.h"没有关系,可以单独的进行编译。我使用的是root用户,执行命令:
                                               
                                                # gcc 1-1.c           //生成目标文件a.out
                                                或者
                                                # gcc -o 1-1 1-1.c           //生成目标文件1-1
                                               
                                                             没有任何错误和警告,说明编译成功。这时我们执行生成的目标文件:
                                               
                                                # ./a.out /home
                                                或者
                                                # ./1-1 /home
                                               
                                                             则会列出/home路径下的所有文件,包括目录(.)和(..)。
                                               
                                                             通过这样的方法,基本上我们可以将该书中所有的例程修改成不包含"ourhdr.h"的程序。这样,我们就可以单独的编译每一个例程,而不用顾及作者所给的杂凑的头文件。同时这种比较笨的方法,反而有利于帮助我们了解不同系统调用所对应的头文件,对于学习来说,这应该是一件好事。
                                               
                                                             现在,我也才学到APUE的第四章了。前四章的程序,我都是采用这种方法进行编译和运行。如果也有在学习APUE的朋友,我们可以一起交流。                                                                                                                                                                                                                                                                                                                                                                                               
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值