代码之家  ›  专栏  ›  技术社区  ›  EMP

C中的指针语法:为什么*只应用于第一个变量?

  •  22
  • EMP  · 技术社区  · 14 年前

    int* a, b;
    

    将宣布 a 作为类型 int* b 作为类型 int . 我很清楚这个陷阱,但我想知道的是 为什么? 它是这样工作的。为什么不也申报 内景* ,正如大多数人直觉所料?换句话说,为什么 * 应用于变量名,而不是类型?

    当然你可以这样写,以便更符合 事实上 作品:

    int *a, b;
    

    然而,我和我交谈过的每个人都认为 ,而不是 a是指向某个数据的指针,该数据的类型为“int”

    8 回复  |  直到 14 年前
        1
  •  20
  •   schmod    8 年前
        2
  •  32
  •   caf    14 年前

    C声明是这样写的,“声明镜像使用”。这就是为什么要这样声明数组:

    int a[10];
    

    你是不是有了你提出的规则,它一直在那里

    type identifier, identifier, identifier, ... ;
    

    int[10] a;
    

    使用 a

    void foo(int a, char *b);
    

    而不是

    void(int a, char* b) foo;
    

    通常,“declaration mirrors use”规则意味着您只需要记住一组关联性规则,这些规则适用于两个操作符,如 * , [] () , [] () .


    指向int的指针 “作为” int* 只是“声明镜像使用”的结果。如果你打算使用另一种声明风格,拼写 指向int的指针 “作为” &int @int ".

        3
  •  10
  •   eruciform    14 年前

    可能还有另外一个历史原因,但我一直这样理解:

    一个声明,一种类型。

    如果a、b、c和d在这里必须是相同的类型:

    int a, b, c, d;
    

    那么行中的所有内容也必须是整数。

    int a, *b, **c, ***d;
    

    4个整数:

    1. **c级
    2. ***d级

    它也可能与运算符的优先级有关,也可能是在过去的某个时刻。

        4
  •  3
  •   bta    14 年前

    这个 * 已解析。以这些陈述为例:

    char*  x;
    char  *x;
    

    这些说法是等价的。这个

    int*  a, b;
    

    不会使 b 指针,因为没有 * * 仅对其两侧的对象进行操作。

    int x; x 是一个整数。如果 y *y 是一个整数。当你写作的时候 int *y; *是的 是一个整数(这是您想要的)。在声明中 char a, *b, ***c; a ,的解引用值 b ,以及 c 都是那种类型的 char

    我同意,如果情况正好相反,那就更有意义了。为了避免这个陷阱,我给自己定了一个规则,总是自己在一行上声明指针。

        5
  •  2
  •   R Samuel Klatchko    14 年前

    int x[20], y;
    int (*fp)(), z;
    

    在这些示例中,更明显的是修饰符只影响其中一个声明。一种猜测是,一旦K&R决定这样设计修饰符,让修饰符只影响一个声明是“正确的”。

    另一方面,我建议您仅将每个声明限制为一个变量:

    int *x;
    int y;
    
        6
  •  1
  •   lorenzog    14 年前

    因为如果声明

    int* a, b;
    

    我们要宣布 b

    int* a;
    int  b;
    

    在一条线上。

    另一方面,你可以

    int*a, *b;
    

    得到你想要的。

    这样想吧:现在的方式仍然是最简洁、最独特的方式。这就是C的主要内容:)

        7
  •  1
  •   Fabio Ceconello    14 年前

    考虑一下宣言:

    int *a[10];
    int (*b)[10];
    

    第一个是指向整数的十个指针的数组,第二个是指向十个整数数组的指针。

    现在,如果*附加到类型声明,那么在它们之间加上括号在语法上是无效的。所以你必须找到另一种方法来区分这两种形式。