【问题标题】:Changing a variable from global to local - C将变量从全局更改为局部 - C
【发布时间】:2015-08-07 09:24:26
【问题描述】:

我为一个项目编写了以下代码,但是它未能通过单一测试,要求两个变量不是全局变量,而是main() 的本地变量。修改structexample1.c,使变量studentanotherStudent 不是全局变量而是main 的局部变量。我对本地和全局概念有模糊的了解,但我不确定如何在我编写的代码中实现问题的要求。

#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;
}

我知道我需要在main() 中定义这些变量,但我不确定如何以不会完全破坏我的代码的方式实现它们。代码的输出应该保持如下:

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

【问题讨论】:

  • 为什么不在main()创建学生,然后再使用呢?

标签: c struct global local


【解决方案1】:

好吧,首先替换这个:

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

与:

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

(即去掉最后一行的student)。

此更改是必要的,因为您要定义结构类型以便以后可以定义 struct student_s 类型的变量,但您不想在此处定义 student 变量,因为这会使它成为全局变量。

然后删除这一行:

struct student_s anotherStudent;

最后,在使用它们之前在main() 中声明这两个变量:

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】:

与您的问题没有直接关系,但无论如何您应该避免这种情况:

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

struct student_s anotherStudent;

而是这样写:

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

这两种方法实际上是等价的,但是使用第二种方法,您可以清楚地将struct student_s 的定义与studentanotherStudent 两个变量的声明分开。这更具可读性。

【讨论】:

    【解决方案3】:

    全局变量是您在任何函数之外声明的变量,并且可以由在变量声明之后定义的任何函数使用:

    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?
    }
    

    大多数时候,您不想使用全局变量,因为您并不真正知道在调用各种函数时它们会发生什么(参见上面的示例,您不知道 a 的值是否已被修改f2f3)。

    一个局部变量只能在它被声明的“作用域”中使用:

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

    在你的例子中,你声明了两个全局变量,但你没有全局使用它们(因为你在本地声明了同名的变量,见下文),所以你应该简单地在你的 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 ;
        /* ... */
    }
    

    请注意,当您这样做时:

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

    您声明了类型struct student_s,同时声明了变量student,而如果您在最后删除student,您仍然声明了struct student_s 类型而不是student 变量any更多的。

    在您的代码中,您执行了以下操作:

    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) ;
    }
    

    输出将是5,而不是8,因为在f 中,名称a 对应于函数的参数,而不是全局变量。

    【讨论】:

    • [...] 并且可以被在变量声明之后声明的任何函数使用。你应该更加小心这里的话。全局变量可以被在该变量之前声明的函数使用,只要函数定义出现在全局变量声明之后。声明和定义不是一回事。
    • @FilipeGonçalves 你完全正确,我已经更新了我的答案。
    【解决方案4】:

    这没什么。只需在 main 中声明它们。没有技巧。

    // 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】:

      在文件的顶部有一个struct student_s {...} student;

      这既定义了一个结构,又为其分配了一个变量student

      下一行,struct student_s anotherStudent; 分配它的另一个变量。

      因为它们没有在函数内部声明,所以它们是全局的。为了使它们本地化,它们必须在函数中声明,例如:

      int main()
      {
          int i;
      

      它定义了一个局部整数变量i

      我不会提供代码;这是你的作业,但我希望我给你足够的澄清。

      【讨论】:

      • typedef 不需要将定义转换为类型
      • 为什么需要 typedef 步骤?
      • 我认为,如果没有 typedef,您将拥有一个未命名的变量。编译器会把它扔掉,但如果你不使用 typedef,基本上你声明一个变量。
      • stackoverflow.com/questions/31877661/… 上查看我的问题,它解释了我的想法哪里出错了。所以请不要再投反对票了。
      • @paul:如果您想避免投票,请改进您的答案。 (例如,删除以“in your case...”开头的段落,这是不正确的。)
      【解决方案6】:

      使用数组:

      #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;
      }
      

      【讨论】:

      • 这根本不能回答问题。
      猜你喜欢
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-14
      相关资源
      最近更新 更多