ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

命令行参数

命令行参数

目录

  • 1. 命令行参数
    • 1.1 什么是命令行参数
    • 1.2 argc 与 argv
      • 1.2.1 argc
      • 1.2.2 argv
    • 1.3 使用命令行参数的意义

在学习 C 语言时,我们最熟悉的main函数可能是无参的int main()。但其实,main函数是可以带参数的!它就是我们在终端执行程序时经常用到的命令行参数。

1. 命令行参数

1.1 什么是命令行参数

当我们打开终端(Terminal)或命令行(CMD),输入一行命令时,其实就是在向操作系统传递参数。例如:

./code a b c d

在这行命令中:

  • ./code:是我们编译生成的可执行程序。

  • a b c d:就是我们传递给程序的命令行参数。

1.2argc与argv

测试代码:

#include <stdio.h> int main(int argc, char *argv[]) { printf("argc: %d\n", argc); int i = 0; for(; i < argc; i++) { printf("argv[%d]->%s\n", i, argv[i]); } return 0; }

编译并运行./code a b c d,输出结果如下:

1.2.1argc

  1. argc全称是argument count,代表参数的个数(整型)。

  2. 注意:程序本身的名称也算一个参数。所以执行./code a b c d时,有./code加上a,b,c,d共 5 个参数,因此argc为 5。

  3. argc的值至少是 1(argc >= 1)。argv[0]必定存在,它指向的就是程序运行时的名称(包含路径)。

1.2.2argv

  1. argv全称是argument vector(参数向量),它是一个字符指针数组char *argv[]。每一个元素指向一个字符串。

  2. 所有的参数都是以空格分隔的字符串。即使你输入的是单个字符a,在 C 语言中它也被当作字符串"a"来处理。

  3. argv数组的长度是argc,最后一个有效参数是argv[argc-1]。并且,在标准实现中,argv[argc]的值必定是NULL,这常被用来作为遍历结束的标志。

  • 当我们在终端敲下命令并回车时,Bash和操作系统在背后默默完成了字符串的拆分和数组的构建。

  • 系统会把这些字符串存放在内存的栈区(或环境区)。

  • char *argv[]就像是一个指针数组,里面的每一个“格子”都存放着对应字符串在内存中的首地址。

  • 同时,系统会将参数个数传给argc。示意图中绿色的格子清晰的展示了argv数组的结构:argv[0]指向./code,argv[1]指向a……最后一个格子指向NULL。

1.3 使用命令行参数的意义

既然可以在程序里用scanf或写死数据,为什么非要用命令行参数呢?

命令行参数的本质应用:是为了实现“一个命令,根据不同的选项,实现不同的子功能”。

这是 Linux/Unix 系统中所有命令(如ls,cp,grep)能够灵活工作的基石。你可以通过传入不同的参数,让同一个程序执行完全不同的逻辑。

示例:

#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { if(argc != 2) { printf("该命令使用错误!你应该这样用: %s -a|-b|-c|-d\n", argv[0]); return 1; } if(strcmp(argv[1], "-a") == 0) { printf("我现在执行的是该命令的第一种功能\n"); } else if(strcmp(argv[1], "-b") == 0) { printf("我现在执行的是该命令的第二种功能\n"); } else if(strcmp(argv[1], "-c") == 0) { printf("我现在执行的是该命令的第3种功能\n"); } else { printf("我现在执行的是该命令的默认功能\n"); } return 0; }

只需运行./code -a或./code -b,就能让程序走不同的分支。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进