C 为什么我们需要int*ptr=NULL;?

C 为什么我们需要int*ptr=NULL;?,c,pointers,initialization,declaration,C,Pointers,Initialization,Declaration,我不太明白为什么在这个例子中我们需要一个partint*ptr=NULL。我知道指针是什么,但为什么我们需要这个*(指向附加到地址的值)呢?为什么这里需要空值 #include <stdio.h> int main() { int a[5] = {22, 33, 44, 55, 66}; int *ptr = NULL; int i; ptr = a; for (i = 0; i < 5; i++) { printf(

我不太明白为什么在这个例子中我们需要一个part
int*ptr=NULL。我知道指针是什么,但为什么我们需要这个*(指向附加到地址的值)呢?为什么这里需要空值

#include <stdio.h>

int main() {
    int a[5] = {22, 33, 44, 55, 66};
    int *ptr = NULL;
    int i;

    ptr = a;
    for (i = 0; i < 5; i++) {
        printf("%d ", *(ptr + i));
    }
}
#包括
int main(){
INTA[5]={22,33,44,55,66};
int*ptr=NULL;
int i;
ptr=a;
对于(i=0;i<5;i++){
printf(“%d”,*(ptr+i));
}
}

此中间初始化

int *ptr = NULL;
这是多余的。你可以马上写

int *ptr = a;
此外,这种初始化是一种糟糕的编程风格。每个变量都应该在使用的地方声明和初始化。否则,代码会让用户感到困惑,因为它会让您感到困惑

我会用下面的方法重写程序

#include <stdio.h>

int main( void )
{
    int a[] = { 22, 33, 44, 55, 66 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for ( const int *ptr = a; ptr != a + N; ++ptr ) 
    {
        printf( "%d ", *ptr );
    }

    putchar( '\n' );
}
#包括
内部主(空)
{
INTA[]={22,33,44,55,66};
常数大小N=sizeof(a)/sizeof(*a);
for(常数int*ptr=a;ptr!=a+N;+ptr)
{
printf(“%d”,*ptr);
}
putchar('\n');
}

在某些情况下,同一个指针可以在不同的上下文中使用。在这种情况下,声明它并用NULL初始化是有意义的。但您的简单程序不是这样。

在您的情况下,
int*ptr=NULL
是完全冗余的,因为您可以编写
int*ptr=a
,正如Vlad所说,但更一般地说,初始化指向
NULL
的指针是一个好主意,因为如果出于某种原因,代码中出现错误并且需要调试它,那么调试指针(如果指针以
NULL
开头)发生的事情要比没有初始化它并且它被一些垃圾值填充时容易得多

我不太明白为什么在这个例子中我们需要一个part
int*ptr=NULL

[……]

为什么我们在这里需要这个*(指向附加到地址的值)

您误解了
*
的重要性。在这种情况下,它不是一元
*
运算符。相反,它是声明类型为指针类型的变量的语法的一部分。该声明将
ptr
声明为
int*
类型的变量,即指向整数的指针。如果没有
*
,则声明将
ptr
的类型指定为
int
,而不是指针类型

为什么这里需要空值

#include <stdio.h>

int main() {
    int a[5] = {22, 33, 44, 55, 66};
    int *ptr = NULL;
    int i;

    ptr = a;
    for (i = 0; i < 5; i++) {
        printf("%d ", *(ptr + i));
    }
}
你没有。
=NULL
是变量
ptr
的初始值设定项,定义了它的初始值,但在读取变量之前,您为该变量指定了不同的值,因此初始值设定项没有实际意义

当然,有些人倾向于提供这样的初始值设定项,其理论是避免意外使用野生指针和/或允许(其他)未初始化的指针被检测到,但正如爱默生所写,“愚蠢的一致性是小头脑的妖怪。”初始值设定项在这个特定代码中没有任何用处。如果坚持提供初始值设定项,则没有理由不直接将
ptr
初始化到
a

int *ptr = a;

正如您的其他答案所建议的那样。

如果在声明时不确定要为指针变量分配哪个变量的地址,建议为指针变量分配空值。分配了空值的指针称为空指针。在您的情况下,这是不必要的,因为您分配了地址
&a[0]
。在循环过程中,如何允许更改常量指针
const int*ptr=a
的值,以及为什么更改常量指针?我不知道这是可能的。对于OP来说,有一件事要说,如果他愿意,他不能比程序中的任何地方都使用这个指针,但是你也已经指出了一点。顺便说一下,这是一段非常酷的代码。@RobertS指针本身并不是常量。指针指向的数据是常量。使用限定符const意味着在循环中指向的数据不会被更改。首先感谢您的第一个解释。但是,让数组保持不变不是没有必要吗?我已经在在线GDB上运行了你的代码,没有
const
限定符。它正在打印相同的结果。为什么要使它保持不变?我没有看到任何导致阵列自身数据发生变化的源。限定符const@RobertS告诉代码的读者,在循环中,指向的数据不会改变。例如,当数组也是常量时,可以使用这个循环。