指向结构的指针经常使用,因此有一个特殊的运算符:->。下面的表达式是等价的:
(*x).y
x->y
将此运算符简单地视为定义如下的预处理器宏是否公平:
#define (x)-> (*(x).)
为什么或者为什么不?还是从一开始就将其编码为运算符-这将有何不同/有利?
只是好奇。
下面的表达式是等价的:?
(*x).y
x->y
是的,两者都是访问结构成员的两种不同方式y
。
(*x).y
运算符是.
与值变量一起使用的 DOT Element selection by reference
。使用的原因*
。手段x
是指向结构的指针。
x->y
运算符->
被称为Element selection through pointer
. 这与指向结构的指针一起工作。这就是这次*
没有使用的原因。
两者的工作原理相同。
将此运算符简单地视为定义如下的预处理器宏是否公平:
#define (x)-> (*(x).)
否 首先它给出一个错误: 宏名称必须是标识符。此错误是因为我们不能将->
运算符作为宏名称。
有效的宏名称可以是:
宏名称只能由字母数字字符和下划线组成,即'az'、'AZ'、'0-9'和'_',并且第一个字符不能是数字。一些预处理器也允许使用美元符号'$',但你不应该使用它;不幸的是,我不能引用 C 标准,因为我没有它的副本。
另外,请注意上面所说->
的.
差异运算符。它们的优先级也不同,因此将一个运算符替换为另一个运算符是个坏主意。
访问结构元素的有效宏:
此外,我今天想分享的只是我知道大多数 C 头文件。定义的宏如:
#define S(x) ((x).y)
对于特定的 strcut 元素。
注意(x)
括号周围x
是覆盖*
over的优先级.
。默认情况下, .
DOT 具有更高的优先级,*
因此它可以用于指针和简单变量。我认为下面的示例会有所帮助。
#define S(x) ((x).y)
typedef struct {
int y;
}X;
X *x;
X b;
int main(){
S(*x);
S(b);
}
编辑:
更好的选择
我正在扩展我的想法来访问 strcut 元素,我定义了新的宏:
#define S(x,y) ((x).y)
typedef struct {
int a;
}X;
X *x;
X b;
int main(){
S(*x,a);
S(b,a);
}
对于通过宏的特定元素而言,这不是更多。
希望至少OP喜欢它:)
将此运算符简单地视为定义如下的预处理器宏是否公平:
不。
为什么或者为什么不?
该->
运算符具有一些无法通过宏强制执行的特定语义(这是一种简单的文本替换)。即,左侧操作数必须是指向结构或联合类型的指针,右侧操作数必须是结构或联合类型的成员,表达式的结果必须是左值。您无法使用宏强制执行这些规则。
将此运算符简单地视为定义如下的预处理器宏是否公平:
不,它不会。
为什么或者为什么不?
因为它不是宏。它是语言中定义的独特运算符,似乎为其他功能提供语法糖。