c - 是否有理由使用像这样的 C 语言指针 &(*foo)?

标签 c pointers

当我需要更改指针的原始内存地址时,我会像这样编写指针。

示例:

static void get_line_func(struct data_s *data,
                                char **begin)
{
    data->slot_number = strsep(&(*(begin)), "/");
    data->protocol = *begin;
    strsep(&(*begin), ">");
    data->service_name = strsep(&(*begin), "\n");
}

我的意思是,&(*foo) == foo 不是吗?

最佳答案

没有理由直接这样做。但是,这种组合可能出现在机器生成的代码中(例如预处理器宏的扩展)。

例如,假设我们有一个宏do_something_to(obj),它期望参数表达式obj 指定一个对象。假设在其扩展的某处,此宏使用 &(obj) 获取对象的地址。现在假设我们想将宏应用于我们仅通过指针 ptr 持有的对象。要指定对象,我们必须使用表达式 *ptr 以便我们将宏用作 do_something_to(*ptr)。这当然意味着 &(*ptr) 现在出现在程序中。

表达式 &*ptr 的状态多年来发生了变化。我似乎记得在 ANSI C 89/ISO C90 方言中,如果 ptr 是无效指针,表达式会产生未定义的行为。

在 ISO C11 中拼写如下(我相信 C99 中的文本几乎相同),要求 &* 不要取消引用指针:“如果操作数 [of the address-of unary & operator] 是一元 * 运算符的结果, 该运算符和 & 运算符均未被评估,结果就好像两者都是 省略,除了对运算符的约束仍然适用并且结果不是左值“。因此在现代 C 方言中,表达式 &*ptr 不会取消引用 ptr,因此即使该值为 null 也具有定义的行为。

这是什么意思? “约束仍然适用”基本上意味着它仍然需要进行类型检查。仅仅因为 &*P 不取消引用 P 并不意味着 P 可以是 double结构;它必须是一个指针。

“结果不是左值”部分可能很有用。如果我们有一个指针 P,它是一个值,如果我们将它包装在表达式 &*P 中,我们将获得与非左值相同的指针值。还有其他方法可以将 P 的值作为非左值来获取,但是 &*P 是解决只需要两个字符的问题的“代码高尔夫”解决方案,并且具有即使 P 从一种指针类型更改为另一种指针类型也将保持正确的属性。

关于c - 是否有理由使用像这样的 C 语言指针 &(*foo)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46162687/

相关文章:

c - C Blackjack 游戏的 int 数组缺少输出

c - 段错误转换成二进制

c - 将字符串解析为空终止数组的最佳方法是什么?

数组的C指针算法

c - 尝试读取文本文件并对其进行排序时出现段错误 11

c - 如何从函数的循环中调用值?

c - Lex 不区分大小写的单词检测

c - 指针条件 while(*s1++=*s2++)

c - 指向范围外变量的指针在 C 中如何表现?

c++ - (->) 箭头运算符和 (.) 点运算符,类指针