1. 程式人生 > >可變引數列表原始碼的剖析

可變引數列表原始碼的剖析

C語言可變參簡介

  我們在C語言程式設計中會遇到一些引數個數可變的函式,例如printf()這個函式,它的定義是這樣的:
      int printf( const char* format, ...);
 它除了有一個固定引數format以外,後面還有很多引數的個數和型別都是可變的,例如,我們可以有一下不同的呼叫方法:
       printf("%d",i);
       printf("%s",s);

寫一個簡單可變引數的c函式

  模擬實現printf函式,沒有呼叫庫函式,實現print("s ccc\n","hello",'b','i','t');
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdarg.h>

void  print(char* str,...)
{
	const char*p=NULL;
	char ch;
	char c;
	va_list arg;
	va_start(arg,str);
	while(*str)
	{
		switch(*str)
		{
		case 's':
			p=va_arg(arg,const char*);
			while(*p)
			{
				putchar(*p);
				p++;
			}
			++str;
			break;
		case 'c':
			ch=va_arg(arg,char);
			putchar(ch);
			++str;
			break;
		case ' ':
			++str;
			putchar(' ');
			break;
		case'\n':
			putchar('\n');
			++str;
			break;
		default:
			break;
		}
	}
	va_end(arg);
}
int main()
{
	print("s ccc\n","hello",'b','i','t');
	return 0;
}
執行結果:
分析:  1)首先在函式裡定義一個va_list型的變數,這裡是arg_ptr,這個變數是指向引數的指標. 
  2)然後用va_start巨集初始化變數arg_ptr,這個巨集的第二個引數是第一個可變引數的前一個引數,是一個固定的引數. 
  3)然後用va_arg返回可變的引數,並賦值給整數j. va_arg的第二個引數是你要返回的引數的型別,這裡是int型.
  4)最後用va_end巨集結束可變引數的獲取.然後你就可以在函式裡使用第二個引數了.如果函式有多個可變引數的,依次呼叫va_arg獲取各個引數.