关于va_copy的问题,函数变参

问题描述

关于va_copy的问题,函数变参

#include
#include
void print(char* format,...);
void print(char* format,...)
{
va_list ptr;
va_list ptr_tmp;
va_start(ptr, format);
va_copy(ptr_tmp,ptr);
printf("print ptr: %p,%pn",format, ptr);

    vfprintf(stdout, format, ptr);
    vfprintf(stdout, format, ptr);

    printf("print ptr: %p,%pn",format, ptr);
    va_end(ptr);

}
int main()
{
int i=3,j=4;
char a[20]="hello world";
print("%d,%d,%sn",i,j,a);
return 0;
}

 为什么会产生段错误,
 而把第二个 vfprintf(stdout, format, ptr);改成
 vfprintf(stdout, format, ptr_tmp);就没有出现问题
时间: 2024-10-31 02:31:23

关于va_copy的问题,函数变参的相关文章

嵌入式 C 语言的可变参数表函数的设计

首先在介绍可变参数表函数的设计之前,我们先来介绍一下最经典的可变参数表printf函数的实现原理.一.printf函数的实现原理在C/C++中,对函数参数的扫描是从后向前的.C/C++的函数参数是通过压入堆栈的方式来给函数传参数的(堆栈是一种先进后出的数据结构),最先压入的参数最后出来,在计算机的内存中,数据有2块,一块是堆,一块是栈(函数参数及局部变量在这里),而栈是从内存的高地址向低地址生长的,控制生长的就是堆栈指针了,最先压入的参数是在最上面,就是说在所有参数的最后面,最后压入的参数在最下

利用可变参实现fprintf函数

#include <stdio.h> #include <stdarg.h> /* 可变参相关接口 typedef char * va_list ; void va_start (va_list ap , prev_param) ; type va_arg(va_list ap , type) ; void va_end(va_list ap); */ int myfprintf(FILE* fp, char* fmt, ...) { int ret = 0; va_list ar

C语言之可变参实现scanf函数

既然有printf函数可变参实现,那就一定有scanf函数的可变参实现.废话不多说,源码奉上: 本源码不过多分析,如要明白原理,请翻本博客以往的文章看说明. 欢迎关注新浪微博:http://weibo.com/u/1896293701/home?topnav=1&wvr=6 #include <stdio.h> #include <stdarg.h> int myscanf(const char *fmt , ...) ; int main(void) { int num

【整理】关于 va_copy 的兼容性问题

首先查看 Linux 下的 man 信息. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [root@Betty ~]# man va_copy STDARG(3)                  Linux Programmer's Manual                 STD

调用规范与可变参数表

语言调用规范是指进行一次函数调用所采用的传递参数的方法,返回值的处理以及调 用堆栈的清理.Microsoft C/C++ 语言中采用了五种调用规范,分别是__cdecl, __stdcall, __fastcall,thiscall和nake每一中调用规范都是利用eax作为返回值,如果 函数返回值是64位的,则利用edx:eax对来返回值.Nake调用规范非常的灵活,足以独立 的一篇文章描述,这里就不再描述nake调用规范.下表列出了前面四种规范调用的特点: 关键字 堆栈清理者 参数传递顺序 _

在Delphi与C++之间实现函数与对象共享

在Delphi中调用C++函数与C++调用Delphi函数相当直接,需要注意的是,Delphi 1默认的函数调用方式是Pascal方式,Delphi 4.Delphi 5的默认方式则是优化的cdecl调用方式,即register方式.要在C++ 与Delphi程序之间实现函数共享,除非有充分的原因,否则应该使用标准系统调用方式,即stdcall方式.为了使C++编译器不将函数标记为"mangled",使Delphi编译器误认为函数是采用cdecl调用方式,应该在C++代码中,以exte

n维数组实现(可变参数表的使用)

首先先介绍一下可变参数表需要用到的宏: 头文件:#include<cstdarg> void va_start( va_list arg_ptr, prev_param );  type va_arg( va_list arg_ptr, type );  void va_end( va_list arg_ptr );   va_list:用来保存宏va_start.va_arg和va_end所需信息的一种类型.为了访问变长参数列表中的参数,必须声明              va_list类型

C语言之linux内核可变参实现printf,sprintf

      昨天,我发表了一篇用可变参实现的fprintf函数,其实说实话还不完全是可变参实现的,因为用到了FILE * 这样的指针,需要包含stdio.h这个头文件才能实现这个函数,今天我们就来看看,如何抛弃stdio.h,全0开始实现printf , sprintf ,当然,这段代码是我在linux内核里面获取的,再经过我本人修改,移植,在DevC++这个编译环境中通过测试.我们来看看代码:       #include <stdarg.h> #define NULL 0 //如果字符串中

C语言“…”占位符及可变参数函数

C语言函数的参数传递总是固定了个数,那么有没有传递任意个数参数的方法呢?在C++中,函数重载提供了多种参数传递的解决办法,但也不是任意参数个数.事实上,C语言是提供任意数量参数的解决方案的. printf(),scanf()等就是这样一类可支持任意参数个数变量的函数,以下是printf的用法示例. 1 printf("%d",x); 2 printf("%f",y); 3 printf("Hello my name is %s", name);