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$ */