【问题标题】:Pointers in C: why is the * needed in *address_of_x = &x when getting the address of x?C中的指针:为什么在获取x的地址时*address_of_x = &x中需要*?
【发布时间】:2017-11-22 14:58:05
【问题描述】:

假设我们有以下代码,它取x,将值4存储在其中,然后将x的地址存储在指针变量中:

int x = 4;
int *address_of_x = &x;

int *address_of_x 中的* 的用途是什么? 我知道* 用于取消引用指针-它需要一个地址并告诉您那里存储的内容。但是,如果要存储地址,那么我们要取消引用什么?还是我们根本没有取消引用任何东西?为什么不写成:

int address_of_x = &x;

【问题讨论】:

  • 它不是解引用,而是一种类型。上下文很重要。
  • * 在 C 语言中可能意味着很多不同的东西,具体取决于上下文。你的 C 编程书应该清楚地说明这一点。
  • 我有一种重复的感觉。
  • 绝对重复

标签: c pointers syntax


【解决方案1】:

int *address_of_x = &x; 中的* 未取消引用 @Eugene Sh
它是类型声明的一部分:pointer to int

int x = 4;
int *address_of_x = &x;

一样
int x = 4;          // declare x as int
int *address_of_x;  // declare address_of_x as pointer to int
address_of_x = &x;  // Assign the address of x to address_of_x

为什么不写成:int address_of_x = &x;

&x 不是int&x 是一个 int *,一个指针(或地址)。指针不是整数。

【讨论】:

    【解决方案2】:

    表达式中,* 是取消引用运算符。在 declaration(您在此处拥有)中,它是 pointer declarator 语法的一部分。您声明address_of_x 是一个指向int 的指针,而不仅仅是一个int

    这种语法背后的想法是,为了方便起见,标识符的声明和使用应该看起来相似(您通常通过取消引用来使用指针)。

    另请注意,每个声明为指针的标识符都需要*,即使您在单个声明中声明了多个标识符,如下所示:

    int *a, *b;
    

    如果你写

    int *a, b;
    

    相反,b不是是一个指针。不过,一般来说,最好避免在每个声明中声明多个标识符。

    【讨论】:

      【解决方案3】:

      int *address_of_x = &x; 不是分配。 int *address_of_x = &x; 是一个带有初始化 (= &x) 的声明 (int *address_of_x)(请注意,在史前C 中,初始化(而不是赋值)已完成没有=,这使它们与作业更加不同)。

      C 镜像使用中的声明。 int *address_of_x 声明 *address_of_x 的类型为 int,因此 address_of_x 的类型为 指向 int 的指针。然后= &x 部分将此指向int 的指针 初始化为&xx 的地址)。

      【讨论】:

        【解决方案4】:

        这是一个指针的定义,address_of_x变量的类型是int *,一个指向int的指针。那里没有发生“取消引用”。

        为什么不写成:

           int address_of_x = &x;
        

        嗯,有两件事

        • C 是一种强类型语言。
        • 变量名与其类型没有任何联系

        【讨论】:

        • @DavidBowling 显然就在那里,伴随着对类型本身的理解。
        【解决方案5】:

        简单回答:变量声明或定义语句中的星号不是解引用运算符。而是修饰符。

        在给定的上下文中,星号表示“将 mext 标识符定义为指向基本类型的指针”。

        你肯定不会问为什么[10] 不代表int a[10] 中的“取数组的第10 个元素”。嗯,马马虎虎。这里的括号也不是括号运算符,原因完全相同。

        为什么不写成:

           int address_of_x = &x;
        

        编译器从不试图解释标识符的字面意思。它仅在确定声明语句中标识符的类型时查找修饰符。

        也就是说,这段代码不会像它看起来的那样工作:

        int *not_a_pointer, not_an_array[10];
        float a_character;
        

        【讨论】:

          【解决方案6】:

          int *address_of_x = &x; 声明一个“指向 int 的指针”(int *address_of_x) 类型的变量,然后初始化它的地址为 x (= &x)。

          所以这个* 不是取消引用,而是声明的一部分。

          【讨论】:

            【解决方案7】:

            这两个sn-ps在功能上是一样的:

            int *address_of_x = &x;
            

            int *address_of_x;
            address_of_x = &x;
            

            在第一种情况下,您在一个语句中定义并初始化了指针,但它可能看起来像错误的语法。在第二个例子中,定义和赋值是单独的语句,代码更清晰。

            没有取消引用(还)。

            【讨论】:

              猜你喜欢
              • 2019-12-23
              • 2022-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-04-17
              • 1970-01-01
              • 2012-10-15
              • 1970-01-01
              • 2020-09-11
              相关资源
              最近更新 更多