main的三种形式

Last Updated: 2024-03-27 07:36:29 Wednesday

-- TOC --

似乎只有入口函数main,可以有多种定义形式,有2个参数,有3个参数,或无参数,甚至可以没有返回值。

C99 标准中,以下两种定义main的方式都是正确的:

int main()  /* 无参数形式 */
{
    ...
    return 0;
}
int main(int argc, char *argv[]) /* 带参数形式 */
{
    ...
    return 0;
}

定义其它无参数函数的时候,建议都明确使用void作为参数,虽然不写也可以,但有的时候,如果不写void,正好出现这个函数的不一样的重复申明,正好你用的这个编译器连个warning都不给,那就浪费生命了......

ANSI C标准对main函数的形式,似乎没有那么严格,不写返回类型,不写void似乎都可以,经典的《The C Programming Language》这本书里面的代码,好多都这样!gcc这样的编译器应该可以支持,但新代码就不要这样写了!

return 0;表示执行成功!在main函数内,return和exit调用,效果是一样的!main甚至可以没有return。

由于main接口的特殊性,在main接口中,可以没有return语句,gcc和g++都没有warning...

参数argc,表示参数个数,argv这个指针数据,指向每一个参数。具体如下:

$ cat tt.c
#include <stdio.h>


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

    printf("argc = %d\n", argc);
    for (i=0; i<argc; i++)
        printf("argv[%d] = %s\n", i, argv[i]);

    return 0;
}

运行看一下:

$ ./tt
argc = 1
argv[0] = ./tt
$ ./tt a b c d e
argc = 6
argv[0] = ./tt
argv[1] = a
argv[2] = b
argv[3] = c
argv[4] = d
argv[5] = e

命令行的所有信息,全部都传递给main了!argv[0]表示运行的程序本身,后面按顺序赋值。这个规则也基本适用于其它传递命令行参数的编程场景,比如Python或Bash。

main还可以定义成有3个入参的形式,如下:

$ cat test_main.c
#include <stdio.h>


int main(int argc, char **argv, char **env) {
    char **p = env;
    while (*p) {
        printf("%s\n", *p);
        ++p;
    }
    return 0;
}

这第3个参数,指向了环境变量。上面这个示例,可以将所有默认的环境变量打印出来。

环境变量和main的其它入参,都是在main被调用之前,就已经准备好了的。

main这个入口还可以定义为没有返回值的形式:

void main(){...}

这种情况,虽然编译会有一个-Wmain告警,代码还可以运行,但是新代码强烈不建议使用。

其实,也很好理解main接口定义的多样性,因为调用main的_start,是一段预先写好的汇编代码。参数都在寄存器中准备好了,不管main接口有无参数,有几个参数,只会影响它自己对参数的使用而已。

trim

char *trim(char *p) {
    if (strlen(p) == 0)
        return p;

    while (isspace(*p))
        p++;

    char *t = p + strlen(p) - 1;
    while (isspace(*t))
        *t-- = '\0';

    return p;
}

写trim的初衷,是用来处理argv这个main参数,它的各个参数中,可能在前后都含有空格。main接口的argv指针数组中的每个指针,是可以修改的,type并没有用const这个qualifier。(参考:详解C语言的const申明

使用方法如下:

int main(int argc, char **argv) {
    // ...
    for (int i=0; i<argc; ++i)
        argv[i] = trim(argv[i]);
    // ...
}

将每个argv[i]指向第1个非space char,同时字符串末尾的space全部修改为\0,即让它前结束。

本文链接:https://cs.pynote.net/sf/c/202112046/

-- EOF --

-- MORE --