外星代码生成术之逗号运算符

    技术2022-05-11  122

    外星代码生成术之逗号运算符

     

    缩减代码不意味着增加可读性,恰恰相反,过分的缩减代码反而会使代码更难懂,难以维护。本文不提倡滥用扭曲化的外星C语法,只是作为一个集趣式的记录,为初学C派系语言的读者简单介绍一下那些莫名其妙的代码是如何造出来的。

     C派系语言为我们提供了许许多的奇怪的运算符,最奇怪的运算符之一当数逗号运算符,它本身并没有太多实际意义“运算”,只是计算各个运算项的值,然后将最右边的运算项的值返回。但这一点使得我们有可能将多个表达式合成为一个:

     a = 1;

    b++;

    c *= 4;

     

    合并为:

    a = i, b++, c *= i;

    呵,好像意义不大,但如果是在循环中使用,就不一样了:

    while (i < n)

    {

    a = i;

    b++;

    i++;

    }

    可简写为:

    while (a = i++, b++, i < n) ;  /* 注意分号不能少 */

    C++中,由于使用cout等流对象进行的输出语句实际上也是一个表达式,所以对于如下常见的打印整个数组的值的代码:

    for (i = 0; i < size; ++i)

         cout << a[i] << endl;

    使用逗号运算符并利用好自加运算的特性,可以简写为:

    for (i = 0; i < size; cout << a[i++] << endl)    /* 注意分号不能少 */

    而对于打印一个二维数组这样的操作,由于循环完一行之后要输出换行,所以外层循环(遍历每一行)不得不使用复合语句:

    for (i = 0; i < size; ++i)

    {

    for (j = 0; j < size; ++j)

        cout << a[i][j];

    cout << endl;

    }

    但如果把cout移到循环内,就可以显著减少行数:

    for (i = 0; i < size; cout << endl; ++i)

    for (j = 0; j < size; cout << a[i][j++]) ;  /* 注意分号不能少 */

     

    当然,也可以是

    for (i = 0; cout << endl, i < size; ++i)

    for (j = 0; cout << a[i][j], j < size; ++j) ;  /* 注意分号不能少 */

     

    但使用逗号运算符时一定要注意其隐含的不确定性,如表达式:

    ++i, cout << a[i], x + y;

    如果语言中对各个表达式的求值顺序不确定,那么cout的子表达式所输出的a[i]就无法确定是自加以前的i还是自加以后的i. 使用逗号运算符,以及相关的重载运算符的连续表达式时应当格外注意这一点。

    注:由于时间仓促,本文程序片断未经调试,如有错误,欢迎批评指正。


    最新回复(0)