指针声明的区别?

时间:2018-02-04 07:52:15

标签: c pointers

这两个声明之间有什么区别?有人可以解释一下吗?

int *ptr=#

int *ptr;
ptr= #

5 个答案:

答案 0 :(得分:4)

没有明显的区别意义。在第一种情况下,您将声明指针变量并立即初始化它。 (&num是初始化程序)。

在第二种情况下,指针被声明,然后它包含垃圾值(考虑到它们具有自动存储持续时间),直到你为它分配num的地址 - 如果你使用它,那么它就是UB。在第一种情况下,你可以消除使用无法实现的指针变量值的机会。

请注意,在第二种情况下,ptr= #不是声明的一部分。它是赋值语句。宣言只是int *ptr

您可以查看此规则以了解声明:来自standard

      declaration:
             declaration-specifiers init-declarator-listopt ;
             static_assert-declaration
      declaration-specifiers:
             storage-class-specifier declaration-specifiersopt
             type-specifier declaration-specifiersopt
             type-qualifier declaration-specifiersopt
             function-specifier declaration-specifiersopt
             alignment-specifier declaration-specifiersopt
      init-declarator-list:
              init-declarator
              init-declarator-list , init-declarator
      init-declarator:
              declarator
              declarator = initializer  <-------

答案 1 :(得分:1)

存在语义差异,即使两者都以相同的结果结束:您已声明指向intptr)并指向变量(num)的指针。

现在有所不同:

int *ptr=&num;

声明指针(它甚至是定义)并使用初始化来设置其初始值,同时:

int *ptr;
ptr= &num;

首先声明指针,然后为其指定值。

具体差异来自那里:

  • 初始化在文件范围内有效,而分配不是
  • 如果指针是静态的,则每次传递都会重复分配,而初始化则让变量保持其值:

       int *foo() {
           static int num[5] = { 1, 2, 3, 4, 5 };
           static int ptr = &num;              // one time only initialization
           return ptr++;
       }
       int main() {
           for(int i=0; i<5; i++) {
               printf("%d ", *foo());
           }
           return 0;
       }
    

    将打印1 2 3 4 5,但如果我们写:

       int *foo() {
           static int num[5] = { 1, 2, 3, 4, 5 };
           static int ptr;
           ptr = &num;              // assignment on each call
           return ptr++;
       ...
    

    结果将为1 1 1 1 1

  • 您可以初始化const变量

        int * const ptr = &num;
    

    虽然你不能分配给它

        int * const ptr;
        ptr = &num;            // syntax error
    
  • 您可以初始化数组,但无法分配数组

  • 可能是其他人......

答案 2 :(得分:0)

对我而言,最大的区别在于它起初看起来很有趣。

对于传统的非指针变量,我们可以编写例如

int num = 5;

int num;
num = 5;

我们声明的内容(num)与我们指定的内容完全相同。

但是在指针声明的情况下,还有那个讨厌的额外*。这种模式导致一些初级程序员尝试编写以下错误代码。既然我们可以有

int *ptr = &num;

为什么我们不能将其重新排列为

int *ptr;
*ptr = &num;           /* XXX looks superficially right, but WRONG */

在这种情况下,按照上一个模式,我们试图使我们声明的内容(*ptr)与我们分配的内容相同。

但这是错误的,这不是指针声明在C中的工作方式。我们声明的事情不是*ptr。我们声明的内容只是ptr,其类型为int *,或指向int

出于这个原因,有些人喜欢以不同的方式编写指针声明:

int* ptr;
ptr = &num;

现在更明显的是,我们宣布的事物(ptr)与我们分配的内容相同。

如果我们尝试在同一行上声明两个指针,那么唯一的问题是:

int* ptr1, ptr2;       /* probably WRONG: ptr2 is *not* a pointer */

但当然这并没有将ptr2声明为指针。

我们还可以使用typedef更清晰:

typedef int *intptr;

后跟

intptr ptr = &num;

intptr ptr;
ptr = &num;

在这种情况下,在同一行上声明两个指针正常工作:

intptr ptr1, ptr2;     /* both ptr1 and ptr2 are pointers */

答案 3 :(得分:0)

int *ptr;        // It’s a pointer variable.
ptr=&num;        // ptr holds address of num.
int * ptr=&num;  // Address of num is held by pointer ptr.

在任何变量前面使用*时,不必再次使用它。 这就是你宣称为ptr=&num的原因。

答案 4 :(得分:0)

int * ptr =&amp; NUM;语句声明指针类型的变量“ptr”,并同时用变量“num”的地址初始化它。

而语句int * ptr; * PTR =安培; NUM;首先声明一个当前包含垃圾值的指针类型变量。

将值,即“num”变量的地址分配给下一个语句中的指针变量。