&(*var) 在大多数情况下,在编译时的计算结果与var 相同,但请注意一些警告:
-
var 应该是一个有效的指针,尽管编译器没有理由生成代码来取消引用它。事实上,C11 指定 &*var 没有未定义的行为,即使 var 是空指针。
- 正如 Pascal Cuoq 评论的那样,
var 不应该是指向 void 的指针,但 C 标准明确允许它用于这种情况......确实令人震惊。
- 如果
var 是一个包含多个元素的数组,则var 和&*var 具有不同的类型,sizeof(var) 和sizeof(&(*var)) 具有不同的值:第一个是数组的大小,而第二个是指向其第一个元素的指针的大小。
- 正如 Peter 所评论的,如果
var 是一个未初始化的指针,那么评估 var == &(*var) 会产生未定义的行为(因为评估 == 的任一侧都会产生未定义的行为 - 访问未初始化的变量给出了未定义的行为)。
您在问题中链接到的示例没有任何目的使用此结构:
#define WrdSiz 4
void getline_bin_float_vertex(int ddim, double *c, int *ref) {
int i;
float ff;
for (i = 0; i < ddim; i++) {
fread((unsigned char *)&(ff), WrdSiz, 1, stdin);
c[i] = ff;
}
fread((unsigned char *)&(*ref), WrdSiz, 1, stdin);
}
程序员正在从重定向到标准输入的文件中读取一些浮点值和一个整数。代码笨拙且不可移植:
-
float 的大小默认为 4
-
int 的大小默认为相同的 4 个字节
-
c 必须是有效指针,除非 ddim 为 0
-
ref 必须是一个有效指针,因为 fread 将尝试在它指向的地址存储 4 个字节,除非流位于文件末尾
- 文件结尾和读取错误会被静默忽略,并且可能出现未定义的行为。
可以这样简化和保护代码:
#define WrdSiz 4
/* read values from stdin, return non-zero in case of failure */
int getline_bin_float_vertex(int ddim, double *c, int *ref) {
int i;
float ff;
assert(sizeof float == WrdSiz);
assert(sizeof int == WrdSiz);
assert(dim == 0 || c != NULL);
assert(ref != NULL);
for (i = 0; i < ddim; i++) {
if (fread(&ff, sizeof ff, 1, stdin) != 1)
return -1;
c[i] = ff;
}
if (fread(ref, sizeof(*ref), 1, stdin) != 1)
return -1;
return 0;
}
此源代码的其他部分显示糟糕甚至无效的结构,您应该仅研究此包以了解不该做什么的示例。