var和&(** var)有什么区别 [英] What's the difference between var and &(*var)

查看:70
本文介绍了var和&(** 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 不应是指向 void 的指针,但是C Standard在这种情况下明确允许使用它...确实令人震惊.
  • 如果 var 是一个数组,并且具有多个元素,则 var & * var 具有不同的类型,并且sizeof(var) sizeof(&(* var))具有不同的值:第一个是数组的大小,第二个是指向数组的指针的大小第一个元素.
  • Peter 所述,如果 var 是未初始化的指针,则对 var ==&(* var)求值将得出未定义的行为(由于评估 == 的任一侧都会产生未定义的行为-访问未初始化变量的值将导致未定义的行为).
  • 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 if var is a null pointer.
  • as Pascal Cuoq commented, var should not be a pointer to void, 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 and sizeof(var) and sizeof(&(*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 evaluating var == &(*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, unless ddim is 0
  • ref must be a valid pointer as fread 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和&amp;(** var)有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