当我需要更改指针的原始内存地址时,我会使用这样的代码编码。
示例:
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
?
答案 0 :(得分:6)
没有理由直接这样做。但是,组合可能出现在机器生成的代码中(例如扩展预处理器宏)。
例如,假设我们有一个宏do_something_to(obj)
,它希望参数表达式obj
指定一个对象。假设在其扩展中的某个位置,此宏使用&(obj)
获取对象的地址。现在假设我们想将宏应用于我们只通过指针ptr
保存的对象。要指定对象,我们必须使用表达式*ptr
,以便我们将宏用作do_something_to(*ptr)
。这当然意味着&(*ptr)
现在出现在程序中。
多年来,表达式&*ptr
的状态发生了变化。我似乎记得在ANSI C 89 / ISO C90方言中,如果ptr
是无效指针,表达式会产生未定义的行为。
在ISO C11中,以下内容已拼写出来(我相信几乎相同的文本在C99中),要求&*
不要取消引用指针:“如果操作数[地址 - 的一元&
运算符]是一元*
运算符的结果,
该运算符和&
运算符都不会被评估,结果就像两者都一样
省略,除了对运算符的约束仍然适用且结果不是左值“。因此在现代C语言中,表达式&*ptr
不会解除引用ptr
,因此具有即使该值为null,也定义了行为。
这是什么意思? “约束仍然适用”基本上意味着它仍然需要键入检查。仅仅因为&*P
没有取消引用P
并不意味着P
可以是double
或struct
;它必须是指针。
“结果不是左值”部分可能有用。如果我们有一个值为P
的指针,如果我们将它包装在表达式&*P
中,我们将得到与非左值相同的指针值。还有其他方法可以获得P
作为非左值的值,但&*P
是一个“代码高尔夫”解决方案,只需要两个字符的问题,并具有保持正确的属性即使P
从一种指针类型更改为另一种指针类型。