当前课程知识点:基于Linux的C++ >  第十二讲 Linux系统编程基础 >  12.2 程序执行环境(一) >  LinuxCPP1202

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP1202在线视频

LinuxCPP1202

下一节:LinuxCPP1203

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP1202课程教案、知识点、字幕

我们首先来看程序执行环境

在程序执行环境这一节

主要包括七个主题

一个是参数列表 第二个是环境变量

第三个是程序退出码

第四个是程序调用的错误处理

第五个是资源管理

最后两个是系统日志和用户信息

我们首先来看参数列表

对 Linux 操作系统来讲

它的命令行是遵照一定的规范的

首先在书写命令行的时候

你可以提供一系列的参数

这些参数是以短参数或长参数的格式来提供的

这些参数是以短参数或长参数的格式来提供的

这两种格式其实都可以

如果是一个短参数的话

它就是一个单横来开头

后面跟着一个单一的字符

比如讲 “ls –h” 它这就是一个短参数

如果是长参数的话的呢

那么就是一个双横来开头

后面跟着就是一个字符串

它就不是一个单一的字符了

比如讲 “ls --help”

就是看 ls 的帮助 也就这个意思

这是 Linux 的命令行规范

当我们在程序中想访问这个程序的参数列表的时候

当我们在程序中想访问这个程序的参数列表的时候

它有一个一定的方案

首先 main() 函数的那个参数

我们此前从来都没用过

事实上我们也没怎么写过

它其实是可以带两个参数的

一个参数呢叫 argc 一个参数叫 argv

这两个参数其实就表达了 Linux 命令行里

这两个参数其实就表达了 Linux 命令行里

后面带的那些附加的参数

我们在程序中就可以通过分析 argc、argv

这两个参数来获取 Linux 命令行里

提供的那些参数的列表

按照这个方式处理它就可以了

我们看这样一个例子

编写程序 输出命令行参数

main() 函数带双参数 argc、argv

argc 是一个整型参数

它表达的是什么呢

它表达是 main() 函数的参数有几个

这是最重要的一个参数

这个参数的计数是包括这个命令本身的

所以命令本身是它的第 0 个参数

接下来才是它真正地附带的那个参数

从第 1 号位开始

这些参数存在什么地方呢

这些参数存在 argv 里

argv 是一个字符串数组

首先它是一个数组

其次呢 它的每个元素都是一个字符串

这个数组的排布就是一个字符串

接着一个字符串 接着一个字符串

每一个字符串都是以 “\0” 结尾的

在所有的这些字符串都结尾之后

再用一个 “\0” 来结尾

表达它的全部字符串的结束

它实际上是按照这样的一个模式

来存储我们的 argv 的

那么在我们的 main() 函数里

我们就可以根据 argc 的值来决定

它到底带没带参数

当 argc 大于 1 的时候

说明它就有参数了

因为 argc 等于 1 的话那实际上

就意味着只有命令本身

它后面没有其它参数了

那么我们怎么在程序中

分析我们的参数列表呢

Linux 操作系统为我们定义了一个结构体

这个结构体的名字叫 option

我们使用这个结构体 option 就可以分析 Linux 命令

我们使用这个结构体 option 就可以分析 Linux 命令

在程序执行过程中所提供的那些参数

这个结构体定义在 “getopt.h” 这个头文件里

它包括了四个字段

第一个字段是 name 表示选项的长名称

第二个字段是 has_arg

表示它是不是具有的附加的参数

如果是 0 表示它没有附加参数

1 就表示有附加参数

2 就表示有可选的附加参数

就是也许有 也许没有

三 是一个指向整数的指针 flag

它用来保存 value 的值

有时候我们需要用

有时候我们不需要用它

第四个是选项的短名称 val

用来存储你在 Linux 命令行

输入的这个参数所对应的短名称

因为你可能输入的是长选项

那么这个地方保存的就是那个选项的短名称

那么这个地方保存的就是那个选项的短名称

长名称是在第一个字段保存的

分析 Linux 命令行参数列表的那个函数

名字叫 getopt_long()

这个函数比较长 参数比较多

argc、argv 是两个分析命令行参数的主要的参数

argc、argv 是两个分析命令行参数的主要的参数

argc 和 argv 是 main() 函数

传过来那两个参数

接下来那两个参数保存就是选项的信息

一个是短选项 一个是长选项

对于短选项来讲它是一个字符串

对于长选项来讲呢

它是一个指向 option 结构体的指针

第五个 用来表达的就是它那个长选项

第五个 用来表达的就是它那个长选项

它事实上在那个选项数组里边的对应的索引

它事实上在那个选项数组里边的对应的索引

所以这个函数的返回值

当你调用 getopt_long()

去分析 Linux 参数列表的时候

每一次它会分析出 Linux 命令行里边的一个参数

每一次它会分析出 Linux 命令行里边的一个参数

如果这个参数是合法有效的

它就会返回那个参数所对应的

