当我需要更改指针的原始内存地址时,我会像这样编写指针。
示例:
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/