在c中的顺序评估中执行for循环

时间:2019-12-17 02:30:32

标签: c for-loop comma-operator

我正在尝试在C语言中使用顺序求值运算符(,),并且希望在第一个表达式中执行for循环,如下所示:

( for(initialization;condition;increment) foo() , bar() )

但是写那行我得到一个error: expected expression

即使让我感到困惑的是,我可以执行logical_expression ? expression_true : expression_false形式的伪if语句,我也不奇怪发现这是一件不可能的事情。

有没有办法做到这一点?还是我需要在外部创建for循环?

编辑:

我决定更新我的问题,以提供有关我的问题的更多背景信息。

我有两个函数,我们称它们为baz()qux()qux()baz()的反函数,因此对于任何给定的输入,qux(baz(input))应该返回输入。

具体地说,baz()接受一个字符数组,所有字符都在'0''9'之间,并以与此问题无关的不同格式返回该数字的表示形式。当我们将不同的表示形式传递给quz()时,我们将返回原始数组。

因此,我想构建自己的代码以测试任意数量的情况,并查看qux(baz(input))是否返回期望的结果。我想用尽可能少的代码行(只是将所有行放在同一行中,并用分号隔开,这不是我想要的)。

我知道我可以使用像CUnit这样的框架来做,但是我想自己做。而且我知道以这种方式编写代码会使代码难以阅读和混淆,但是我想将其作为个人挑战。所以我写了(不要试图理解它,它几乎是不可读的代码):

#include "my_lib.h"
#include <stdlib.h>
#include <stdio.h>
int main() {
    int i, errors_size = 0, str_size = 1;
    char *str, **errors = NULL;
    (str = malloc(sizeof(*str)*2) , str[0] = '1' , str[1] = '\0');
    for( (i = 0) ; i < 10000 ; ( i++ , (str[str_size-1] == '9') ? ( ( str[str_size-2] == '9' ? str[str_size-1] = '0' , str_size++, str = realloc(str, sizeof(*str) * (str_size+1)), str[str_size- 1] = '0', str[str_size] = '\0' : str[str_size-2]++ , str[str_size-1] = '0' ) ) : ( str[str_size-1]++ ) ) ) ( printf("Trying %s:",str) , (strcmp(qux(baz(str)) , str) == 0) ? ( printf(" pass\n") , NULL ) : ( printf(" FAIL, got %s\n",qux(baz(str))) , errors_size++ , errors = realloc(errors, sizeof(*errors)*errors_size ) , errors[errors_size-1] = malloc( sizeof(*str)*(str_size+1) ) , memcpy(errors[errors_size-1] , str , sizeof(*str)*(str_size+1)) ) );
    for ( ( printf("\n\nERROR SUMMARY:\n\nTried %d cases. %d errors found (%f%%)\n\n",i,errors_size,100.0*(((float)errors_size)/((float)i))) , i = 0 ) ; i < ( (errors_size < 100) ? errors_size : 1) ; i++ ) ( (errors_size < 100) ? (printf("%d.\t%s\t-->   %s\n",i,errors[i],qux(baz(errors[i])))) : ( printf("The amount of cases to show is too big.\n") ) );
    return 0; }

那只有7行代码,主要部分仅在其中两行中执行。我尝试构建一个以'1'开头的字符字符串,并针对每个步骤将其递增。但是,当我达到999之类的数字时,我必须将其全部设置为零,并在开头加1。我唯一想到的方法就是使用for循环。

一种可能的解决方案是创建一个递增str的函数,但这将意味着编写额外的代码行,这并不是我所面临挑战的最佳解决方案。

4 个答案:

答案 0 :(得分:0)

您可能在实际的代码中缺少了分号,但是在语句中使用逗号运算符完全可以,例如:

for(int i = 0; i < 10; i++) printf("%d", i), printf(" Hello\n");

答案 1 :(得分:0)

您只能在表达式周围加上括号。
for这样的关键字构造不算作表达式。

按照@mnistic的建议,您可以编写:

for(initialization;condition;increment) foo() , bar();

没有最外面的括号。

但是您不能将括号放在for循环周围。

这样做到底有什么问题?

for(initialization;condition;increment) foo();
bar();

为什么您需要使用逗号?

答案 2 :(得分:0)

您在这里想得太多。语句是按顺序求值的,因此以您的示例为例,您可以这样做:

for(initialization;condition;increment) 
    foo();
bar();

如果对bar的调用是某个较大表达式的一部分,则该表达式位于bar();上方的位置,而for循环位于该位置之前。

如果这仍然不是您想要的,那么您需要为我们提供更多有关您正在做的事情的背景信息,以及为什么您认为需要一个像您提议的结构那样的构想。

答案 3 :(得分:0)

这篇文章的许多好的答案都涵盖了语句和表达式之间的区别。希望重点介绍几种替代方法,这些替代方法可以实现将for语句转换为表达式的作用。

一些注意事项:

这不是标准的“ C”-使用GCC扩展名。。如果构建要求严格遵循标准,则可能必须在构建中启用这些功能。

OP没有提供具体情况,因此很难确定是否还有其他特定选择

选项1-声明为表达式

请参阅:https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs

int func(void)
{
    // Execute the loop as expression
    ({ for (...) foo()  ; bar() }) ;
}

选项2-使用嵌套函数

请参阅:https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html#Nested-Functions

int func(void)
{
    void foo_loop(void) {
        for (...) foo() ;
    }

    // Execute the loop as expression
    ( foo_loop(), bar() ) ;
}

嵌套函数foo_loop将可以访问局部变量。

选项3-使用函数调用

从OP中不清楚什么是循环依赖项。如果很简单(例如,循环N次),则可以使用辅助函数

void foo_loop(int n) {
     for (int i=0 ; i<n ; i++) foo() ;
}

int func(void)
{
    // Execute the loop in the function
    int n = 50 ;
    ( foo_loop(n), bar() ) ;
}
相关问题