Changing a variable from global to local - C

2019-08-09 07:47发布

问题:

I have written the following code for a project however it fails a singular test asking for two variables to not be global, and instead be local to main(). Modify structexample1.c so that the variables student and anotherStudent are not global but are local to main. I vaguely understand the local and global concept but I am unsure how to implement what the question is asking into the code I have written.

#include <stdio.h>
#include <stdlib.h>
struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
} student;

struct student_s anotherStudent;

void printOneStudent(struct student_s student)
{
    printf("%s (%d) %s %s %.2lf %s\n", student.name, student.age, ",", "height", student.height, " m");
}   

void printStudents(const struct student_s* student)
{
    while (student != NULL) {
        printOneStudent(*student);
        student = student->next;
    }
}

int main(void)
{
    student.name = "Agnes McGurkinshaw";
    student.age = 97;
    student.height = 1.64;
    student.next = &anotherStudent;

    anotherStudent.name = "Jingwu Xiao";
    anotherStudent.age = 21;
    anotherStudent.height = 1.83;
    anotherStudent.next = NULL;

    printStudents(&student);
    return EXIT_SUCCESS;
}

I know I will need to define these variables inside main() but I am unsure how to implement them in a way that does not entirely break my code. The output of the code should remain as follows:

Agnes McGurkinshaw (97), height 1.64 m
Jingwu Xiao (21), height 1.83 m

回答1:

Well, first replace this:

struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
} student;

With:

struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
};

(That is, remove student in the last line).

This change is necessary because you want to define the structure type so that you can later define variables of type struct student_s, but you don't want to define the student variable here, as that would make it global.

Then remove this line:

struct student_s anotherStudent;

And finally, declare both variables in main() before using them:

int main(void)
{
    struct student_s student;
    struct student_s anotherStudent;

    student.name = "Agnes McGurkinshaw";
    student.age = 97;
    student.height = 1.64;
    student.next = &anotherStudent;

    anotherStudent.name = "Jingwu Xiao";
    anotherStudent.age = 21;
    anotherStudent.height = 1.83;
    anotherStudent.next = NULL;

    printStudents(&student);
    return EXIT_SUCCESS;
}


回答2:

Not directly related to your question, but anyway you should avoid this:

struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
} student;

struct student_s anotherStudent;

But rather write this:

struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
} ;                               // defines the structure

struct student_s student;         // declares variable
struct student_s anotherStudent;  // declares variable

Both methods are actually equivalent, but with the second method you clearly separate the definition of struct student_s from the declaration of the two variables studentand anotherStudent. This is more readable.



回答3:

A global variable is a variable that you declare outside any functions and which can be used by any functions defined after the variable declaration:

void f1 () { } // Cannot access a

int a ;

void f2 () { } // Can get and set the value of a

void f3 () { } // Can also get and set the value of a

int main () { // Same as f1 and f2
    f2 () ;
    f3 () ;
    printf("%d\n", a) ; // What is the output?
}

Most of the time, you don't want to use global variable because you do not really know what happens to them when calling various functions (see the example above where you don't know if the value of a has been modified by f2 or f3).

A local variable can only be used in the "scope" where it has been declared:

void f1 () {
    int a ;
}

int main () {
    // a is not accessible here
}

In your case, you are declaring two global variables, but you do not use them globally (because you declare variable with the same name locally, see below), so you should simply declare them locally inside your main:

struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
} ; // Not student here

// No declaration here

void printOneStudent(struct student_s student) { /* ... */ }

void printStudents(const struct student_s* student) { /* ... */ }

int main (void) {
    /* Declare student and anotherStudent here */
    struct student_s student, anotherStudent ;
    /* ... */
}

Note that when you did:

struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
} student ;

You were declarting type struct student_s and in the same time the variable student, while if you remove the student at the end, you are still declaring the struct student_s type but not the student variable any more.

In your code, you were doing the following:

struct student_s { /* ... */ } student ; // student is a global variable

void printOneStudent (struct student_s student) {
    // Here student correspond to the argument, not to the global variable
}

// Example:
int a = 8 ;

void f (int a) {
    printf("%d\n", a) ;
}

int main (void) {
    f(5) ;
}

The output will be 5, not 8, because in f the name a correspond to the parameter of the function, not to the global variable.



回答4:

There is not much to it. Just declare them in main. There are no tricks.

// ConsCPP.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>
struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;   
};


void printOneStudent(struct student_s student)
{
    printf("%s (%d) %s %s %.2lf %s\n", student.name, student.age, ",", "height", student.height, " m");
}   

void printStudents(const struct student_s* student)
{
    while (student != NULL) {
        printOneStudent(*student);
        student = student->next;
    }
}

int main(void)
{
    struct student_s student;
    struct student_s anotherStudent;

    student.name = "Agnes McGurkinshaw";
    student.age = 97;
    student.height = 1.64;
    student.next = &anotherStudent;

    anotherStudent.name = "Jingwu Xiao";
    anotherStudent.age = 21;
    anotherStudent.height = 1.83;
    anotherStudent.next = NULL;

    printStudents(&student);
    return EXIT_SUCCESS;
}


回答5:

At the top of the file you have a struct student_s {...} student;.

This both defines a structure, and allocates one variable of it, student.

The next line, struct student_s anotherStudent; allocates another variable of it.

Because they are not declared inside a function, they are global. To make them local, they must be declared in a function, for example:

int main()
{
    int i;

which defines a local integer variable i.

I will not provide the code; it is your homework, but I hope I gave enough clarification for you.



回答6:

Using array:

#include <stdio.h>
#include <stdlib.h>

#define NUM_OF_STUDENTS 2

struct student_s {
    char* name;
    int age;
    double height;
    struct student_s* next;
};


void printOneStudent(struct student_s student)
{
    printf("%s (%d) %s %s %.2lf %s\n", student.name, student.age, ",", "height", student.height, " m");
}

void printStudents(const struct student_s* student)
{
    int i;
    for (i = 0; i < NUM_OF_STUDENTS; i++) {
        printOneStudent(student[i]);
    }
}

int main(void)
{
    struct student_s student[NUM_OF_STUDENTS];
    student[0].name = "Agnes McGurkinshaw";
    student[0].age = 97;
    student[0].height = 1.64;

    student[1].name = "Jingwu Xiao";
    student[1].age = 21;
    student[1].height = 1.83;

    printStudents(student);
    return EXIT_SUCCESS;
}