C: 运算符 -> 和 *
C: operator -> and *
在下面的例子中:
typedef struct {
const char *description;
float value;
} swag;
typedef struct {
swag *swag;
const char *sequence;
} combination;
typedef struct {
combination numbers;
const char *make;
} safe;
int main()
{
swag gold = {"GOLD!", 1000000.0};
combination numbers = {&gold, "6502"};
safe s = {numbers, "RAMACON250"};
//Correct handling
printf("Result: %s \n", s.numbers.swag->description);
//Faulty handling
// printf("Result: %s \n", s.numbers.(*swag).description);
return 0;
}
为了接收 "GOLD!"
以下行是正确的
printf("Result: %s \n", s.numbers.swag->description);
但为什么以下内容不正确,因为 (*x).y
与 x->y
相同
printf("Result: %s \n", s.numbers.(*swag).description);
我在编译过程中收到以下错误:
C:\main.c|26|error: expected identifier before '(' token|)
只需使用
printf("Result: %s \n", ( *s.numbers.swag).description);
根据 C 语法,后缀表达式 .
定义如下
postfix-expression . identifier
所以你可以这样写
( identifier1 ).identifier2
但你可能不会写
identifier1.( identifier2 )
回到你的程序你甚至可以写
printf("Result: %s \n", ( *( ( ( s ).numbers ).swag ) ).description);
只需将 *swag 替换为 swag[0]。
printf("Result: %s \n", s.numbers.swag[0].description);
记住 *swag 和 swag[0] 是一回事。
why the following is not correct as the (*x).y is same as x->y
printf("Result: %s \n", s.numbers.(*swag).description);
关于 (*x).y
与 x->y
相同的说法是正确的
但这不是您在代码中所做的:
s.numbers.(*swag).description
这样看:
when comparing s.numbers.swag->description to x->y
x is s.numbers.swag
y is description
so by simple substitution
x->y equivalent to (*x).y becomes (*s.numbers.swag).description
.
和->
运算符优先级相同,结合性从左到右。这就是为什么
s.numbers.swag->description
工作正常。而且,凭直觉,您可以从左到右跟踪已解决的问题。
您访问 s
然后 numbers
然后 swag
,您取消引用以访问 description
.
你犯的错误是得出结论,因为a->b
等价于(*a).b
,表达式
s.numbers.(*swag).description
应该等同于上面那个。事实并非如此。
那是因为(一元)*
运算符的优先级低于.
和->
,而且它的结合性是从右到左的,加上括号不解决这个问题(您想访问 swag
指针而不是 swag
成员)。
有效的做法是:访问 s
然后 numbers
然后取消引用 swag
(数字)并尝试访问 description
。但是 numbers
只有一个指向 swag
而不是 swag
成员的指针。
另一个答案中已经提到了等价的表达式,为了完整起见,我在这里重复一下:
(*s.numbers.swag).description
访问 s
然后 numbers
然后 swag
然后访问描述。
请记住 .
的优先级高于 *
并且由于从左到右的关联性,括号在 .
之前解析以访问描述。
s.numbers.swag[0].description
访问 s
然后 numbers
然后 swag
并取消引用访问描述。
[]
运算符与 .
具有相同的优先级和结合性。所以你可以从左到右阅读这个表达式。
在下面的例子中:
typedef struct {
const char *description;
float value;
} swag;
typedef struct {
swag *swag;
const char *sequence;
} combination;
typedef struct {
combination numbers;
const char *make;
} safe;
int main()
{
swag gold = {"GOLD!", 1000000.0};
combination numbers = {&gold, "6502"};
safe s = {numbers, "RAMACON250"};
//Correct handling
printf("Result: %s \n", s.numbers.swag->description);
//Faulty handling
// printf("Result: %s \n", s.numbers.(*swag).description);
return 0;
}
为了接收 "GOLD!"
printf("Result: %s \n", s.numbers.swag->description);
但为什么以下内容不正确,因为 (*x).y
与 x->y
printf("Result: %s \n", s.numbers.(*swag).description);
我在编译过程中收到以下错误:
C:\main.c|26|error: expected identifier before '(' token|)
只需使用
printf("Result: %s \n", ( *s.numbers.swag).description);
根据 C 语法,后缀表达式 .
定义如下
postfix-expression . identifier
所以你可以这样写
( identifier1 ).identifier2
但你可能不会写
identifier1.( identifier2 )
回到你的程序你甚至可以写
printf("Result: %s \n", ( *( ( ( s ).numbers ).swag ) ).description);
只需将 *swag 替换为 swag[0]。
printf("Result: %s \n", s.numbers.swag[0].description);
记住 *swag 和 swag[0] 是一回事。
why the following is not correct as the (*x).y is same as x->y
printf("Result: %s \n", s.numbers.(*swag).description);
关于 (*x).y
与 x->y
但这不是您在代码中所做的:
s.numbers.(*swag).description
这样看:
when comparing s.numbers.swag->description to x->y
x is s.numbers.swag
y is description
so by simple substitution
x->y equivalent to (*x).y becomes (*s.numbers.swag).description
.
和->
运算符优先级相同,结合性从左到右。这就是为什么
s.numbers.swag->description
工作正常。而且,凭直觉,您可以从左到右跟踪已解决的问题。
您访问 s
然后 numbers
然后 swag
,您取消引用以访问 description
.
你犯的错误是得出结论,因为a->b
等价于(*a).b
,表达式
s.numbers.(*swag).description
应该等同于上面那个。事实并非如此。
那是因为(一元)*
运算符的优先级低于.
和->
,而且它的结合性是从右到左的,加上括号不解决这个问题(您想访问 swag
指针而不是 swag
成员)。
有效的做法是:访问 s
然后 numbers
然后取消引用 swag
(数字)并尝试访问 description
。但是 numbers
只有一个指向 swag
而不是 swag
成员的指针。
另一个答案中已经提到了等价的表达式,为了完整起见,我在这里重复一下:
(*s.numbers.swag).description
访问 s
然后 numbers
然后 swag
然后访问描述。
请记住 .
的优先级高于 *
并且由于从左到右的关联性,括号在 .
之前解析以访问描述。
s.numbers.swag[0].description
访问 s
然后 numbers
然后 swag
并取消引用访问描述。
[]
运算符与 .
具有相同的优先级和结合性。所以你可以从左到右阅读这个表达式。