可变参数宏

   
// 可变参数宏.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define va_start_test(ap, v) (ap = (va_list)&(v) + _INTSIZEOF(v))
#define va_arg_test(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end_test(ap)      ( ap = (va_list)0 )

void Va_fn1(char* dest, ...) {
	va_list ap;
	char* p_dest = dest;
	char** n_dest = &dest;
	va_start_test(ap, dest);
	/*之前没理解(ap = (va_list)&(v) + _INTSIZEOF(v)),为什么不能用一级指针 而非得用&v,以为用dest指针加上他的内存大小可能够得到下一个参数的地址了,
	误以为dest指向的内存和下一个参数的内存是相连的,其实是错误的,va_start宏是利用参数入栈的顺序和地址连续来取得可变参数的地址,在函数堆栈之中 所传递的dest指针所在堆栈上的地址和下一个可变参数指针所在
	堆栈上地址才是连续的,因此用到二级指针,参数可能所占内存不尽相同,但是不同指针永远都占相同的内存,因此能取得可变参数。(va_list)&dest + _INTSIZEOF(dest) 后得到 针对于堆栈上 第一个可变参数的地址,
	这里为什么强制转换为va_list类型,是因为&dest是一个二级指针,指针+1是根据所指向的类型的大小决定的,如果用&dest + _INSIZEOF(dest)在函数堆栈上超过了下一个可变参的地址。*/
	char** gf = &dest + _INTSIZEOF(dest);
	char*  gf1 = (va_list)&dest + _INTSIZEOF(dest);
	printf("%s\n", &dest + _INTSIZEOF(dest));
	printf("%s\n", *(char**)ap);
	int a = 1;
	int* qa = &a;
	printf("qa = %p\n", qa);
	printf("qa + 1 = %p\n", qa + 1);
	char ch = 'c';
	char* qch = &ch;
	printf("qch = %p\n", qch);
	printf("qch + 1 = %p\n", qch + 1);
}

int _tmain(int argc, _TCHAR* argv[])
{
	Va_fn1("guifan", "Hello", "OK", NULL);  
	char* a[3] = {"guifan", "Hello", "OK"};
	printf("a[0] = %d\n", _INTSIZEOF(a[0]));
	printf("a[1] = %d\n", _INTSIZEOF(a[1]));
	printf("a[2] = %d\n", _INTSIZEOF(a[2]));
	char* p1 = a[0];
	char** p2 = a;
	char* p3 = (char *)&a[0] + _INTSIZEOF(a[0]);
	char* p4 = (char *)a[0] + _INTSIZEOF(a[0]);
	printf("p1 = %p\n", p1);
	printf("p1 + 1 = %p\n", p1 + 1);

	printf("p2 = %p\n", p2);
	printf("p2 + 1 = %p\n", p2 + 1);
	printf("p2 !%s\n", *(p2 + 1));
	
	printf("p3 = %p\n", p3);
	
	printf("p4 = %p\n", p4);
	printf("*p4 = %c\n", *p4);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值