10.6 main()的参数

10.6.1 指向指针的指针

定义

指针是一种用“”和其他数据类型或函数类型构造出来的数据类型,因而也可以用“”与某种指针(比如“char ”)构造出指向指针的指针(比如“char *”)。可以用下面方式定义这种变量。

10.6 main()的参数 - 图1

这时称“p”是一个指向字符类型指针的指针变量(听起来有些拗口)。显然两个“*”中右面一个说明“p”是指针(根据结合性),其余的部分说明“p”指向的数据类型。

下面的定义也与指向指针的指针有关。

10.6 main()的参数 - 图2

这里定义的“a_p”由于首先与“[]”结合因此是一个数组名,“[]”内的“3”表明数组有3个元素,每个元素的类型皆为“char ”;由于数组名的值是指向数组起始元素的指针,因此“a_p”的值就是一个指向“char ”指针类型的指针(常量)。

如果定义:

10.6 main()的参数 - 图3

那么“&p_c”也是指向“char *”类型的指针常量。

能创作诗的程序

自然语言中一种常见的句式是“主语+谓语+宾语”,其中“主语”和“宾语”可以是名词,“谓语”要求是及物动词。而所谓的诗则要求压韵。根据这些规则,下面的代码可以自行创作四言诗。

程序代码10-7

10.6 main()的参数 - 图4

如图10-5所示,是这个程序批量生产的诗的样品。

10.6 main()的参数 - 图5

图10-5 能创作诗的程序

由于“故事”这样赤裸裸的字符串的类型是“char ”,而“zhuyu”作为数组名的值是指向起始元素的指针,因而类型是“char ”。这样当把“zhuyu”作为实参传值给形参时,对应形参的类型也就应该是“char ”,或者写作“char []”。两者形式不同,但本质一样。

了解了这一点,就可以研究main()函数的另一种标准的写法了。

10.6.2 main()函数的第二种写法

C语言代码中的main()除了可以写成:

10.6 main()的参数 - 图6

的形式,也可以写成:

10.6 main()的参数 - 图7

这样的形式。这里main()的两个形参的名字是任意的,但类型必须是“int”和“char []”(等价于“char *”)。其余各种形式的main()是不被C89、GB/T 15272-94承认的,而C99则认为那些是各种编译器自己的方言土语。

main()的两个形参来自何处?答案是来自操作系统或程序的调用者。控制台程序通常是在命令提示符后面用文字的方式启动的,如:

10.6 main()的参数 - 图8

其中“c:\可执行文件的名字.exe”部分是必须的,而后面跟几个参数则视程序启动要求而定。输入[CR]之后,操作系统将把命令行的各个被空白符分开的字符序列存储为字符串,然后把指向这些字符串首个字符的各个指针(俗称指向字符串的指针)组织成一个“char *[]”类型的数组,再把这个数组名及数组元素的的个数传入main(),这样main()在运行的时候就可以获得命令行中的信息了。

存储指向字符串的指针数组的类型,显然就是上一小节的程序代码10-7中“zhuyu”那样的类型,而这种数组名的值显然是“char ”类型的,因而需要main()对应的形参为“char *[]”或“char ”类型。在main()中若希望得到指向参数1的指针(实际是指向开头那个字符的指针),则可以通过运算“argv[1]”得到。

此外,C语言不保证一定能从“argv[0]”得到可执行文件的名字,在有些环境下“argv[0]”是一个指向""空字符串起始字节的指针。

下面代码演示了如何从命令行读取参数并输出。

程序代码10-8

10.6 main()的参数 - 图9

这个代码的执行效果,一般需要以命令行方式运行程序或在编译器中添加运行参数才能看出。如图10-6所示,是以命令行方式运行的结果。

10.6 main()的参数 - 图10

图10-6 main()函数的第二种写法

在Dev C++中添加运行参数的方法如图10-7所示。

10.6 main()的参数 - 图11

图10-7 添加运行参数

运行结果如图10-8所示。

10.6 main()的参数 - 图12

图10-8 在DevC++中运行结果

练习

编写程序,按照相反单词顺序输出命令行参数。