var和&(** var)有什么区别 [英] What's the difference between var and &(*var)
问题描述
某些源代码使用符号&(* var)
,其中 var
已经是一个指针,例如 int * var = ...
.
Some source code use the notation &(*var)
where var
is already a pointer, like int *var = ...
.
这两个符号之间有区别吗?
Is there a difference between this two notations ?
var!=&(* var)
吗?
示例: https://github.com/FreeFem/FreeFem-sources/blob/develop/src/medit/inout_popenbinaire.c#L40
推荐答案
&(* var)
在大多数情况下在编译时的计算结果与 var
相同,但请注意以下几点:
&(*var)
evaluates to the same as var
in most circumstances, at compile time, but note some caveats:
-
var
应该是有效的指针,尽管没有理由让编译器生成取消引用的代码.实际上,C11规定即使var
是空指针,也没有针对& * var
的未定义行为. 正如 Pascal Cuoq 所评论的那样, - 如果
var
是一个数组,并且具有多个元素,则var
和& * var
具有不同的类型,并且sizeof(var)
和sizeof(&(* var))
具有不同的值:第一个是数组的大小,第二个是指向数组的指针的大小第一个元素. - 如 Peter 所述,如果
var
是未初始化的指针,则对var ==&(* var)
求值将得出未定义的行为(由于评估==
的任一侧都会产生未定义的行为-访问未初始化变量的值将导致未定义的行为).
var
不应是指向 void
的指针,但是C Standard在这种情况下明确允许使用它...确实令人震惊.var
should be a valid pointer, although there is not reason for the compiler to generate code to dereference it. Indeed C11 specifies that there is no undefined behavior for&*var
even ifvar
is a null pointer.- as Pascal Cuoq commented,
var
should not be a pointer tovoid
, but the C Standard explicitly allows it for this very case... Shocking indeed. - if
var
is an array, with more than one element,var
and&*var
have a different type andsizeof(var)
andsizeof(&(*var))
have a different value: the first is the size of the array while the second is the size of a pointer to the its first element. - As commented by Peter, if
var
is an uninitialised pointer, then evaluatingvar == &(*var)
gives undefined behaviour (since evaluating either side of the==
gives undefined behaviour - accessing the value of an uninitialised variable is what gives the undefined behaviour).
您在问题中链接的示例完全没有任何目的使用此构造:
The example you link to in the question uses this construction for no purpose whatsoever:
#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);
}
程序员正在从重定向到标准输入的文件中读取许多浮点值和整数.代码笨拙且不可移植:
The programmer is reading a number of floating point values and an integer from a file redirected into the standard input. The code is awkward and non-portable:
-
float
的大小被默认为4 -
int
的大小被默默假定为相同的4个字节 -
c
必须是有效的指针,除非ddim
为0 -
ref
必须是有效的指针,因为fread
会尝试在其指向的地址存储4个字节,除非流位于文件末尾 - 文件和读取错误的末尾将被忽略,并且可能发生未定义的行为.
- the size of
float
is silently assumed to be 4 - the size of
int
is silently assumend to be the same 4 bytes c
must be a valid pointer, unlessddim
is 0ref
must be a valid pointer asfread
will try and store 4 bytes at the address it points to, unless the stream is at end of file- end of file and read errors are silently ignored and undefined behavior is possible.
可以通过以下方式简化和保护代码:
The code can be simplified and protected this way:
#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;
}
此源代码的其他部分显示出不良的结构,甚至是无效的结构,您应该仅研究该软件包的示例以了解不执行的操作.
Other portions of this source code show poor or even invalid constructions, you should study this package only for examples of what not to do.
这篇关于var和&(** var)有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!