在以下行中:
struct student *ptr = NULL;
为什么ptr设置为NULL??有人能告诉我吗?
#include <stdio.h>
int main(void) {
// student structure
struct student {
char id[15];
char firstname[64];
char lastname[64];
float points;
};
// student structure variable
struct student std[3];
// student structure pointer variable
struct student *ptr = NULL;
// other variables
int i;
// assign std to ptr
ptr = std;
// get detail for user
for (i = 0; i < 3; i++) {
printf("Enter detail of student #%d\n", (i + 1));
printf("Enter ID: ");
scanf("%s", ptr->id);
printf("Enter first name: ");
scanf("%s", ptr->firstname);
printf("Enter last name: ");
scanf("%s", ptr->lastname);
printf("Enter Points: ");
scanf("%f", &ptr->points);
// update pointer to point at next element
// of the array std
ptr++;
}
// reset pointer back to the starting
// address of std array
ptr = std;
for (i = 0; i < 3; i++) {
printf("\nDetail of student #%d\n", (i + 1));
// display result via std variable
printf("\nResult via std\n");
printf("ID: %s\n", std[i].id);
printf("First Name: %s\n", std[i].firstname);
printf("Last Name: %s\n", std[i].lastname);
printf("Points: %f\n", std[i].points);
// display result via ptr variable
printf("\nResult via ptr\n");
printf("ID: %s\n", ptr->id);
printf("First Name: %s\n", ptr->firstname);
printf("Last Name: %s\n", ptr->lastname);
printf("Points: %f\n", ptr->points);
// update pointer to point at next element
// of the array std
ptr++;
}
return 0;
}
3条答案
按热度按时间2w2cym1i1#
在发布的程序中,初始化为
NULL
是可选的。您可以删除它,程序将完全等效。完全等价于
并且还
初始化变量的原因是"健壮性",而不是正确性,健壮性是关于最小化当你改变程序时出错的风险。
假设你修改了程序,不小心删除了
ptr = std;
这一行,由于NULL
的初始化,当ptr
在for循环中使用时,它将是一个空指针,如果你的程序崩溃或出现其他问题,你可以在编译时禁用优化,然后在调试器中运行它。然后,你会可靠地看到它在"如果ptr
没有被初始化,那么它的行为可能是任何的,这取决于当时内存中发生了什么,并且它可能无法从一次执行到下一次执行重现,所以很难找到这个bug。在这个例子中,没有什么强有力的理由让我们更喜欢初始化为
NULL
而不是直接设置ptr = std
。出于不同的原因,这两种方法都可以被认为是很好的卫生措施。将所有指针初始化为null是很好的,因为这是一个简单的规则,而且它将枯燥的初始化过程分开了(你不需要太注意)从有趣的计算中。另一方面,直接将ptr
初始化为它所需要的值是很好的,因为它最小化了发生的事情的数量。rm5edbpk2#
NULL
对指针的初始化是多余的。
您可以通过其声明中的结构数组的第一个元素来初始化它,如
代码的作者用
NULL
初始化指针,因为他不想声明一个未初始化的指针,并且程序中的指针至少被重新分配了两次。所以看起来他想把指针的声明分开,并用
std
赋值给它。此外,由于指针仅在for循环中使用,因此最好在for循环语句中声明它,例如
您应该始终在使用变量的最小作用域中声明变量。
请注意,它会比
scanf
的这些调用更安全写作
还有一点要注意,与其使用幻数
3
,不如引入一个命名常量,例如在这种情况下,你的代码会更加灵活,只需要改变常量
N
的值就足够了,程序可以正常运行,而不需要对程序做任何额外的修改。fivyi3re3#
C标准规定,具有自动存储持续时间的指针在声明时具有不确定的值,即它们未初始化,可能指向内存中的任何内容。
当指针的值不确定时使用指针是未定义的行为,因此在声明时(以及在调用
free()
之后)将指针设置为NULL
被认为是“良好的实践”。但有必要吗?没有。
如果你声明了一个指针,并立即用一个值初始化它,那么首先将它设置为
NULL
是没有意义的。只在需要的地方声明也是一个好习惯。所以不要:
你可以这样写:
另一个好的做法是避免用不必要的注解使代码混乱。
上面的注解没有任何意义,很明显
std
被分配给了ptr
。