短选项那个字符

如果那个参数不存在 它就会返回 -1

如果在参数列表中提供的是长选项

那么它的第五个参数就会输出

那个长选项在长选项数组里边的索引

就是它下标是几

这样的话 你就能够查找到它对应的短选项的名称和其它附加信息

这样的话 你就能够查找到它对应的短选项的名称和其它附加信息

就是这个意思

在实际编程的时候

我们需要使用循环来处理所有的命令行参数

我们需要使用循环来处理所有的命令行参数

如果在处理的过程中遇到错误选项

如果在处理的过程中遇到错误选项

那么就应该输出错误的信息

并且终止程序的运行

当你处理附加参数的时候

可以使用全局变量 optarg

来获取它那个附加参数的基地址

在完成所有的处理之后

全局变量 optind

存储首个非可选参数的索引

你比如讲 我们写这样一个程序

接受三个选项 执行正确的处理

第一个选项是 “-h”/“--help”

显示程序的帮助信息然后退出

第二个选项是 “-o filename”

或者 “--output_filename”

“-o” 选项

它就会带一个附加的参数 filename 文件名

“-v” 和 “--verbose” 用来输出复杂的信息

“-v” 和 “--verbose” 用来输出复杂的信息

缺省情况下边

这些复杂信息我们是不输出的

如果你设定了这个开关

那么在程序运行过程中

就会输出复杂的信息

这样能帮助你调试你的程序代码

我们看程序代码

在这个程序代码里边

我们定义一个全局量 program_name

来存储我们这个程序的实际的名字

然后我们定义一个函数 OutputInfo() 来输出信息

然后我们定义一个函数 OutputInfo() 来输出信息

因为这个输出的信息

有的时候是向标准输出流

有的时候是向标准错误流里输出

所以我们提供一个输出流的参数 os

ostream 的一个引用

然后提供一个退出码

在这个函数的内部简单地将整个程序的使用方法罗列一下

在这个函数的内部简单地将整个程序的使用方法罗列一下

输出 就 OK 了

关键是我们的主函数

在主函数里

我需要定义一个短选项的字符串

这个字符串不能变 全是常数

所以是 const char * const short_opts

这个短选项字符串有一个特别定义的规格

这个短选项字符串有一个特别定义的规格

字符串的内容是所有短选项的简单拼接

字符串的内容是所有短选项的简单拼接

你必须按照那个选项顺序拼接

跟长选项必须完全对应的

一个选项一个字符

如果这个选项有一个附加参数

后面就要带 “:”

因为我们这里边提供了三个附加参数

顺序是 “hov”

所以我们写的这个短选项字符串就是 “ho:v”

这就是我们短选项字符串

它对应的长选项数组

你也必须按照这个格式来

"help", 0, NULL,'h' 这是第一个选项

"output",1, NULL,'o' 这是第二个选项

我们前面不解释了吗

第二个参数表示它有没有附加参数

0 表示没有

1 表示它有一个附加参数

就按照这个模式写就行了

写完这三个选项之后

记得在最后封装一个空选项

NULL, 0, NULL, 0

用来表达这个长选项数组结束了

必须按照这个格式来定义

然后我们首先定义一个 output_filename 输出文件名

然后我们首先定义一个 output_filename 输出文件名

把它设成 NULL 初始化成 NULL

然后我们把 verbose 初始化成 0

然后我们把 program_name 初始化成 argv[0]

接下来就我们需要调用 getopt_long()

来处理它的每一个参数

getopt_long() 这个函数在处理参数的时候

它一次只能处理一个

你把 argc、argv、short_opts、long_opts、NULL

这五个参数全传进去以后

它返回的呢

就是对应那个 option 那个选项

那个选项处理的是第一个

然后我们根据它的选项返回值

看它是不是 -1

如果是 -1 就说明处理完了嘛

如果不是我们就要一个接着一个地去处理

用一个 switch 来去处理它

如果它是 “h” 我们就输出它的用法

就是用户想看这个程序怎么用

你就输出它的用法

如果是 “o” 那我们就把

output_filename 设成 optarg

刚才不谈到过了吗

带着一个附加参数的一个选项

那么它的那个附加参数怎么获得呢

就是通过全局量 optarg

就 optarg 选项参数

就这个意思 用它来获得

它已经给你保存好了

你拿过来直接用就 OK 了

然后 break

“v” 我们就把 verbose 设成 1 break

“?” 说明出错了

发现了一个无效的参数

我们就向标准错误流里输出信息

如果是 “-1”

表示处理完毕了

连 “-1” 都不是

那就程序出现了未知错误

我们就 abort() 结束了

这一个参数处理完毕了

那我们接下来就要处理第二个参数

所以继续调用 getopt_long()

处理它的下一个参数 循环

按照这个模式就能够将 Linux 命令行的全部的参数都处理完

按照这个模式就能够将 Linux 命令行的全部的参数都处理完

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP1202笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。