【问题标题】:What is the syntax in c to combine statements as a parameterc中将语句组合为参数的语法是什么
【发布时间】:2014-10-20 20:05:43
【问题描述】:

我有一种暗示,有一种旧的讨厌的方法可以让函数在计算参数时运行,但是我不知道它叫什么,我无法搜索出规则。

一个例子

char dstr[20];
printf("a dynamic string %s\n", (prep_dstr(dstr),dstr));

这个想法是,“()”将在执行完 prep_dstr 函数后返回地址 dstr。

我知道这很丑陋,我可以直接在网上做 - 但它很复杂......

#

好的 - 回应请求不要这样做。

我实际上正在对一些现有代码进行 MISRA 清理(不是我的,不要拍我),目前“prep_dstr”函数需要一个缓冲区来修改它(不考虑缓冲区的长度)并返回它的指针作为参数传递。

我喜欢迈出一小步 - 测试然后再迈出一小步。

所以 - 比返回一个不知道其持久性的指针稍微不那么讨厌的方法是停止函数返回一个指针并使用逗号运算符(在确保它不会跳出缓冲区的末尾之后)。

这会使 MISRA 错误倒计时,当一切仍然有效并且 MISRA 错误消失时,我将尝试优雅地解决 - 也许是后年:)。

【问题讨论】:

  • 之前为什么不干脆就行了?
  • 但这应该可以,不是吗? , 返回最后一个表达式的结果。
  • 我不明白你在问什么。您在问题中有正确的语法(尽管我不建议使用它)。
  • “它的名称”和“为什么起作用”密切相关:operator precedence。您的 () 在食物链中的位置比逗号运算符要高得多,实际上它们位于运算符优先级星系的两端。
  • MISRA-C 禁止逗号运算符。重写代码的理智且兼容 MISRA 的方法是:prep_dstr(dstr); printf("a dynamic string %s\n", dstr);。此外,MISRA 禁止在生产代码中使用 stdio.h。

标签: c misra


【解决方案1】:

逗号运算符具有适当的优先级,此外,它还给出了一个序列点,即它在程序的执行流程中定义了一个点,所有前面的副作用都被解决了。 因此,无论您的函数prep_dstr() 对字符串dstr 执行什么操作,它都会在到达逗号运算符之前完全执行。

另一方面,逗号运算符给出了一个表达式,其值为最右边的操作数。

以下示例根据需要为您提供值dstr

   5+3, prep_dstr(dstr), sqrt(25.0), dstr;
   a+b-c, NULL, dstr;
   (prep_dstr(dstr), dstr);

当然,只要需要字符串dstr,就可以使用这样的表达式。

因此,你在问题​​中使用的语法,然后,它完美地完成了工作。

由于您愿意使用语法,因此您可以使用另一种可能性。
考虑到函数printf()是一个函数,它尤其是一个表达式。
这样就可以用逗号表示:

  prep_dstr(dstr), printf("Show me the string: %s\n", dstr);

似乎每个人都在告诉您“不要以这种方式编写代码……”。
这种编程风格的宗教建议被高估了。
如果你需要做某事,那就去做吧。

C 的一条原则是:“不要阻止程序员做已经做过的事情。”

但是,无论您做什么,都要尝试编写可读的代码。

【讨论】:

    【解决方案2】:

    是的,您使用的语法将适用于您的目的。

    但是,请考虑编写干净易读的代码。例如,

    char buffer[20];
    
    char *destination = prepare_destination_string(buffer);
    
    printf("a dynamic string %s\n", destination);
    

    一切都可以清楚地命名和理解,并且易于推断预期的行为。如果愿意,您甚至可以省略某些部分,例如 destination,或者执行更简单的错误检查。

    【讨论】:

      【解决方案3】:

      你的暗示和你的代码都是正确的。也就是说,请不要这样做。将prep_dstr 单独放在一行中可以更轻松地推断出发生了什么以及何时发生。

      您想到的是逗号运算符。在逗号还没有其他含义的上下文中(例如分隔函数参数),表达式a, b 的值是b,但首先计算a。代码中多余的括号会导致逗号以这种方式被解释,而不是作为函数参数分隔符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多