Home > Back-end >  A code for accessing each element of the structure array variable via pointer
A code for accessing each element of the structure array variable via pointer

Time:02-05

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.

  • Related