Pointer to structure

2019-01-15 21:21发布

问题:

I am new to pointers and trying to use a pointer to the structure. But after the first entry, my program crashes. Kindly assist me.

Here's the structure definition:

struct students{//structure students definition
   char name[20];
   char RegNo[15];
   char CourseUnit[10];
   int score;
   char grade;
};

The grade should not be entered by the user but instead computed by the program.

Here's my code so far I have written:

int main()//start of main
{
    struct students *myStudPtr,myStud[SIZE];

    myStudPtr=&myStud[SIZE];

    int i;//declare variables
    int count;

    printf("How many students do you want to deal with?\n");
    scanf("%d",&i);//number of entries

    for(count=1;count<=i;count++) {
        printf("Enter student's name\n");
        scanf("%s",&(*myStudPtr).name);

        printf("Enter the student's registration number\n");
        scanf("%s",&(*myStudPtr).RegNo);

        printf("Enter the course unit\n");
        scanf("%s",&(*myStudPtr).CourseUnit);

        printf("Enter the marks scored\n");
        scanf("%d",&(*myStudPtr).score);
    }

    printf("NAME\tREGISTRATION\t\tCOURSE UNIT\tSCORE\t\tGRADE\n");//tabulates the output
    printf("%s\t", myStudPtr->name);
    printf("%s\t\t", myStudPtr->RegNo);
    printf("%s\t", myStudPtr->CourseUnit);
    printf("%d\t\t", myStudPtr->score);

    if(myStudPtr->score>100) {
        printf("Invalid\n");
    } else if(myStudPtr->score<40) {
        printf("FAIL\n");
    } else if(myStudPtr->score<50) {
        printf("D\n");
    } else if(myStudPtr->score<60) {
        printf("C\n");
    } else if(myStudPtr->score<70) {
        printf("B\n");
    } else if(myStudPtr->score>70) {
        printf("A\n");
    } else {
        printf("Invalid");
    }

    return 0;
}

Kindly assist.Thanks in advance.

回答1:

You have an index-out-of bound mistake that causes undefined behavior at runtime:

myStudPtr = &myStud[SIZE];
//                  ^^^^^ 
//                  wrong 

According to declaration struct students myStud[SIZE];, Maximum index value can be SIZE - 1. Remember array index starts with 0.

Edit

As I can understand, you have declared an array of struct, and wants to read i number of student's information from user using pointer to struct. But there are some more problems in your code e.g. in for loop you always access same struct element:

for(count = 1; count <= i; count++)
    scanf("%s", &(*myStudPtr).name);
//                  ^   
//                  points to same struct element in array

This mistake is present in every scanf() and printf() statements.

Correct will be as follows:

  1. Initialize pointer to the address of first element in array:

     myStudPtr = &myStud[0];
     //                  ^ first element at 0th index 
    
  2. Via pointer you can simply access struct's elements in any one of following two ways:

    First: for example to scan score value of a student:

    scanf("%d", &myStudPtr[count].score);
    

    Note: precedence of [] 'array subscript operator' is higher then . 'member selection via object name operator' so you do not need () parenthesis. Also precedence of . operator is higher then & ampersand operator so even you do not need any parenthesis to get address(for example &(myStudPtr[count].score) not needed).

    Second: to scan score value of a student using pointer and -> operator:

    scanf("%d", &(myStudPtr + count)->score);
    

    Note: + plus operator has lower precedence so we need parenthesis to overwrite precedence. And precedence of -> member selection via pointer operator higher then & ampersand operator so here also you do not need any parenthesis like &((myStudPtr + count)->score).

Important to notes:

  1. You should check entered value of i by user that must be less to SIZE (the size of strcut array) otherwise you may have undefined behavior in your code.

  2. To read string use safe fgets() function instead of scanf to avoid buffer overflow. Read: "Reading a line using scanf() not good?"

One more side note:

  1. As you are new C programmer(I feel) you should read: Indenting C Programs its a quick tutorial to learn indentation practice.

  2. You should always keep space after , and ; to make your code readable, and for the same reason an expression like count<=i should be written as count <= i. Compare your for loop:

     for(count=1;count<=i;count++)
    

    And following that I would like to suggest you:

     for(count = 1; count <= i; count++){
         // code after one tab
     }  
    

Improve code:

I would also like to suggest you to improve if-else coding style, your if-else part of code can be written as follows:

score = myStudPtr->score;
if(0 <= score && score <= 100){
  if(score > 70)
    printf("A");
  if(60 <= score && score < 69)
    printf("B");    
  if(50 <= score && score < 59)
    printf("C");    
  if(40 <= score && score < 49)
    printf("D");    
  if(score < 40)
    printf("FAIL");
}
else
 printf("Error: Invalid Entry!");
printf("\n");
  • I removed many else statement, instead used &&.
  • Removed redundant {..} braces pairs.
  • Used local score variable instead myStudPtr->score to keep code look simple.
  • Remove \n from each pritf statement instead add a new printf at the end (not very important).

Last mistake:

To print each students record you need a new loop within that you call printf() function and includes if-else logic to evaluate student grades.