Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何定义一个要被另一个函数替换的函数?_C - Fatal编程技术网

C 如何定义一个要被另一个函数替换的函数?

C 如何定义一个要被另一个函数替换的函数?,c,C,如何定义一个要被另一个函数替换的函数 例如,如果我有一个函数Stuff(int-numbers)并想用Stuff2(int-numbers,int-otherNumbers)替换它 因此,当调用Stuff()时,将使用Stuff2()。使用#define是一种基本的全局文本替换 #define Stuff(number) Stuff2(number,0) 零在这里是为了说明;用适当的默认值替换它。如有必要,您甚至可以调用函数或使用更多的宏魔术来计算它 更新 因此,在评论之后,OP试图重定向ma

如何定义一个要被另一个函数替换的函数

例如,如果我有一个函数Stuff(int-numbers)并想用Stuff2(int-numbers,int-otherNumbers)替换它

因此,当调用Stuff()时,将使用Stuff2()。

使用#define是一种基本的全局文本替换

#define Stuff(number) Stuff2(number,0)
零在这里是为了说明;用适当的默认值替换它。如有必要,您甚至可以调用函数或使用更多的宏魔术来计算它

更新

因此,在评论之后,OP试图重定向main()

这是一种具有高度特定用例的技术。首先要记住的是main()不是一个普通函数。没错,main()很特别

因此,您不能仅仅替换main()而期望事情顺利进行。必须有一个main(),并且必须根据编译器接受的一个变体声明它。(在国际海事组织,您应该更喜欢使用C标准要求的两种变体之一。)

截取用户的主目录()

这种技术通常被那些希望对应用程序进行应用程序级控制,但又希望您认为一切正常的库所使用

它们通过在库的代码中声明main(),并#将main定义为头文件中的其他内容,这样当您编写“main()”时,它实际上是一个不同的函数。例如:

// quuxlib.c

int main( int argc, char** argv )
{
  int exit_code = 0;

  // library does initializations here
  ...

  // call the user's main(), LOL
  exit_code = UsersMain( argc, argv );

  // perform cleanup
  ...

  return exit_code;
}
库的标题:

// quuxlib.h

#define main UsersMain

...
现在用户的代码看起来很正常:

注意事项和最佳实践

我认为,这种技术是糟糕的设计。它试图掩盖实际发生的事情。更好的库设计应该是明确的,并且:

  • 要求您在main()中正确初始化和完成库
  • 希望您使用显式的输入过程
前者是首选,因为它能更好地处理各种各样的事情。例如,Tcl可以正确地钩住东西。在这里,您只需创建一个解释器,使用它,然后正常终止

#include "tcl.h"

int main()
{
  Tcl_Interp* interp = Tcl_CreateInterp();
  int status = Tcl_Eval( interp, "puts {Hello world!}" );
  return 0;
}
Tcl也更进一步,提供并使生活变得非常轻松

使用显式输入过程与main()替换技巧完全相同,只是不需要假装:

#include "quuxlib.h"

int AppMain()  // required by QuuxLib
{
  // my main program here
  ...

  return 0;
}
问题

最后,重新定义main的问题有:

  • 它掩盖了真正发生的事情
  • 它使用全局宏替换
好的设计不会试图对你隐瞒事情。全局宏替换也是不好的。在本例中,“main”不是保留字。您可以有一个名为“main”的有效本地标识符。使用全局宏替换可以避免这种可能性

最后,让一个库提供显式的初始化和终结过程,而不是接管main,可以增加用户可用的灵活性。接受main()的库不能与另一个执行相同操作的库一起使用,也不能真正信任它处理可能出错的事情(IMHO)以及为库用户提供适当和显式挂钩以处理此类事情的库

对于普通情况和多功能性来说,两者之间的权衡是相当不错的


好吧,我想我现在已经非常喜欢漫无边际了,所以是时候停止了…

你会用什么来代替缺少的参数?为什么要这样做?那么,让我们假设我正在尝试用main2()替换main()。目前它找不到main2,正在退出。我正在尝试做以下工作:#define main()main2()
main()
是您的入口点,我不确定您是否想重新定义它。可以指定一个单独的入口点,但这听起来很像一个。你想完成什么?
#include "quuxlib.h"

int AppMain()  // required by QuuxLib
{
  // my main program here
  ...

  return 0;
}