各位大侠,这个问题怎么解决?

DentistryDoctor 2004-08-13 10:01:21
我声明了形如下面的函数

void FunctionName(...);

请问我怎么在函数体中知道调用端传入了多少个参数,参数类型和参数值呢?

用汇编解决也行。
...全文
182 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
大家可以继续答,如果比较好的,另外开帖送上500大洋。
DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
我仔细看看楼上说的,可偶的汇编不太好哟
gwinner 2004-08-13
  • 打赏
  • 举报
回复
参考一下这个
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=824
DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
我就是不要fmt!!!
softcar 2004-08-13
  • 打赏
  • 举报
回复
void FunctionName(fmt,...);
这样吧,类似于printf的格式!

DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
我是想实现一个宏
放在函数体内不管函数是如何声明的都倾印它的参数列表。能实现不?
pacman2000 2004-08-13
  • 打赏
  • 举报
回复
函数的声明和调用的地方是有的啊,那里就有参数的啊
DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
这个问题无解?那VC的调试器是怎样的呢?
pacman2000 2004-08-13
  • 打赏
  • 举报
回复
比如传的参数究竟是int还是char*,是没有办法区分的。
softcar 2004-08-13
  • 打赏
  • 举报
回复
流星说得没错。
pacman2000 2004-08-13
  • 打赏
  • 举报
回复
没有办法不指定的,因为栈的数据是连续的,可以看成是参数,也可以看成是定义的变量什么的,并没有特殊的标志表明在哪里是参数结束。
DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
楼上这位老兄不会是传教士吧.
  • 打赏
  • 举报
回复
创建新进程:fork函数
========================

fork函数干什么?
----------------------

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
‘fork()’函数用于从已存在进程中创建一个新进程。新进程称为子进程,而原进程称为
父进程。你可以通过检查‘fork()’函数的返回值知道哪个是父进程,哪个是子进程。父
进程得到的返回值是子进程的进程号,而子进程则返回0。以下这个范例程序说明它的基本
功能:
pid_t pid;
switch (pid = fork())
{
case -1:
/* 这里pid为-1,fork函数失败 */
/* 一些可能的原因是 */
/* 进程数或虚拟内存用尽 */
perror("The fork failed!");
break;
case 0:
/* pid为0,子进程 */
/* 这里,我们是孩子,要做什么? */
/* ... */
/* 但是做完后, 我们需要做类似下面: */
_exit(0);
default:
/* pid大于0,为父进程得到的子进程号 */
printf("Child's pid is %d\n",pid);
}

当然,有人可以用‘if() ... else ...’语句取代‘switch()’语句,但是上面的形式是
一个有用的惯用方法。
知道子进程自父进程继承什么或未继承什么将有助于我们。下面这个名单会因为
不同Unix的实现而发生变化,所以或许准确性有了水份。请注意子进程得到的是
这些东西的 *拷贝*,不是它们本身。
由子进程自父进程继承到:
* 进程的资格(真实(real)/有效(effective)/已保存(saved) 用户号(UIDs)和组号(GIDs))
* 环境(environment)
* 堆栈
* 内存
* 打开文件的描述符(注意对应的文件的位置由父子进程共享,这会引起含糊情况)
* 执行时关闭(close-on-exec) 标志 (close-on-exec标志可通过fnctl()对文件描述符设置,POSIX.1要求所有目录流都必须在exec函数调用时关闭。
* 信号(signal)控制设定
* nice值 (nice值由nice函数设定,该值表示进程的优先级,数值越小,优
先级越高)
* 进程调度类别(scheduler class) (进程调度类别指进程在系统中被调度时所
属的类别,不同类别有不同优先级,根据进程调度类别和nice值,进程调度程序可计
算出每个进程的全局优先级(Global process prority),优先级高的进程优先执行)
* 进程组号
* 对话期ID(Session ID) (指:进程所属的对话期(session)ID, 一个对话期包括一个 或 多个进程组)
* 当前工作目录
* 根目录 (根目录不一定是“/”,它可由chroot函数改变)
* 文件方式创建屏蔽字(file mode creation mask (umask)) (指:创建新文件的缺省屏蔽字)
* 资源限制
* 控制终端
子进程所独有:
* 进程号
* 不同的父进程号(即子进程的父进程号与父进程的父进程号不同,父进
程号可由getppid函数得到)
* 自己的文件描述符和目录流的拷贝(目录流由opendir函数创建,因其为
顺序读取,顾称“目录流”)
* 子进程不继承父进程的进程,正文(text),数据和其它锁定内存(memory locks)
(锁定内存指被锁定的虚拟内存页,锁定后,不允许内核将其在必要时
换出(page out))
* 在tms结构中的系统时间(tms结构可由times函数获得,它保存四个数据
用于记录进程使用中央处理器(CPU:Central Processing Unit)的时间,包括:用户时
间,系统时间,用户各子进程合计时间,系统各子进程合计时间)
* 资源使用(resource utilizations)设定为0
* 阻塞信号集初始化为空集
* 不继承由timer_create函数创建的计时器
* 不继承异步输入和输出


父子进程如何通信?
======================

一对父子进程可以通过正常的进程间通信的办法(管道,套接字,消息队列,共
享内存)进行通信,但也可以通过利用它们作为父子进程的相互关系而具有的一
些特殊方法。

一个最显然的方法是父进程可以得到子进程的退出状态。

因为子进程从它的父进程继承文件描述符,所以父进程可以打开一个管道的两端,
然后fork,然后父进程关闭管道这一端,子进程关闭管道另一端。这正是你从你的
进程调用‘popen()’函数运行另一个程序所发生的情况,也就是说你可以向
‘popen()’返回的文件描述符进行写操作而子进程将其当作自己的标准输入,或
者你可以读取这个文件描述符来看子进程向标准输出写了什么。(‘popen()’函数
的mode参数定义你的意图(译者注:mode=“r”为读,mode=“w”为写);如果你
想读写都做,那么你可以并不困难地用管道自己做到)

而且,子进程继承由父进程用mmap函数映射的匿名共享内存段(或者通过映射特
殊文件‘/dev/zero’);这些共享内存段不能从无关的进程访问。
DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
我的要求是完全不知道参数类型与参数个数,但上面的例子我早看过,它实际上知道参数类型,并设置了结束标志。
qwertasdfg123 2004-08-13
  • 打赏
  • 举报
回复
/* VA.C: The program below illustrates passing a variable
* number of arguments using the following macros:
* va_start va_arg va_end
* va_list va_dcl (UNIX only)
*/

#include <stdio.h>
#define ANSI /* Comment out for UNIX version */
#ifdef ANSI /* ANSI compatible version */
#include <stdarg.h>
int average( int first, ... );
#else /* UNIX compatible version */
#include <varargs.h>
int average( va_list );
#endif

void main( void )
{
/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}

/* Returns the average of a variable list of integers. */
#ifdef ANSI /* ANSI compatible version */
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;

va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
#else /* UNIX compatible version must use old-style definition. */
int average( va_alist )
va_dcl
{
int i, count, sum;
va_list marker;

va_start( marker ); /* Initialize variable arguments. */
for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )
sum += i;
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
#endif


DentistryDoctor 2004-08-13
  • 打赏
  • 举报
回复
怎么没人回答,顶一下!

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