如何在C中解析使用逗号运算符的复杂表达式?
在阅读了以下两篇文章之后 我仍然不确定我是否无法解析在其他人的源代码中找到的以下语句:如何在C中解析使用逗号运算符的复杂表达式?,c,variable-assignment,comma,assignment-operator,comma-operator,C,Variable Assignment,Comma,Assignment Operator,Comma Operator,在阅读了以下两篇文章之后 我仍然不确定我是否无法解析在其他人的源代码中找到的以下语句: int i, n, val, locala = a, bestval = -INFINITY; 逗号运算符按从左到右的顺序计算,是吗?如果我们用括号来表示优先顺序,我想我们有这样的东西: (int i, (n, (val, (locala = a, (bestval = -INFINITY))))); 那么,也许,原始版本等同于以下内容 int bestval = -INFINITY; int loc
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
可能会在赋值发生后返回locala
的值。这是否意味着变量i
、n
和val
都被初始化?如果是这样,它们的初始化目的是什么<代码>-无限?a
?的值
int i, n, val, locala = a, bestval = -INFINITY;
这是一份声明
声明在C中以以下方式定义(没有所有细节)
声明说明符影响init声明器中的所有声明器-
名单
如果您想在声明中使用逗号运算符,那么这样的声明可以如下所示
int i = 1, j = 2, k = ( ++i, j++, i + j );
这里的表达式(++i,j++,i+j)
用作基于逗号运算符的初始值设定项
在声明之后,i
等于2
,j
-3
,和k
-5
int i, n, val, locala = a, bestval = -INFINITY;
这是一份声明
声明在C中以以下方式定义(没有所有细节)
声明说明符影响init声明器中的所有声明器-
名单
如果您想在声明中使用逗号运算符,那么这样的声明可以如下所示
int i = 1, j = 2, k = ( ++i, j++, i + j );
这里的表达式(++i,j++,i+j)
用作基于逗号运算符的初始值设定项
在声明
i
等于2
,j
-3
,和k
-5
之后,逗号标记在C中做了几个不同的事情,不应混淆:
- 分离函数的参数,如预处理器宏定义:
#define CAT_NO_EXPAND(x,y) x ## y
enum colors { RED, GREEN, BLUE };
void f(int n, double, const char* fmt, ...);
- 分离函数的参数,如预处理器宏使用:
int CAT_NO_EXPAND(ident_, 3) = 3;
- 分离枚举定义中的枚举数:
#define CAT_NO_EXPAND(x,y) x ## y
enum colors { RED, GREEN, BLUE };
void f(int n, double, const char* fmt, ...);
- 在声明中分隔声明符:
int a, b=3, c;
- 分隔大括号初始值设定项中的成员/元素:
int arr[3] = {0, 2, 4}; struct mystruct s = {8, 3.0}; func( (mystruct s){8, 3.0} );
- 分离函数声明或定义的参数:
#define CAT_NO_EXPAND(x,y) x ## y
enum colors { RED, GREEN, BLUE };
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)
\define CALL\u G\u IGNORE\u RESULT(x)((void)G(x),0)
对于(i=0,j=0;i而言,逗号标记在C中有几种不同的功能,不应混淆:- 分离函数的参数,如预处理器宏定义:
#define CAT_NO_EXPAND(x,y) x ## y
enum colors { RED, GREEN, BLUE };
void f(int n, double, const char* fmt, ...);
- 分离函数的参数,如预处理器宏使用:
int CAT_NO_EXPAND(ident_, 3) = 3;
- 分离枚举定义中的枚举数:
#define CAT_NO_EXPAND(x,y) x ## y
enum colors { RED, GREEN, BLUE };
void f(int n, double, const char* fmt, ...);
- 在声明中分隔声明符:
int a, b=3, c;
- 分隔大括号初始值设定项中的成员/元素:
int arr[3] = {0, 2, 4}; struct mystruct s = {8, 3.0}; func( (mystruct s){8, 3.0} );
- 分离函数声明或定义的参数:
#define CAT_NO_EXPAND(x,y) x ## y
enum colors { RED, GREEN, BLUE };
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)
\define CALL\u G\u IGNORE\u RESULT(x)((void)G(x),0) 对于(i=0,j=0;i
- 这不是逗号运算符
- 这是一份申报单
- 它是从左到右执行的,或者至少是它的可执行部分
- 求值顺序和运算符优先级是两件不同的事情
- 从左到右的执行顺序与括号中的相反
关键字应用于所有声明,因为这就是语法的含义int
- 这里没有“最右边的表达式”,只有带有初始值设定项的声明
- 因此也没有返回值
、i
和n
未初始化val
- 这不是逗号运算符
- 这是一份申报单
- 它是从左到右执行的,或者至少是它的可执行部分
- 求值顺序和运算符优先级是两件不同的事情
- 从左到右的执行顺序与括号中的相反
关键字应用于所有声明,因为这就是语法的含义int
- 这里没有“最右边的表达式”,只有带有初始值设定项的声明
- 因此也没有返回值
、i
和n
未初始化val
这不是逗号运算符。C中逗号的大多数用法都不是逗号运算符。合理的经验法则:如果左边的东西没有被丢弃,它就不是逗号运算符。@Toothick Anemone没有逗号运算符。这里有一个声明列表。@KrassiEm:这不是什么超深奥的不切实际的构造。提问者正在尝试g理解真正的代码,而他们却以一种非常自然的方式误解了它。@KrassiEm解析问题和语言律师问题在这里并不是离题。如果你个人不想问这样的问题,为什么还要读它?标题应该足以阻止你。这不是逗号运算符。逗号在C不是逗号运算符。经验法则:如果左边的东西没有被丢弃,它就不是逗号运算符。@牙签海葵没有逗号运算符。这里有一个声明列表。@Krassi
- 分离函数的参数,如预处理器宏定义: