【查错】关于标准printf()函数的具体实现中的问题

1.//========================================================================================================
/*2018-05-25
File:	push_test1
功能:手动确定可变参数的标准printf()函数
*/
#include "stdio.h"

struct person
{
	char * name;
	int age;
	char score;
	int id;
	
};

/*参考标准函数:int printf(const char * format, ...)
*依据:x86平台,函数调用时参数的传递是使用堆栈来实现的
*目的:将所有传入的参数全部打印出来
*/
int push_test(const char * format, ...)
{
	volatile char *p = (char *)&format;
	//char *p = &format;
	int i;
	struct person per;
	char c;
	double d;
	
	printf("arg1:	%s\n", format);
	//printf("&format = %p\n", p);
	
	p = p + sizeof(char *);
	i = *((int *)p);
	p = p + sizeof(int);
	printf("arg2:	%d\n", i);
	//printf("&i = %p, p = %p\n", &i, p);
	

	per = *((struct person*) p);
	p = p + sizeof(struct person);
	printf("arg3:	.name = %s, .age = %d, .score = %c, .id = %d\n", per.name, per.age, per.score, per.id);
	//printf("&per = %p, p = %p\n", &per, p);
	
	
	c = *((char *)p);
	p = p + ((sizeof(char) + 3) & (~3));
	printf("arg4:	c = %c\n", c);
	
	
	d = *((double *)p);
	p = p + (sizeof(double) & (~3));
	printf("arg5:	d = %lf\n", d);    //输出格式符为 %f或%lf,输出结果都一样  arg5:  d = 3.140000
	
	
	return 0;
}

int main(void)
{
	struct person per = {"zhangsan", 15,  'A', 003};
	push_test("abcd", 123, per, 'W', 3.14);
	
	return 0;
}
/*
1.第31行屏蔽前后,程序的运行结果:
【屏蔽前】[email protected]:~/workbook/hardware/UART/push_test1$ ./push_test
arg1:   abcd
arg2:   -134643712
&i = 0xffc48054, p = 0xffc48050
arg3:   .name = <?, .age = -3899308, .score = , .id = -3899308
【屏蔽后】[email protected]:~/workbook/hardware/UART/push_test1$ gcc -m32 -o push_test push_test.c
[email protected]:~/workbook/hardware/UART/push_test1$ ./push_test
arg1:   abcd
arg2:   123
arg3:   .name = zhangsan, .age = 15, .score = A, .id = 3
[email protected]:~/workbook/hardware/UART/push_test1$
2.
push_test.c:30:9: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘char *’ [-Wformat=]
printf("&format = %#x\n", p);
3.屏蔽第24,31,37,43句前,程序的运行结果:
【屏蔽前】[email protected]:~/workbook/hardware/UART/push_test1$ gcc -m32 -o push_test push_test.c
[email protected]:~/workbook/hardware/UART/push_test1$ ./push_test
arg1:   abcd
&format = 0xffc23e5c
arg2:   -135135232
&i = 0xffc23e64, p = 0xffc23e60
arg3:   .name = <?, .age = -4047260, .score = , .id = -4047260
&per = 0xffc23e6c, p = 0xffc23e64
[email protected]:~/workbook/hardware/UART/push_test1$
【屏蔽后】
[email protected]:~/workbook/hardware/UART/push_test1$ gcc -m32 -o push_test push_test.c
[email protected]:~/workbook/hardware/UART/push_test1$ ./push_test
arg1:   abcd
arg2:   123
arg3:   .name = zhangsan, .age = 15, .score = A, .id = 3
[email protected]:~/workbook/hardware/UART/push_test1$
为什么啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊??????????????????
4.最终的运行结果为
[email protected]:~/workbook/hardware/UART/push_test1$ ./push_test
arg1:   abcd
arg2:   123
arg3:   .name = zhangsan, .age = 15, .score = A, .id = 3
arg4:   c = W
arg5:   d = 3.140000
[email protected]:~/workbook/hardware/UART/push_test1$
*/
2.//========================================================================================================
/*2018-05-25
File:	push_test1
功能:
*/
#include <stdio.h>
#include <stdarg.h>

struct person
{
	char * name;
	int age;
	char score;
	int id;
	
};

/*参考标准函数:int printf(const char * format, ...)
*依据:x86平台,函数调用时参数的传递是使用堆栈来实现的
*目的:将所有传入的参数全部打印出来
*/
int push_test(const char * format, ...)
{
	//volatile char *p = (char *)&format;
	//char *p = &format;
	int i;
	struct person per;
	char c;
	double d;
	
	va_list p;
	
	printf("arg1:	%s\n", format);
	//printf("&format = %p\n", p);
	
	//p = p + sizeof(char *);
	va_start(p, format);
	
	//i = *((int *)p);
	//p = p + sizeof(int);
	i = va_arg(p, int);
	printf("arg2:	%d\n", i);
	//printf("&i = %p, p = %p\n", &i, p);
	

	//per = *((struct person*) p);
	//p = p + sizeof(struct person);
	per = va_arg(p, struct person);
	printf("arg3:	.name = %s, .age = %d, .score = %c, .id = %d\n", per.name, per.age, per.score, per.id);
	//printf("&per = %p, p = %p\n", &per, p);
	
	
	//c = *((char *)p);
	//p = p + ((sizeof(char) + 3) & (~3));
	c = va_arg(p, int);
	printf("arg4:	c = %c\n", c);
	
	
	//d = *((double *)p);
	//p = p + (sizeof(double) & (~3));
	d = va_arg(p, double);
	printf("arg5:	d = %lf\n", d);
	
	va_end(p);
	
	return 0;
}

