如何使用在C中解析的逗号运算符来复杂表达式?

时间:2017-10-11 23:28:29

标签: c variable-assignment comma assignment-operator comma-operator

阅读以下两个内容后......

What does the comma operator , do?

How does the Comma Operator work

我仍然不确定我是否无法解析我在别人的源代码中找到的以下陈述:

// Your custom function revisited
function display_product_title_as_link( $item_name, $item ) {
    $product = wc_get_product( $item['variation_id'] ? $item['variation_id'] : $item['product_id'] );
    $image = wp_get_attachment_image_src( $product->get_image_id(), 'full' );
    $product_name = $product->get_name();
    return '<a href="'. $image[0] .'" rel="nofollow">'. $product_name .'</a>
    <div style="color:blue;display:inline-block;clear:both;">'.$image[0].'</div>';
}

// The hooked function that will enable your custom product title links for "New Order" notification only
add_action( 'woocommerce_email_order_details', 'custom_email_order_details', 1, 4 );
function custom_email_order_details( $order, $sent_to_admin, $plain_text, $email ){
    // Only for "New Order" and admin email notification
    if ( 'new_order' != $email->id && ! $sent_to_admin ) return;
    // Here we enable the hooked function
    add_filter( 'woocommerce_order_item_name', 'display_product_title_as_link', 10, 3 );
}

逗号运算符按从左到右的顺序进行评估,是吗?如果我们使用括号来显示优先顺序,我想我们有这样的事情:

int i, n, val, locala = a, bestval = -INFINITY;

那么,也许,原件相当于以下内容?

(int i, (n, (val, (locala = a, (bestval = -INFINITY)))));

如果是这样,为什么int bestval = -INFINITY; int locala = a; int val; int n; int i; 关键字应用于所有变量而不是仅应用于最左边的变量int

另外,最右边的表达式会返回它们的值,是吗?因此,i可能会在分配完成后返回locala = a的值。这是否意味着变量localain都已初始化?如果是这样,它们被初始化为什么? val-INFINITY的价值?

3 个答案:

答案 0 :(得分:4)

int i, n, val, locala = a, bestval = -INFINITY;

是一份声明。

声明在C中定义如下(没有所有细节)

declaration:
    declaration-specifiers init-declarator-listopt ;

init-declarator-list:
    init-declarator
    init-declarator-list , init-declarator

init-declarator:
    declarator
    declarator = initializer

声明说明符会影响 init-declarator中的所有声明符 - 列表

如果你想在声明中使用逗号运算符,那么这样的声明可以查找例如

int i = 1, j = 2, k = ( ++i, j++, i + j );

此处表达式( ++i, j++, i + j )用作基于逗号运算符的初始值设定项。

声明后i等于2j - 3k - 5

答案 1 :(得分:3)

逗号令牌在C中执行了几个不同的操作,不应混淆:

  • 分离类似函数的预处理器宏定义的参数:

    #define CAT_NO_EXPAND(x,y) x ## y
    
  • 将类似函数的预处理器宏的参数分开使用:

    int CAT_NO_EXPAND(ident_, 3) = 3;
    
  • 在枚举定义中分隔枚举数:

    enum colors { RED, GREEN, BLUE };
    
  • 在声明中分隔声明者:

    int a, b=3, c;
    
  • 分隔支撑初始值设定项中的成员/元素:

    int arr[3] = {0, 2, 4};
    struct mystruct s = {8, 3.0};
    func( (mystruct s){8, 3.0} );
    
  • 分隔函数声明或定义的参数:

    void f(int n, double, const char* fmt, ...);
    
  • 分隔函数调用表达式的参数:

    f(3, 0.5, "Test %s\n", "Hello");
    
  • 形成一个表达式,如果求值将丢弃左侧并使用右侧的值作为其值。

    #define CALL_G_IGNORE_RESULT(x) ((void)g(x), 0)
    for (i=0, j=0; i<m && j<n; ++i, ++j)
    

您所了解的“逗号运算符”只是 描述最后一种情况,它在表达式上下文中工作,与上述任何其他情况都不匹配。

您发布的是一个声明,它不涉及“逗号运算符”,只是一次声明多个变量。任何初始化程序都按顺序进行求值(这很重要,因为您可以在以后的初始化程序中使用先前声明的变量)。

答案 2 :(得分:0)

  1. 这不是逗号运算符。
  2. 这是宣言清单。
  3. 从左到右执行,或者至少执行它的可执行部分。
  4. 评估顺序和运算符优先级是两回事。
  5. 从左到右的执行顺序与您在括号中发布的顺序相反。
  6. int关键字适用于所有声明,因为这就是语法的含义。
  7. 这里没有'最正确的表达式',只有初始化器的声明。
  8. 因此没有返回任何值。
  9. inval未初始化。