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 --