目录

1 不同操作系统的main函数

2 带参 main 函数的格式

2.1 格式定义

2.2.参数解释

2.2.1 argc (Argument Count)

2.2.2 argv (Argument Vector)

3 示例

3.1 标准示例

3.2 简易计算器(支持 + - * /)

3.2.1 目标

3.2.2 atoi() —— 字符串转整数函数

3.2.3 代码示例

3.3.4 注意事项

3.3.5 编译运行

4 Linux 命令与 main 的关系

4.1 编写 ls 命令

4.2 编写 cat 命令和 cp 命令


1 不同操作系统的main函数

Windows 上,main 函数通常是这样的:

int main(void)

这是因为其 main 函数并不会直接传递命令行参数,而是通过操作系统提供的 API(比如 GetCommandLine)来获取命令行参数。这意味着,Windows 系统下的 main 函数通常是没有参数的,系统通过内部机制来管理参数的传递。

而在 Linux 系统下,几乎所有的命令都是可执行程序,这些程序都在用户空间运行,并且可以通过命令行接收参数。例如:

  • ls -l /home

  • cp a.txt b.txt

这正是因为这些命令在其源代码中使用了 带参数的 main 函数。

int main(int argc, char *argv[])

2 带参 main 函数的格式

2.1 格式定义

int main(int argc, char *argv[])
  • intmain 函数的返回类型为 int,表示程序执行结束后的退出状态。通常,返回 0 表示程序成功执行,返回非零值表示出现错误。

  • main:程序执行的入口点。

  • argc:一个整数,表示传递给程序的命令行参数的数量(包括程序名)。

  • argv:一个字符指针数组(char *argv[]),包含了传递给程序的所有命令行参数。每个元素是一个指向字符串的指针,表示一个命令行参数。

2.2.参数解释

2.2.1 argc (Argument Count)

  • 类型int

  • 说明argc 表示命令行中传递给程序的参数个数。它至少为 1,因为 argv[0] 总是程序的名称或路径。

    例如,假设命令行输入为:

    ./myprogram arg1 arg2 arg3
    

    那么,argc 将为 4,因为包括程序名称 ./myprogram,总共有 4 个参数。

2.2.2 argv (Argument Vector)

  • 类型char *argv[]char **argv(其实是一个指向字符串的指针数组,也可以理解为二维数组)

  • 说明argv 是一个数组,每个元素是一个指向字符串的指针,表示一个命令行参数。argv[0] 是程序的名称(或路径),argv[1] 是第一个参数,argv[2] 是第二个参数,依此类推,argv[argc] 是一个 NULL 指针,用来标示参数的结束。

    继续上面的例子:

    ./myprogram arg1 arg2 arg3
  • argv[0] 会是 "./myprogram"(程序名)。

  • argv[1] 会是 "arg1"

  • argv[2] 会是 "arg2"

  • argv[3] 会是 "arg3"

  • argv[4]NULL,表示参数的结束。

3 示例

3.1 标准示例

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("程序名称: %s\n", argv[0]);  // 输出程序名
    printf("传递给程序的参数个数: %d\n", argc - 1);  // 输出参数个数(不包括程序名)

    // 打印所有命令行参数
    for (int i = 1; i < argc; i++) {
        printf("参数 %d: %s\n", i, argv[i]);
    }

    return 0;
}

编译和运行:

假设保存为 example.c 文件:

gcc -o example example.c
./example arg1 arg2 arg3

输出:

3.2 简易计算器(支持 + - * /)

3.2.1 目标

  • 使用 atoi() 将命令行参数转换成整数

  • 分层实现计算器功能

  • 支持四则运算

  • 使用命令行参数输入运算符

3.2.2 atoi() —— 字符串转整数函数

头文件

#include <stdlib.h>

函数原型

int atoi(const char *str);

函数参数

函数参数 参数类型 参数功能
str const char* 指向一个以 null 结尾的字符串。该字符串应表示一个整数。

