【问题标题】:Structure pointer operator conjecture (theory)结构指针算子猜想(理论)
【发布时间】:2013-03-01 21:58:46
【问题描述】:

指向结构的指针被如此频繁地使用,以至于有一个特殊的运算符:->。下面的表达式是等价的:

(*x).y
 x->y

将这个运算符简单地看作是这样定义的预处理器宏是否公平:

#define (x)-> (*(x).)

为什么或为什么不?还是从一开始就将其编码为运算符 - 这将有何不同/有利?

只是好奇。

【问题讨论】:

  • 呸。不可能,因为(x)-> 没有一个有效的宏名 make。

标签: c pointers syntax struct operators


【解决方案1】:

以下表达式是等价的:?

(*x).y
 x->y

是的,两者都是访问结构成员y 的两种不同方式。

(*x).y 运算符是 . DOT,它与值变量 Element selection by reference 一起使用。 * 使用的原因。表示x 是指向结构的指针。

x->y 运算符-> 被称为Element selection through pointer。这与指向结构的指针一起工作。这就是这次没有使用* 的原因。

两者的工作原理相同。

是否可以将此运算符简单地视为定义为这样的预处理器宏:

#define (x)-> (*(x).)

首先它给出一个错误: 宏名必须是标识符。此错误是因为我们不能将 -> 运算符作为宏名称。

valid macro name 可以是:

宏名称只能由字母数字字符和下划线组成,即“a-z”、“A-Z”、“0-9”和“_”,并且第一个字符不能是数字。一些预处理器也允许使用美元符号'$',但你不应该使用它;不幸的是,我无法引用 C 标准,因为我没有它的副本。

另外,请注意->. 是如上所述的差异运算符。它们的优先级也不同,因此将一个运算符替换为另一个运算符是个坏主意。

访问结构元素的有效宏:

另外我今天想分享一下,只有我知道大多数 C 头文件。定义的宏如:

#define S(x)  ((x).y)

用于特定的 strcut 元素。

注意(x) 周围的括号x 将覆盖* 的优先级超过.。默认情况下. 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 喜欢它 :)

【讨论】:

  • 如果您对S(x) ((x).y) 宏有疑问,请告诉我。
  • @GManNickG 它不是我在头文件中看到的。但我是真的。你有更好的想法请与我们分享。
  • @GManNickG 哈哈!我刚刚看到您在 SO 上提出的最精彩的问题。
  • 好吧,我不会提出任何想法,因为没有问题要解决。 :) 人们应该明确地使用x.y
  • 所以你可以将像 (*x) 这样的指针作为参数传递给宏吗?这就说得通了。邪恶的答案,酷。
【解决方案2】:

将这个运算符简单地看作是这样定义的预处理器宏是否公平:

没有。

为什么或为什么不?

-> 操作符有一些特定的语义,不能用宏来强制执行(这是一个简单的文本替换)。即,左侧操作数必须是指向结构或联合类型的指针,右侧操作数必须是结构或联合类型的成员,并且表达式的结果必须是一个左值。您无法使用宏强制执行这些规则。

【讨论】:

    【解决方案3】:

    将这个运算符简单地看作是这样定义的预处理器宏是否公平:

    不,不会的。

    为什么或为什么不?

    因为它不是宏。它是语言中定义的独特运算符,似乎为其他功能提供语法糖。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      相关资源
      最近更新 更多