没有合适的资源?快使用搜索试试~ 我知道了~
首页Linux高级编程入门指南:Emacs编辑与C/C++实战
Linux高级编程入门指南:Emacs编辑与C/C++实战
需积分: 10 4 下载量 112 浏览量
更新于2024-07-18
1
收藏 1.2MB PDF 举报
"《高级Linux程序设计》是一本深入探讨Linux平台高级UNIX编程的指南,由完美废人翻译。全书分为两卷,专注于C/C++编程实践和技巧。本书假定读者已具备基础的C/C++编程知识和对标准C库的理解,主要使用C语言编写示例,但也会提及C++的独特特性。 第一部分,"起步",详细介绍了在Linux系统中进行C/C++程序开发的全套流程,包括但不限于:代码编辑。作者推荐使用GNUEmacs,这是一种功能强大且流行的编辑器,尽管书中不会完全依赖它的特性,但对于新手来说,Emacs的强大功能和可定制性可能会成为学习过程中的重要工具。虽然其他编辑器如Vi或Atom也可选用,但对于Linux新手,通过一个简短的教程学习Emacs能帮助建立基本的编程环境。 第二章着重于"编写优质GNU/Linux软件",深入讲解了静态库和动态库的区别,这对于理解和优化软件性能至关重要。如果读者是从Windows环境转到Linux,章节还会对比两个平台在编程实践中的异同,确保跨平台开发的顺利进行。 这本书不仅提供技术知识,也关注实践经验,适合希望在Linux系统上提升高级编程技能的开发者,无论是对C/C++语言的深化理解,还是学习如何高效利用Linux环境进行软件开发,都将受益匪浅。通过阅读本书,读者能够掌握Linux平台的高级编程技巧,并能够在实际项目中应用所学,从而成为Linux环境下的熟练开发者。"
资源详情
资源推荐
高级 Linux 程序设计·卷一·Linux 平台上的高级 UNIX 编程 完美废人 译
/* 记住程序的名字,可以用于输出的信息。名称保存在 argv[0]中。*/
program_name = argv[0];
do {
next_option = getopt_long (argc, argv, short_options,
long_options, NULL);
switch (next_option)
{
case ‘h’: /* -h 或 --help */
/* 用户要求查看使用帮助。输出到标准输出,退出程序并返回 0(正常结束)。*/
print_usage (stdout, 0);
case ‘o’: /* -o 或 --output */
/* 此函数接受一个参数,表示输出文件名。*/
output_filename = optarg;
break;
case ‘v’: /* -v 或 --verbose */
verbose = 1;
break;
case ‘?’: /* The user specified an invalid option. */
/* 向标准错误输出帮助信息,结束程序并返回 1(表示非正常退出)。*/
print_usage (stderr, 1);
case -1: /* 结束处理选项的过程。*/
break;
default: /* 别的什么:非预料中的。*/
abort ();
}
}
while (next_option != -1);
/* 选项处理完毕。OPTIND 指向第一个非选项参数。
出于演示目的,如果指定了冗余输出选项,则输出这些参数。*/
if (verbose) {
int i;
for (i = optind; i < argc; ++i)
printf (“Argument: %s\n”, argv[i]);
}
/* 主程序到这里结束。*/
return 0;
}
使用 getopt_long 看起来需要不少的工作量,但是如果你尝试自己写代码解析这些参数,
你就会发现这会浪费更多的代码。函数 getopt_long 已经过反复的考验,而且它在程序选择
接受何种参数方面提供了出众的灵活性。不过,最好还是不要轻易去使用那些高级技巧而斤
19
www.linuxidc.com
Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。
高级 Linux 程序设计·卷一·Linux 平台上的高级 UNIX 编程 完美废人 译
两使用上面介绍的基本用法。
2.1.4 标准 I/O
标准 C 库提供了标准输入和输出流(分别为 stdin 和 stdout)。它们被用于 scanf、printf
和其它库函数中。在 UNIX 传统中,程序习惯使用标准输入输出进行沟通。这种习惯允许多
个程序通过管道和重定向进行串连。(参考你使用的 shell 的手册页以学习相关语法。)
C 库还提供了标准错误流 stderr。程序应该将警告和错误信息输出到标准错误流而不是
标准输出流。这样方便了用户区别对待普通程序输出和错误输出,比如将标准输出重定向到
一个文件而让标准错误显示在终端里。可以通过 fprintf 函数向标准错误流输出信息:
fprintf (stderr, (“Error: …”));
这三个流也可以文件描述符的形式通过底层 UNIX I/O 命令(read、write 等)进行操作。
文件描述符 0 代表标准输入,1 为标准输出而 2 为标准错误。
当调用一个程序的时候,有时候需要将标准输出和错误同时重定向到一个文件或管道。
不同 shell 为这个操作提供了不同的语法;对于类似 Bourne shell 的 shell 程序(包括多数
GNU/Linux 系统的默认 shell 程序 bash)语法是这样的:
% program > output_file.txt 2>&1
% program 2>&1 | filter
这里,2>&1 的语法表示文件描述符 2(stderr)应并入文件描述符 1(stdout)。注意,
2>&1 这个语法必须出现在文件重定向之前(如第一个例子所示)或者管道重定向之前(如
第二个例子所示)。
需要注意的是,stdout 是经过缓冲处理的。写入 stdout 的数据不会立刻被写入终端(或
其它设备,如果程序输出被重定向)除非缓冲区满、程序正常退出或 stdout 被关闭。你可
以这样显式地刷新输出流:
fflush (stdout);
与stdout不同的是,stderr没有经过缓冲处理;输出到stderr的数据会直接被发送到终端。
1
这可能导致令人惊奇的结果。例如下面这个程序,运行时并不会每一秒钟输出一个句点,
而是会在缓冲被填满的时候一起输出一堆。
while (1) {
printf (“.”);
sleep (1);
}
在这个循环中句点则会每秒钟输出一个。
while (1) {
fprintf (stderr, “.”);
sleep (1);
}
20
1
在C++中,cout和cerr之间也有这样的区别。注意endl操作符除了输出换行符,还会执行刷新操作;
如果你不希望执行刷新操作(例如出于运行效率的考虑)则应该使用常量’\n’表示换行。
www.linuxidc.com
Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。
高级 Linux 程序设计·卷一·Linux 平台上的高级 UNIX 编程 完美废人 译
2.1.5 程序退出代码
当一个程序结束的时候,它会通过一个退出代码表示自己的运行结果。退出代码是一个
小整数值。一般的习惯是,返回 0 表示正常,而非 0 表示错误的出现。一些程序通过不同的
非 0 值表示不同的错误情况。
在许多 shell 中,可以通过特殊环境变量$?得到最近执行的一个程序的退出代码。下面
这个例子中,ls 命令被执行了两次,每次执行完毕之后我们都输出了命令的退出代码。第一
次调用中,ls 成功执行且返回 0。第二此运行的时候 ls 在运行中出现了错误(因为在命令行
中指定的文件不存在),并因此返回了非 0 值作为退出代码。
% ls /
bin coda etc lib misc nfs proc sbin usr
boot dev home lost+found mnt opt root tmp var
% echo $?
0
$ ls bogusfile
ls: bogusfile: No such file or directory
% echo $?
1
C 或 C++程序通过从 main 函数返回来指定程序的退出代码。还可以通过其它的方法指
定程序的退出代码,且特殊的退出代码被分配用于标识特殊的程序退出原因(被信号终止等)
我们将在第三章中对这些情况进行深入的讨论。
2.1.6 环境
GNU/Linux 为每个运行程序提供了一个
环境(
environment
)
。环境是一组“键-值”对
的集合。环境变量名和它们的值都是字符串。环境变量名通常由大写字母组成。
你可能已经对一些常见的环境变量有所熟悉。例如:
· USER 包含了你的用户名。
· HOME 包含了你的个人目录
(
home directory
)
的位置。
· PATH 包含了一些文件夹路径,之间由冒号进行分隔。Linux 系统在这些文件夹中
搜索可执行程序。
· DISPLAY 包含了 X 窗口服务器的名称和显示器编号。这里指定的 X 服务器和显示
器编号将是基于 X 的图形程序运行时将会出现的地方。
Shell 和其它所有程序一样,都有一个环境。Shell 提供了直接查看和修改环境的方法。
可以使用 printenv 程序输出完整的当前环境。不同的 shell 程序通过不同的内建语法使用环
境变量的值;以下示例使用的是 Bourne 式的 shell。
· Shell 会自动为每个检测到的环境变量设置一个 Shell 变量,因此你可以通过$变量
名的语法访问环境变量。例如:
%echo $USR
samuel
% echo $HOME
/home/samuel
· 可以通过 export 命令将一个 shell 变量加入环境中。例如,可以这样设置环境变
21
www.linuxidc.com
Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。
高级 Linux 程序设计·卷一·Linux 平台上的高级 UNIX 编程 完美废人 译
量 EDITOR 的值:
% EDITOR=emacs
% export EDITOR
或
% export EDITOR=emacs
程序中可以使用<stdlib.h>中提供的 getenv 函数访问环境变量。这个函数接受一个包含
变量名的字符串作为参数,并返回包含了相应的环境变量值的字符串。如果参数中指定的环
境变量不存在,getenv 将返回 NULL。而 setenv 和 unsetenv 函数则分别可用于设置和清除
环境变量。
列举所有环境变量需要一点技巧。你需要通过访问一个叫做 environ 的全局变量来列举
所有环境变量。这个变量是由 GNU C 库定义的。它是一个 char **类型的变量,包含了一个
以 NULL 指针结束的字符串数组。每个字符串都包含了一个环境变量。这个环境变量被表
示为“变量=值”的形式。
请看下面的例子。列表 2.3 中的程序通过一个循环遍历整个 environ 数组并输出所有环
境变量。
代码列表
2.3
(
print-env.c
)输出运行环境
#include <stdio.h>
/* ENVIRON 变量包含了整个环境。*/
extern char** environ;
int main ()
{
char** var;
for (var = environ; *var != NULL; ++var)
printf (“%s\n”, *var);
return 0;
}
不要直接修改 environ 变量;如果需要修改环境变量,则应通过 setenv 和 unsetenv 函
数完成。
通常,当启动一个新程序的时候,这个程序会从调用者那里继承一份运行环境(在交互
运行的情况下,通常调用者是 shell 程序)。因此,你从 shell 中运行的程序可以使用你通过
shell 设置的环境变量。
环境变量常被用于向程序提供配置信息。假设你正在写一个程序,它需要连接到一台
Internet 服务器并获取一些信息。程序可以利用命令行参数获取服务器地址。但是,如果用
户不会需要经常改变服务器地址,那么你可以选择将服务器地址存储在一个特殊的环境变量
中(譬如 SERVER_NAME)。如果这个环境变量不存在则使用一个默认值。这个程序的部
分可能像这个样子:
22
www.linuxidc.com
Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。
高级 Linux 程序设计·卷一·Linux 平台上的高级 UNIX 编程 完美废人 译
代码列表
2.4
(
client.c
)一个网络客户程序的片断
#include <stdio.h>
#include <stdlib.h>
int main ()
{
char* server_name = getenv (“SERVER_NAME”);
if (server_name == NULL)
/* 环境变量 SERVER_NAME 不存在。使用默认值。*/
server_name = “server.my-company.com”;
printf (“accessing server %s\n”, server_name);
/* 在这里访问服务器。*/
return 0
}
假设这个程序叫 client。假设你还没有设置 SERVER_NAME 变量,则程序会使用默认
值进行连接:
% client
accessing server server.my-company.com
但修改要连接到的服务器也很容易:
% export SERVER_NAME=backup-server.elsewhere.net
% client
accessing server backup-server.elsewhere.net
2.1.7 使用临时文件
有时候程序需要使用临时文件,用来缓存或者向别的程序传递大量的数据。在
GNU/Linux 系统中,临时文件被存储在 /tmp 文件夹下。当使用临时文件的时候,你需要注
意以下的问题:
· 同一个程序的多个副本可能正在(由同一个用户或不同的用户)并行运行。每个
副本都应该使用不同的临时文件以避免冲突。
· 文件权限的设置应当保证临时文件不会被未被授权的用户修改或替换,从而导致
程序行为被改变。
· 生成的临时文件名应该不可被外界预料;否则,攻击者可能会在程序检测一个文
件名是否被占用与实际打开临时文件进行读写之间的间隔进行攻击。
GNU/Linux 提供了 mkstemp 和 tmpfile 两个函数以帮助你解决这些问题(以辅助使用
其它一些仍需要面临这些问题的函数)。两者之间的选择取决于你对文件操作的要求:是否
准备将临时文件转交给其它程序?使用 UNIX I/O(open、write 之类)还是标准 C 库的 I/O
(fopen、fprintf 之类)?
23
www.linuxidc.com
Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。
剩余103页未读,继续阅读
dd369980260
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- JDK 17 Linux版本压缩包解压与安装指南
- C++/Qt飞行模拟器教员控制台系统源码发布
- TensorFlow深度学习实践:CNN在MNIST数据集上的应用
- 鸿蒙驱动HCIA资料整理-培训教材与开发者指南
- 凯撒Java版SaaS OA协同办公软件v2.0特性解析
- AutoCAD二次开发中文指南下载 - C#编程深入解析
- C语言冒泡排序算法实现详解
- Pointofix截屏:轻松实现高效截图体验
- Matlab实现SVM数据分类与预测教程
- 基于JSP+SQL的网站流量统计管理系统设计与实现
- C语言实现删除字符中重复项的方法与技巧
- e-sqlcipher.dll动态链接库的作用与应用
- 浙江工业大学自考网站开发与继续教育官网模板设计
- STM32 103C8T6 OLED 显示程序实现指南
- 高效压缩技术:删除重复字符压缩包
- JSP+SQL智能交通管理系统:违章处理与交通效率提升
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功