int main(void)
{
	struct person per = {"zhangsan", 15,  'A', 003};
	push_test("abcd", 123, per, 'W', 3.14);
	
	return 0;
}
/*
当 //volatile char *p = (char *)&format;  未修改为:
va_list p; 时,编译链接的结果如下:
In file included from push_test.c:7:0:
push_test.c: In function ‘push_test’:
push_test.c:35:11: warning: passing argument 1 of ‘__builtin_va_start’ from incompatible pointer type [-Wincompatible-pointer-types]
  va_start(p, format);
           ^
push_test.c:35:11: note: expected ‘char **’ but argument is of type ‘volatile char **’
push_test.c:62:9: warning: passing argument 1 of ‘__builtin_va_end’ from incompatible pointer type [-Wincompatible-pointer-types]
  va_end(p);
         ^
push_test.c:62:9: note: expected ‘char **’ but argument is of type ‘volatile char **’push_test。c:35:11:注意:预期“char **”,但参数是“volatile char **”
push_test.c:39:16: error: first argument to ‘va_arg’ not of type ‘va_list’
  i = va_arg(p, int);
                ^
push_test.c:46:18: error: first argument to ‘va_arg’ not of type ‘va_list’
  per = va_arg(p, struct person);
                  ^
push_test.c:53:16: error: first argument to ‘va_arg’ not of type ‘va_list’
  c = va_arg(p, char);
                ^
push_test.c:59:16: error: first argument to ‘va_arg’ not of type ‘va_list’
  d = va_arg(p, double);
                ^
//--------------------------最终的输出结果为:--------------------------//
[email protected]:~/workbook/hardware/UART/push_test2$
[email protected]:~/workbook/hardware/UART/push_test2$ ./push_test
arg1:   abcd
arg2:   123
arg3:   .name = zhangsan, .age = 15, .score = A, .id = 3
arg4:   c = W
arg5:   d = 3.140000
[email protected]:~/workbook/hardware/UART/push_test2$

*/

3.//==============================================================================================
/*2018-05-25
File:	push_test2
功能:
*/
#include <stdio.h>
//#include <stdarg.h>
typedef char * va_list;    //错误写法:typedef (char *) va_list; error: expected identifier or ‘(’ before ‘char’typedef (char *) va_list;
#define		_INTSIZEOF(n)	((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))	//错误:sizeof写成siezeof
#define	va_start(ap, v)	(ap = (va_list)&v + _INTSIZEOF(v))							
//#define 	va_arg(ap, t)	(*(t *)(ap +=  _INTSIZEOF(t) - _INTSIZEOF(t)))			//错误:*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))写成
																							*(t *)(ap +=  _INTSIZEOF(t) - _INTSIZEOF(t))
#define 	va_arg(ap, t)	(*(t *)(ap +=  _INTSIZEOF(t) - _INTSIZEOF(t)))
#define 	va_end(ap)		(ap = (va_list)0)


//typedef char *  va_list;
//#define 	_INTSIZEOF(n)		((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
//#define 	va_start(ap, v)		(ap = (va_list)&v + _INTSIZEOF(v))		
//#define 	va_arg(ap, t) 		(*(t *)(ap += _INTSIZEOF(t), ap - _INTSIZEOF(t)))  
//#define 	va_end(ap)	 		(ap = (va_list)0)

struct person
{
	char * name;
	int age;
	char score;
	int id;
};

/*参考标准函数:int printf(const char * format, ...)
*依据:x86平台,函数调用时参数的传递是使用堆栈来实现的
*目的:将所有传入的参数全部打印出来
*/
int push_test(const char * format, ...)
{
	//volatile char *p = (char *)&format;
	//char *p = &format;
	int i;
	struct person per;
	char c;
	double d;
	//volatile char *p = (char *)&format;
	va_list p;
	
	printf("arg1:	%s\n", format);
	//printf("&format = %p\n", p);
	
	//p = p + sizeof(char *);
	va_start(p, format);
	
	//i = *((int *)p);
	//p = p + sizeof(int);
	i = va_arg(p, int);
	printf("arg2:	%d\n", i);
	//printf("&i = %p, p = %p\n", &i, p);
	

	//per = *((struct person*) p);
	//p = p + sizeof(struct person);
	per = va_arg(p, struct person);
	printf("arg3:	.name = %s, .age = %d, .score = %c, .id = %d\n", per.name, per.age, per.score, per.id);
	//printf("&per = %p, p = %p\n", &per, p);
	
	
	//c = *((char *)p);
	//p = p + ((sizeof(char) + 3) & (~3));
	c = va_arg(p, int);
	printf("arg4:	c = %c\n", c);
	
	
	//d = *((double *)p);
	//p = p + (sizeof(double) & (~3));
	d = va_arg(p, double);
	printf("arg5:	d = %lf\n", d);
	
	va_end(p);
	
	return 0;
}

int main(void)
{
	struct person per = {"zhangsan", 15,  'A', 003};
	push_test("abcd", 123, per, 'W', 3.14);
	
	return 0;
}
/*
1.最终的运行结果为
[email protected]:~/workbook/hardware/UART/push_test1$ ./push_test
arg1:   abcd
arg2:   123
arg3:   .name = zhangsan, .age = 15, .score = A, .id = 3
arg4:   c = W
arg5:   d = 3.140000
[email protected]:~/workbook/hardware/UART/push_test1$
*/


猜你喜欢

转载自blog.csdn.net/weixin_39420903/article/details/80437124