逗号运算符做什么?

时间:2020-03-05 18:50:14  来源:igfitidea点击:

运算符在C中做什么?

解决方案

回答

表达方式:

(expression1,  expression2)

首先对expression1求值,然后对expression2求值,然后为整个表达式返回expression2的值。

回答

它导致对多个语句的求值,但仅使用最后一个作为结果值(我认为是rvalue)。

所以...

int f() { return 7; }
int g() { return 8; }

int x = (printf("assigning x"), f(), g() );

应该导致x设置为8.

回答

如先前的答案所述,它评估所有语句,但使用最后一个作为表达式的值。我个人只发现它在循环表达式中很有用:

for (tmp=0, i = MAX; i > 0; i--)

回答

我看到它唯一有用的地方是当我们编写一个时髦的循环时,我们想在其中一个表达式中执行多个操作(可能是init表达式或者循环表达式。类似:

bool arraysAreMirrored(int a1[], int a2[], size_t size)
{
  size_t i1, i2;
  for(i1 = 0, i2 = size - 1; i1 < size; i1++, i2--)
  {
    if(a1[i1] != a2[i2])
    {
      return false;
    }
  }

  return true;
}

如果存在语法错误,或者如果我混入了不严格的C语言,请原谅我。我不是在争论运算符是一种很好的形式,但这就是我们可以使用的形式。在上述情况下,我可能会使用" while"循环来代替,因此init和loop上的多个表达式将更加明显。 (然后我将内联的i1和i2初始化,而不是先声明然后再初始化...。等等等等。)

回答

我在while循环中使用最多:

string s;
while(read_string(s), s.len() > 5)
{
   //do something
}

它将进行操作,然后根据副作用进行测试。另一种方法是这样做:

string s;
read_string(s);
while(s.len() > 5)
{
   //do something
   read_string(s);
}

回答

逗号运算符将其两侧的两个表达式组合为一个,并按从左到右的顺序对它们进行求值。右侧的值作为整个表达式的值返回。
({expr1,expr2)就像{expr1; expr2; },但是我们可以在函数调用或者赋值中使用expr2的结果。

for循环中经常会看到它来初始化或者维护多个变量,如下所示:

for (low = 0, high = MAXSIZE; low < high; low = newlow, high = newhigh)
{
    /* do something with low and high and put new values
       in newlow and newhigh */
}

除此之外,在包装应该始终在宏中一起执行的两个操作时,在另一种情况下,我仅在"愤怒中"使用过它。我们有将各种二进制值复制到字节缓冲区中以便在网络上发送的代码,并且维护了一个指针,该指针指向:

unsigned char outbuff[BUFFSIZE];
unsigned char *ptr = outbuff;

*ptr++ = first_byte_value;
*ptr++ = second_byte_value;

send_buff(outbuff, (int)(ptr - outbuff));

在值是short或者in的情况下,我们这样做:

*((short *)ptr)++ = short_value;
*((int *)ptr)++ = int_value;

后来我们读到这并不是真正有效的C语言,因为((short *)ptr`不再是l值,并且不能递增,尽管当时我们的编译器并不介意。为了解决这个问题,我们将表达式分为两部分:

*(short *)ptr = short_value;
ptr += sizeof(short);

但是,此方法依赖于所有开发人员始终记住同时编写这两个语句的情况。我们想要一个函数,我们可以在其中传递输出指针,值和值的类型。这是C语言,而不是带有模板的C ++语言,我们无法使函数采用任意类型,因此我们选择了宏:

#define ASSIGN_INCR(p, val, type)  ((*((type) *)(p) = (val)), (p) += sizeof(type))

通过使用逗号运算符,我们可以根据需要在表达式或者语句中使用它:

if (need_to_output_short)
    ASSIGN_INCR(ptr, short_value, short);

latest_pos = ASSIGN_INCR(ptr, int_value, int);

send_buff(outbuff, (int)(ASSIGN_INCR(ptr, last_value, int) - outbuff));

我并不是说这些示例中的任何一个都是好的样式!的确,我似乎还记得史蒂夫·麦康奈尔(Steve McConnell)的代码完成建议,甚至在for循环中使用逗号运算符也不建议:为了提高可读性和可维护性,该循环应仅由一个变量控制,而for行中的表达式本身仅包含循环控制代码,而不包含初始化或者循环维护的其他额外位。