返回值

返回值 返回值类型 返回值功能
整数值 int 返回字符串 str 表示的整数值。如果字符串不是有效的整数,返回 0。
注意:如果字符串中有非数字字符,函数会将其停止,并只转换有效部分。

函数功能

atoi() 将一个以 null 结尾的字符串转换为整数。

  • 如果字符串有效且表示一个整数,atoi() 将其转换为相应的整数类型。

  • 如果字符串不代表有效的整数(如包含非数字字符),函数返回 0。

  • 该函数不做任何错误处理,例如对于溢出的情况不抛出异常。

  • 通常用于将字符串输入转换为整数,在处理用户输入时使用。

  • 对于更安全的转换,可以使用 strtol(),因为 atoi() 无法检测溢出等问题。

3.2.3 代码示例

#include <stdio.h>
#include <stdlib.h>  // atoi()

int main(int argc, char *argv[])
{
    int a, b;

    // 判断参数个数是否正确
    if(argc != 4)
    {
        printf("Usage: %s num1 operator num2\n", argv[0]);
        return -1;
    }

    a = atoi(argv[1]);
    b = atoi(argv[3]);

    // 根据运算符执行运算
    switch(*argv[2])
    {
        case '+': printf("%d\n", a + b); break;
        case '-': printf("%d\n", a - b); break;
        case '*': printf("%d\n", a * b); break;
        case '/': 
            if(b != 0) 
                printf("%f\n", (float)a / b); 
            else 
                printf("Division by zero!\n");
            break;
        default: 
            printf("Unsupported operator: %s\n", argv[2]);
    }

    return 0;
}

3.3.4 注意事项

  • 乘法符号 * 在 Linux shell 中可能被解释为通配符,需要用 双引号 包裹,例如:

./a.out 3 "*" 5
15
  • 除法需要注意除数不能为零

3.3.5 编译运行

4 Linux 命令与 main 的关系

Linux 下的命令实际上是可执行文件,它们通常存放在系统的 /bin/sbin 目录下,像 lscp 等都是可执行程序。对于这些命令的可执行程序,其程序入口点就是 main 函数main 函数负责启动命令行程序并处理输入的参数。通过 argcargv,程序可以获取传递给它的所有命令行选项和参数,从而控制程序的行为。

示例:

4.1 编写 ls 命令

要用带参数的 main 函数编写一个简化版的 ls 命令,我们需要处理命令行参数,解析文件和目录,并列出它们的内容。我们将创建一个程序,模仿 ls 命令的基本功能,列出当前目录中的文件和目录。

目标功能:

  1. 基本列出文件和目录:不带参数时列出当前目录下的文件和子目录。

  2. 支持指定路径:允许用户通过命令行参数指定路径(例如 ls /path/to/dir)。

程序代码:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(int argc, char *argv[]) {
    const char *dir_path = ".";  // 默认路径是当前目录
    
    // 如果传递了路径作为参数,则使用该路径
    if (argc > 1) {
        dir_path = argv[1];
    }

    // 打印目录路径,确认是否正确
    printf("尝试打开目录: %s\n", dir_path);

    DIR *dir = opendir(dir_path);
    if (dir == NULL) {
        perror("opendir");
        return 1;
    }

    struct dirent *entry;

    // 列出目录内容
    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n", entry->d_name);  // 直接列出文件/目录名称
    }

    closedir(dir);
    return 0;
}

代码解释:

  • 如果指定了路径(例如 ./ls /home/user),则使用指定的路径。如果没有指定路径,则默认列出当前目录 .

  • 使用 opendirreaddir 打开目录并列出内容。

编译和运行:

编译:

gcc -o myls myls.c

运行:

  • 列出当前目录中的文件:

    ./myls

  • 列出指定目录的文件:

    ./myls /path/to/directory

4.2 编写 cat 命令和 cp 命令

请移步到

2.4 文件 I/O示例

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