main函数参数解析和可变函数列表

main函数参数解析

    main函数是有参数的,只是我们使用main函数时,大多数情况下会省略参数。接下来我们看一下main函数的原型,并对main函数的三个参数进行解析。

main函数原型

解析:

       这里有三个参数。

       第一个参数:argc是一个整形变量,表示命令行参数的个数(含第一个参数)。

     第二个参数:argv是一个字符指针数组,每个元素是一个字符指针,指向一个字符串。这些字符串就是命令行中的每一个参数(字符串)

      第三个参数:envp是字符指针数组,数组的每一个元素是一个指向一个环境变量(字符串)的字符指针。

如下列程序:

运行结果与分析:

argv是一个指针数组,这个数组的每个元素都是一个字符指针,数组的末尾是一个NULL指针。argc的值和这个NULL值都用于确定实际传递了多少个参数。注:第一个参数就是程序的名称

 那么第三个参数有怎么解释呢?

可以看出第三个参数保存的是环境变量,envp数组的最后一个元素也存放NULL指针。

可变参数列表解析 

     在C语言中,可变参数是指一个函数在不同时刻接受不同的数目的参数,可以接受1个以上的任意多个参数(不固定)

先看一个例子:实现一个函数可以求任意个参数的平均值。

分析:此函数要实现求任意个参数的平均值,由于参数的个数是不固定的,所以应该使用可变参数列表。程序实现如下:

int average(int n,...)
{
	va_list arg;
	int i=0; 
	int sum = 0;
	va_start(arg, n);
	for(i=0; i<n; i++)
	{
		sum += va_arg(arg,int);
	}
	va_end(arg);
	return sum/n;
}

int main()
{
	cout<<average(5,1,2,3,4,5)<<endl;
	system("pause");
}

观察上面程序我们可能会对va_list、va_start、va_arg、va_end感到陌生,通过在vc6.0编译器中转到定义出,我们可以发现va_start、va_arg、va_end个是宏,va_list 和char* 类型的变量。具体的分析如下:

       通过上面的分析,我们可以看到可变参数是通过宏来实现的,这些宏定义在stdarg.h头文件中,它是标准库的一部分。这个头文件声明了一个类型va_list和三个宏----va_start、va_arg、va_end。我们可以声明一个类型为va_list的变量,与这些宏配合使用,访问参数的值。 注意参数列表中的省略号:它提示此处可能传递的数量和类型未确定的参数。参数列表中的可变部分位于一个或多个普通参数的后面。

下面这个程序具体进行分析:

         1. 声明一个va_list类型的变量arg,它用于访问参数列表的未确定部分。

        2. arg是通过va_list进行初始化。它的第一个参数是va_list的变量名,第2个参数是省略号前最后一个有名字的参数。初始化过程把arg变量设置为指向可变参数部分的第一个参数。

         3. 使用va_arg访问参数。

         4. 当访问完毕后,调用va_end将arg置为NULL指针 。

可变参数的限制

        1. 可变参数必须从头到尾逐个访问。

        2.参数列表中至少有一个命名参数。如果一个命名参数都没有,就无法使用va_start.

        3.如果在va_arg中指定了错误的类型,那么其后果是不可预测的。

        4. 这些宏是无法直接判断实际存在参数的数量,这些宏无法判断每个参数的类型。

通过上面分析,实现求任意多个数的最大值。

int Max(int n,...)
{
	va_list arg;
	int i=0;
	int max = 0x80000000;
	va_start(arg,n);
	for(; i<n; i++)
	{
		int tmp = va_arg(arg,int);
		if(max < tmp)
		{
			max = tmp;
		}
	}

	va_end(arg);
	return max;
}

int main()
{
	int ret = Max(3, -1,-2,-3);
	cout<<ret<<endl;
	return 0;
}

    在我们学习过程中,经常使用的printf函数就是利用可变参数实现的,printf函数中的命名参数是格式字符串,它不仅指定了参数的数量(通过几个%可以确定有几个参数),而且指定了参数的类型(d、s、ld等表示类型)。但底层实现相对比较复杂,有兴趣可以进行了解。

猜你喜欢

转载自blog.csdn.net/smile_zhangw/article/details/81098343