如何使用?在C中的for循环中使用问号?

cs7cruho  于 2023-10-16  发布在  其他
关注(0)|答案(4)|浏览(117)

如果i是偶数,则for(int j = 0; j < m; j++)
否则,如果i是奇数,则for(int j = m-1; j > 0; j--)
我想把这两个条件合并结合起来。

for( (i%2==0) ? (int j = 0; j < m; j++) : (int j = m-1; j > 0; j--))

但似乎失败了。
在C语言中,有没有什么方法可以使用?或其他方式将这两个条件合并组合起来?

hjzp0vay

hjzp0vay1#

不,您不能将它们与条件运算符合并组合。条件表达式的操作数是每个返回值的表达式,条件表达式的结果是 * 单个 * 值。
一个for循环的形式是for( init expression; condition expression; iteration expression) loop-body,它有 * 三个 * 表达式。
您试图从三进制返回某种类型的三元素(init, condition, iteration)expressions 元组,作为for循环的init/condition/iteration表达式,但您不能将这些东西打包,然后以这种方式解包。语法根本就是错误的。
使用if/else。如果你想共享循环体,把它放在一个函数中,并在每个循环中调用该函数:

if (i % 2 == 0) {
  for (int j = 0; j < m; j++) {
    do_things(j);
  }
} else {
  for (int j = m-1; j > 0; j--) {
    do_things(j);
  }
}
zy1mlcev

zy1mlcev2#

你可以做一些有点古怪和模糊的事情,就像下面这样,但我不推荐这样做。如果i是奇数,则从m-1递减到0;如果i是偶数,则从0递增到m-1。请注意,最初的问题从m-1倒数到1,我假设您希望从m-1倒数到0,因此根据需要进行更正。
小心m的“意外”输入值,例如否定,因为在这种情况下,循环可能不会在你想要的时候终止。

#include <stdio.h>

int main()
{
    int i = 1;
    int m = 8;
    
    int start = i%2 ? m-1 : 0;
    int end = i%2 ? -1 : m;
    int delta = i%2 ? -1 : 1;
    
    for (int j = start; j != end; j += delta)
    {
        printf("j=%d\n", j);
    }

    return 0;
}
sirbozc5

sirbozc53#

不要通过向上或向下计数来使循环复杂化...只需根据需要翻译循环计数器:

void doit( int m, int i ) {
    // peculiar imbalance in OP's ranges :\
    // if i is odd, bail out BEFORE reaching 0th value
    m -= i%2;
    for( int j = 0; j < m; j++ ) {
        int k = i%2 ? m - j : j;  // ternary, and begin using 'k'

        printf( "%d ", k );
    }
    putchar( '\n' );
}

int main( void ) {
    doit( 15, 0 );
    doit( 15, 1 );

    return 0;
}

测试结果:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
14 13 12 11 10 9 8 7 6 5 4 3 2 1

编辑:

其他的答案建议要么在两个独立的循环中重复处理,要么重复一个函数调用,下面是上面的简化版本。像其他给出的答案一样,这个版本忽略了OP的不平衡范围。倒计时。

int main( void ) {

    for( int i = 0; i <= 1; i++ ) { // demonstrate both even and odd

        unsigned m = 10; // # of steps

        for( unsigned j = 0; j < m; j++ ) { // traverse range

            int k = i%2 ? m - j - 1: j; // descending or ascending

            printf( "%d ", k ); // Simulate processing
            /* more processing with this value */
        }

        putchar( '\n' );
    }

    return 0;
}

测试结果:

0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0

(更改为使用unsigned以避开@Chux提出的问题)
证明此实施的有效性:一个可笑的摄氏度/华氏度的转换:

int main( void ) {
    double temp = get_double( "Temperature: " );
    int i = get_int( "Is this Celsius(0) or Fahrenheit(1): " );

    for( unsigned m = 3, j = 0; j < m; j++ ) {
        switch( (i%2) ? m - j - 1: j ) {
            case 0:
                temp *= (i%2) ? 5 : 1.0/5;
                break;
            case 1:
                temp *= (i%2) ? 1.0/9 : 9;
                break;
            case 2:
                temp += (i%2) ? -32 : 32;
                break;
        }
    }

    printf( "%.2lf%s\n", temp, i%2 ? "C" : "F" );

    return 0;
}
taor4pac

taor4pac4#

成为一个成功程序员的黄金法则:不要为了好玩而把事情复杂化。尽可能以最简单、最易读的方式编写代码。
例如,这是非常可读的,因此很难进一步改进:

if(i % 2) // odd
{
  for(int j=m-1; j > 0; j--)
  {
    do_stuff_with(something[i][j]);
  }
}
else // even
{
  for(int j = 0; j < m; j++)
  {
    do_stuff_with(something[i][j]);
  }
}

我们可以写一个更模糊的循环来适应这两种情况,但是这样做的好处是值得怀疑的,因为代码只会变得更难阅读,没有明显的好处:

// not really recommended
int start;
int end;
int mod;

if(i % 2) // odd
{
  start = m-1;
  end   = -1;
  mod   = -1;
}
else // even
{
  start = 0;
  end   = m;
  mod   = 1;
}

for(int j=start; j!=end j+=mod)
{
  do_stuff_with(something[i][j]);
}

(This在某些手动优化以获得更好的数据缓存性能的情况下可能是明智的,但只有在实际基准测试和找到性能瓶颈之后。)

相关问题