中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言可變參數va_list

發布時間:2020-06-28 12:05:13 來源:網絡 閱讀:818 作者:暮色伊人 欄目:編程語言
#include<stdlib.h>
#include<stdio.h>
#include<stdarg.h>

/*
1. 使用va_list va_start va_arg va_end實現可變參數
*/
void simple_va_fun(int i, ...) {
	va_list arguments;
	int j = 0;
	int k, m;
	va_start(arguments, i);
	j = va_arg(arguments, int);
	m = va_arg(arguments, int);
	va_end(arguments);

	printf("%d,%d,%d\n",i,j,m);

}

/*
2. 固定參數函數
*/
void fixed_args_func(char x, int a, double b, char *c)
{	//打印參數在棧中的地址
	printf("x = 0x%p\n", &x);
	printf("a = 0x%p\n", &a);
	printf("b = 0x%p\n", &b);
	printf("c = 0x%p\n", &c);
}
/*
3. 實現自己的可變參數,實則是按順序從棧中取出參數的值
*/
void var_args_func(const char * fmt, ...) {
	char* ap;
	ap = (char *)&fmt + sizeof(fmt);

	int* int_ap = (int *)ap;
	printf("first:%d\n",*int_ap);

	int_ap = int_ap + 1;

	printf("second:%d\n",*int_ap);

	int_ap = int_ap + 1;// string start index
	char* c_ptr = (char*)int_ap;

	char* str = (char* )*int_ap;

	printf("&int_ap = 0x%p\n",int_ap);
	printf("&c_ptr  = 0x%p\n", c_ptr);
	printf("&str    = 0x%p\n",str);
	
	//棧里面存儲的是指向字符串"helloworld的指針",即二級字符指針
	printf("third1:	%s\n",str);
	printf("third2:	%s\n", *(char **)int_ap);



}
//stdarg.h 中提供的標準可變參數宏
void std_vararg_func(const char *fmt, ...) {
	va_list ap;
	va_start(ap, fmt);

	printf("%d\n", va_arg(ap, int));
	printf("%f\n", va_arg(ap, double));
	printf("%s\n", va_arg(ap, char*));

	va_end(ap);
}

int main() {

	
	//fixed_args_func('a',17, 5.40, "hello world");

	//char* p = "xiongwei";
	//printf("%d\n",sizeof(p));
	var_args_func("%d %d %s\n", 4, 5, "helloworld");
	printf("--------------------------------------\n");
	std_vararg_func("%d %f %s\n", 4, 5.4, "helloworld");

	system("pause");
	return 0;
}

對比一下 std_vararg_func和var_args_func的實現,va_list似乎就是char*, va_start似乎就是((char*)&fmt) + sizeof(fmt),va_arg似乎就是得到下一個參數的首地址。沒錯,多數平臺下stdarg.h中va_list, va_start和var_arg的實現就是類似這樣的。一般stdarg.h會包含很多宏,看起來比較復雜。在有的系統中stdarg.h的實現依賴some special functions built into thethe compilation system to handle variable argument lists and stack allocations,多數其他系統的實現與下面很相似:(Visual C++ 6.0的實現較為清晰,因為windows上的應用程序只需要在windows平臺間做移植即可,沒有必要考慮太多的平臺情況)。

output://

first:4

second : 5

& int_ap = 0x003EF968

& c_ptr = 0x003EF968

& str = 0x013780D4

third1 : helloworld

third2 : helloworld

--------------------------------------

4

5.400000

helloworld





實現Printf()函數:

#include "stdio.h"
#include "stdlib.h"
void myprintf( char* fmt, ... )         /* 一個簡單的類似于printf的實現,//參數必須都是int 類型 */
{
	char	* pArg = NULL;          /* 等價于原來的va_list */
	char	c;

	pArg	= (char *) &fmt;        /* 注意不要寫成p = fmt !!因為這里要對//參數取址,而不是取值 */
	pArg	+= sizeof(fmt);         /* 等價于原來的va_start */

	do
	{
		c = *fmt;
		if ( c != '%' )
		{
			putchar( c );   /* 照原樣輸出字符 */
		}else     {
			/*按格式字符輸出數據 */
			switch ( *++fmt )
			{
			case 'd':
				printf( "%d", *( (int *) pArg) );
				break;
			case 'x':
				printf( "%#x", *( (int *) pArg) );
				break;
			default:
				break;
			}
			pArg += sizeof(int);    /* 等價于原來的va_arg */
		}
		++fmt;
	}
	while ( *fmt != '\0' );
	pArg = NULL;                            /* 等價于va_end */
	return;
}


int main( int argc, char* argv[] )
{
	int	i	= 1234;
	int	j	= 5678;

	myprintf( "thefirst test:i=%d", i, j );
	myprintf( "thesecend test:i=%d; %x;j=%d;", i, 0xabcd, j );
	system( "pause" );
	return(0);
}


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

金寨县| 元谋县| 广东省| 铁岭县| 谢通门县| 大竹县| 郓城县| 建宁县| 广昌县| 诏安县| 黄大仙区| 汉阴县| 夏邑县| 溧阳市| 观塘区| 平邑县| 延川县| 新郑市| 江达县| 稷山县| 台州市| 淳化县| 渭源县| 涿鹿县| 铁力市| 西平县| 华容县| 岳池县| 纳雍县| 南溪县| 浏阳市| 孝感市| 北安市| 营口市| 临西县| 湘西| 罗江县| 尼木县| 赤壁市| 辽阳市| 玛纳斯县|