器→工具, 术→技巧, 研发, 编程语言

C语言:main()函数正确写法

钱魏Way · · 849 次浏览

C语言虽然是一门古老的语言,但是其标准一直在完善,所以很多以前支持的语法在到当前已经不能在使用了。

C语言的版本历史

C语言的版本历史:

  • 【K&R C】 1978 年,Brian Kernighan和Dennis Ritchie 合作推出了《The C Programming Language》的第一版,该书被简称为K&R(取了作者名字的首字母)。书末的参考指南 (Reference Manual) 一节给出了当时 C 语言的完整定义,成为那时 C 语言事实上的标准,人们称之为 K&R C。从这一年以后,C 语言被移植到了各种机型上,并受到了广泛的支持,使 C 语言在当时的软件开发中几乎一统天下。
  • 【C89】(ANSI C) 随着 C 语言在多个领域的推广、应用,一些新的特性不断被各种编译器实现并添加进来。于是,建立一个新的“无歧义、于具体平台无关的 C 语言定义”成为越来越重要的事情。1983 年,ASC X3(ANSI 属下专门负责信息技术标准化的机构,现已改名为 INCITS)成立了一个专门的技术委员会 J11(J11 是委员会编号,全称是 X3J11),负责起草关于 C 语言的标准草案。1989 年,草案被 ANSI 正式通过成为美国国家标准,被称为 C89 标准。
  • 【C90】(ISO C) 随后,《The C Programming Language》第二版开始出版发行,书中内容根据 ANSI C(C89)进行了更新。1990 年,在 ISO/IEC JTC1/SC22/WG14 (ISO/IEC 联合技术第 I 委员会第 22 分委员会第 14 工作组) 的努力下,ISO 批准了ANSI C成为国际标准。于是 ISO C(又称为 C90) 诞生了。除了标准文档在印刷编排上的某些细节不同外,ISO C(C90) 和 ANSI C(C89) 在技术上完全一样。 (ISO/IEC 9899:1990)
  • 【C95】 之后,ISO 在 1994、1996 年 分别出版了 C90 的技术勘误文档,更正了一些印刷错误,并在1995 年通过了一份 C90 的技术补充,对 C90 进行了微小的扩充,经过扩充后的 ISO C 被称为 C95。
  • 【C99】 1999 年,ANSI 和 ISO 又通过了最新版本的 C 语言标准和技术勘误文档,该标准被称为 C99 。这基本上是目前关于 C 语言的最新、最权威的定义了。(ISO/IEC 9899:1999
  • 【C11】指ISO标准ISO/IEC 9899:2011,这次修订新增了被主流C语言编译器(如GCC,Clang,Visual C++等)增加的内容,和引入了内存模型以更好的执行多线程。之前C99的一些被推迟的计划在C11中增加了,但是对C99仍保留向后兼容。
  • 目前最新版:ISO/IEC 9899:2018

main()函数的正确写法

常见的写法:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

能否写成“void main()” 或“main()”

void main() { /* … */ }  在C或者C++的标准中从未出现过,一个合适的可被接受的定义为:int main() { /* … */ } 和int main(int argc, char* argv[]) { /* … */ } 。main函数返回int类型是向调用它的“系统”返回信息的方式,返回0则表示成功,其他数字则可以定义为错误或异常。虽然使用void main() { /* … */ } 能在C语言中编译通过,但是还是不建议使用。另外C++规定必须在main()函数中必须包含return语句。

main() { /* … */ } ,在ISO C++和C99中是可以省略函数的返回类型的(但会出现如下警告信息:warning: return type defaults to ‘int’ [-Wimplicit-int]),但是在C89和 ARM C++中必须声明返回数据的类型,因为其不会将其默认假定为”int”.

与不同的是,在函数声明中缺少类型时,不会假定为”int”。

“return 0” 能否省略

程序不写return 0是可以编译通过的,但是就像前面讲的,C++规范中规则了必须在main()函数中必须包含return语句。所以一切还是按照标准比较好。

“int main()”和“int main(void)”的区别

在C++中两者是没有区别的,但是在C语言中却存在差别,都是表示函数不接受任何参数。而在C语言中,int main(void)表示不接受任何参数,但是int main()则表示该函数可以接受任意参数或不接受参数。正常情况下加或者不加影响不大,建议还是加上void好。

C程序的入口真的是main函数吗?

对于大部分C程序员来说,我们通常认为程序的入口是 main 函数,因为这通常是我们开始编写代码的地方,而且程序的执行也确实从这里开始。然而,实际上在 main 函数被调用之前,C运行时库(C Runtime Library)已经进行了一些初始化工作。

以下是在调用 main 函数之前,C运行时库通常会执行的一些步骤:

  • 设置程序的运行环境: 这包括初始化进程堆,处理命令行参数,设置环境变量等。
  • 调用全局对象的构造函数: 如果程序中包含了全局对象,那么这些对象的构造函数(如果有的话)需要在 main 函数被调用之前执行。

只有在完成了这些初始化工作之后,C运行时库才会调用 main 函数。因此,从这个角度来看,C程序的实际入口并不是 main 函数,而是C运行时库的入口点。这个入口点的名称取决于操作系统和编译器,例如在Linux系统中,使用GCC编译器,这个入口点通常是一个名为 _start 的函数。

然而,对于大部分应用程序开发者来说,这些细节通常是透明的,我们可以继续把 main 函数视为程序的入口。

C语言命令行参数

在C语言中,可以通过命令行参数来向程序传递信息。这些参数在程序启动时由操作系统传递给主函数main。主函数的标准声明包含两个参数,用于接收命令行参数:

int main(int argc, char *argv[]) {
    // ...
}

这里,argc和argv分别是”argument count”(参数数量)和”argument vector”(参数向量)的缩写。具体解释如下:

  • argc:这是一个整数,表示命令行参数的数量。当没有参数时,argc的值为1,因为命令行总是包含执行程序的名字作为第一个参数。
  • argv:这是一个指针数组,每个元素都是一个字符指针,指向一个命令行参数的字符串。argv[0]总是指向程序的名字,argv[1]指向第一个参数,argv[2]指向第二个参数,以此类推。argv[argc]是一个空指针。

例如,如果你在命令行输入以下命令:

./program arg1 arg2

那么,argc的值为3,argv[0]的值为”./program”,argv[1]的值为”arg1″,argv[2]的值为”arg2″,argv[3]的值为NULL。

你可以在main函数中使用这些参数来控制你的程序的行为。例如,你可以根据命令行参数的值来选择不同的输入文件、输出文件,或者选择不同的操作模式等。

下面是一个使用命令行参数的示例程序,该程序将输出所有传入的命令行参数。

#include <stdio.h>

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

    // 输出参数数量
    printf("Total arguments passed: %d\n", argc);

    // 遍历每个参数并输出
    for (i = 0; i < argc; i++) {
        printf("Argument %d: %s\n", i, argv[i]);
    }

    return 0;
}

编译并运行这个程序的方法(假设你的源文件名为args_example.c):

编译程序:

gcc args_example.c -o args_example

运行程序,传入一些参数:

./args_example hello world example

输出应该类似于:

Total arguments passed: 4
Argument 0: ./args_example
Argument 1: hello
Argument 2: world
Argument 3: example

这个简单的示例展示了如何在C程序中接收和处理命令行参数。argv[0]通常是程序的名称或路径,真正的用户输入参数从argv[1]开始。

使用命令行参数,你可以让程序行为根据传入的参数变化,从而提高程序的通用性和适应性。例如,你可以根据传入的参数决定读取哪个文件、应用哪个算法或设置不同的运行模式等。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注