In the following line :
struct student *ptr = NULL;
Why is ptr set to NULL?? can someone plss tell me..
#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;
}
CodePudding user response:
In the program as posted, the initialization to NULL
is optional. You could remove it, and the program would be exactly equivalent.
struct student *ptr = NULL;
int i;
ptr = std;
is exactly equivalent to
struct student *ptr;
int i;
ptr = std;
and also to
struct student *ptr = std;
int i;
The reason to initialize the variable is robustness, not correctness. Robustness is about minimizing the risk that something goes wrong if you change the program.
Suppose you modified the program and accidentally deleted the line ptr = std;
. Thanks to the initialization to NULL
, ptr
would be a null pointer when it is used inside the for loop. If your program crashes or otherwise misbehave, you could compile it with optimizations disabled and run through it in a debugger. You'd then reliably see it crash at the point where it's trying to dereference a null pointer, and that would clearly indicate that ptr
is not set correctly. If ptr
was uninitialized, the behavior could be anything depending on what happens to be in memory at that point, and it might not be reproducible from one execution to the next, so it would be harder to find the bug.
In this example, there's no strong reason to prefer initializing to NULL
rather than directly setting ptr = std
. Either can be considered good hygiene for different reasons. Initializing all pointers to null is nice because it's a simple rule, and it separates the boring initialization (which you don't need to pay much attention to) from the interesting computation. On the other hand, directly initializing ptr
to the value it needs to have is nice because it minimizes the number of things happening.
CodePudding user response:
This initialization of the pointer by NULL
// student structure pointer variable
struct student *ptr = NULL;
is redundant.
You could initialize it by the first element of the array of structures in its declaration like
// student structure pointer variable
struct student *ptr = std;
The author of the code initialized the pointer by NULL
because he did not want to declare an uninitialized pointer and the pointer within the program is reassigned at least two times.
So it seems he wanted to separate the declaration of the pointer and assignments it with std
.
Also as the pointer is used only in for loops then it is much better to declare it in the for loops statements as for example
for ( struct student *ptr = std; ptr != std 3; ptr ) {
printf("Enter detail of student #%d\n", (i 1));
printf("Enter ID: ");
scanf("s", ptr->id);
printf("Enter first name: ");
scanf("cs", ptr->firstname);
printf("Enter last name: ");
scanf("cs", ptr->lastname);
printf("Enter Points: ");
scanf("%f", &ptr->points);
}
You should always declare variables in minimum scopes where they are used.
Pay attention to that it will be more safer instead of these calls of scanf
scanf("%s", ptr->id);
scanf("%s", ptr->firstname);
scanf("%s", ptr->lastname);
to write
scanf("s", ptr->id);
scanf("cs", ptr->firstname);
scanf("cs", ptr->lastname);
And one more remark. Instead of using the magic number 3
it will be better to introduce a named constant as for example
enum { N = 3 };
struct student std[N];
//...
for ( struct student *ptr = std; ptr != std N; ptr ) {
In this case your code will be more flexible. It will be enough just to change the value of the constant N
and the program will work without any additional changes of the program.
CodePudding user response:
The C standard states that pointers with automatic storage duration have indeterminate values when they're declared, i.e. they're uninitialized and may be pointing to anything in memory.
It is undefined behaviour to use a pointer while it's value is indeterminate, so it's considered good practice to set pointers to NULL
upon declaration (and after a call to free()
.
But is it necessary or required? No.
If you're declaring a pointer, and immediately initialising it with a value, then there's no point in setting it to NULL
first.
It's also a good practice to declare only where needed. So instead of:
struct student *ptr = NULL;
// other variables
int i;
// assign std to ptr
ptr = std;
You could write:
int i;
struct student *ptr = NULL;
Another good practice is to avoid cluttering the code with unnecessary comments.
// assign std to ptr
ptr = std;
The above comment serves no purpose, it's very clear that std
is being assigned to ptr
.