【问题标题】:Can I shorten a function name I use repeatedly?我可以缩短重复使用的函数名称吗?
【发布时间】:2019-01-23 14:00:14
【问题描述】:

我有一个很长的公式,如下所示:

float a = sin(b)*cos(c)+sin(c+d)*sin(d)....

有没有办法在 C 中使用 s 代替 sin 来缩短公式,而不影响运行时间?

【问题讨论】:

  • double (*s)(double) = sin;
  • 使用#definesin 缩短为s 的唯一效果是使您的代码不可读
  • 您可以编写一个 emac 宏来为您编写 sin,每当您键入例如CTRL + s。在 Vim 中,您可以编写一次 sin,然后使用 . 重复输入任意次数。
  • 我知道可能有理由不同意 OP 的编码风格,但这似乎是一个完全有效且中肯的问题。我不明白为什么它应该被否决。
  • 不反对,但我鼓励你重新考虑你的想法。重命名标准库函数可能会给未来的代码阅读者和维护者带来混乱。通过使用空格并在必要时将它们分成多行来使您的表达式更具可读性。

标签: c formula


【解决方案1】:

至少有三个选项可以将s 用于sin

使用预处理器宏:

#define s(x) (sin(x))
#define c(x) (cos(x))
float a = s(b)*c(c)+s(c+d)*c(d)....
#undef c
#undef s

请注意,宏定义会立即用#undef 删除,以防止它们影响后续代码。此外,您应该了解预处理器宏替换的基础知识,注意c(c) 中的第一个c 将被扩展,但第二个c 不会因为类似函数的宏c(x) 仅被扩展其中c 后跟(

此解决方案不会影响运行时间。

使用内联函数:

static inline double s(double x) { return sin(x); }
static inline double c(double x) { return cos(x); }

使用好的编译器,这对运行时间没有影响,因为编译器应该用直接调用sincos 替换对sc 的调用,结果与原始代码。不幸的是,在这种情况下,c 函数将与您在示例代码中显示的c 对象发生冲突。您将需要更改其中一个名称。

使用函数指针:

static double (* const s)(double) = sin;
static double (* const c)(double) = cos;

使用好的编译器,这也不会影响运行时间,尽管我怀疑使用此解决方案的编译器可能比以前的解决方案多一些编译器无法优化代码。同样,您将与c 发生名称冲突。请注意,使用函数指针会直接调用 sincos 函数,绕过 C 实现可能为它们定义的任何宏。 (C 实现允许使用宏和函数来实现库函数,并且它们可能会这样做以支持优化或某些功能。对于高质量的编译器,这通常是一个小问题;直接调用的优化仍然应该是好的.)

【讨论】:

    【解决方案2】:

    如果我使用define,会影响运行时间吗?

    define 通过在编译时进行基于文本的替换来工作。如果你 #define s(x) sin(x),那么 C 预处理器将在编译器有机会查看之前将所有 s(x) 重写为 sin(x)

    顺便说一句,这种低级的文本处理正是为什么 define 对于更复杂的表达式会很危险。例如,一个典型的陷阱是,如果您执行#define times(x, y) x*y 之类的操作,则times(1+1,2) 会重写为1+1*2,其计算结果为3,而不是预期的4。对于更复杂的表达式,使用 inlineable functions 代替通常是个好主意。

    【讨论】:

    • 宏替换替换预处理器标记,而不是文本。
    【解决方案3】:

    不要这样做。

    数学家一直将三角函数缩写为sincostansinh coshtanh 已经很多年了。尽管数学家(比如我)喜欢使用他们最喜欢的且通常是特殊的符号,因此将任何论文都膨胀了好几页,但这些已经成为相当标准的。甚至 LaTeX 也有 \sin\cos\tan 之类的命令。

    日本人在 1970 年代发布科学计算器时使缩写词永垂不朽(简写可以很容易地放在按钮上),C 标准库采用了它们。

    如果您偏离这一点,那么您的代码会立即变得难以阅读。这对于您无法立即看到错误实现的影响的数学代码尤其有害。

    但如果你必须,那么一个简单的

    static double(*const s)(double) = sin;
    

    足够了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-29
      • 2021-10-31
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2011-07-14
      相关资源
      最近更新 更多