我正在尝试在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
的函数,但这将意味着编写额外的代码行,这并不是我所面临挑战的最佳解决方案。
答案 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() ) ;
}