C 如何将局部结构传递给函数?

C 如何将局部结构传递给函数?,c,scope,sdl,pass-by-reference,sdl-2,C,Scope,Sdl,Pass By Reference,Sdl 2,下面的链接指出,main中定义的结构没有函数调用的范围,因为它们是本地的,所以您应该全局定义结构。但是对于变量,最好在本地声明变量,并用指针传递给函数,而不是声明全局变量 在纯C中,有没有一种方法可以使用指针等将main中定义的结构传递给函数?如果您不介意,请使用示例程序演示该方法。谢谢 这段代码有效,但不是我想要的。我想在main中定义结构。这可能吗 #include <stdio.h> #include <SDL2/SDL.h> void function();

下面的链接指出,
main
中定义的结构没有函数调用的范围,因为它们是本地的,所以您应该全局定义结构。但是对于变量,最好在本地声明变量,并用指针传递给函数,而不是声明全局变量

在纯C中,有没有一种方法可以使用指针等将main中定义的结构传递给函数?如果您不介意,请使用示例程序演示该方法。谢谢

这段代码有效,但不是我想要的。我想在
main
中定义结构。这可能吗

#include <stdio.h>
#include <SDL2/SDL.h>

void function();

struct hexColour
    {
        Uint32 red;
    }hc;

int main(void)
{
    hc.red = 0xFFFF0000;
    function(hc);
    return 0;
}

void function(struct hexColour hc)
{
    printf("red is %x\n", hc.red);
}

首先,您应该真正使用与函数定义匹配的适当原型

其次,您的示例将结构传递到函数中的局部变量
hc

函数
运行时,内存中有两个不同且独立的结构:一个在
函数中,另一个在
函数
函数中


为了说明我的基本观点,以下是另外两个问题的两个答案:

  • 您希望在
    main
    函数中定义结构本身,然后能够在其他函数中使用它

    差不多

    int main(void)
    {
        struct hexColor
        {
            uint32_t white;
            // Other members omitted
        };
    
        struct hexColour hc;
        hc.white = 0xff;
    
        func(hc);  // Assume declaration exist
    }
    
    void func(struct hexColour my_colour)
    {
        printf("White is %u\n", my_colour.white);
    }
    
    这是不可能的。结构
    hexcolor
    仅在
    main
    函数中定义。没有其他函数可以使用该结构。无论是否传递指针,结构
    hexcolor
    仍将仅存在于
    main
    函数中

  • 通过向结构对象传递指针来模拟按引用传递。像

    struct hexColor
    {
        uint32_t white;
        // Other members omitted
    };
    
    int main(void)
    {
        struct hexColour hc;
        hc.white = 0xff;
    
        // Assume declaration of function exists
        func(&hc);  // Emulate pass-by-reference by passing a pointer to a variable
    }
    
    void func(struct hexColour *colourPointer)
    {
        colourPointer->white = 0x00;
    }
    
    这是可能的,因为结构
    hexcolor
    存在于全局范围内的
    main
    函数之外。在结构定义之后声明和定义的所有函数都可以使用结构及其成员


  • 如果按值传递,则会生成副本(代价高昂,修改不会反映在外部)。如果要传递指向
    结构的指针,只需使用,即可,但这并不意味着通过引用传递
    结构(C没有引用),而是通过值传递指向
    结构的指针

    void function(struct hexColour* hc) {
      printf("red is %x", hc->red);
    }
    
    int main() {
      ...
      functon(&hc);
      ...
    }
    
    见:

    • 函数的签名从
      struct hexColor
      更改为
      struct hexColor*
      ,因此您正在传递指针(按值)
    • 要在处理指针时访问
      结构的字段,请使用
      ->
      而不是
    • 调用函数时,需要获取结构的地址,
      function(hc)
      变为
      function(&hc)

    现在,由于您正在向结构传递地址,因此对实际值进行了任何修改。

    您似乎不完全理解链接的问题及其答案。你写

    下面的链接表示main中定义的结构没有 函数调用的范围,因为它们是本地的,所以您应该 全局定义结构

    这里的歧义存在于结构类型(如
    struct hexcolor
    )和具有这些类型的对象(如
    hc
    )之间。应该声明结构类型和结构对象,以便它们在所有需要它们的地方都在作用域中,但对于这两种不同类型的实体和不同的情况,结果是不同的

    但是对于变量,最好在本地声明变量 并通过引用传递,而不是声明全局变量

    通常最好使用块作用域变量而不是文件作用域变量,是的,但C只有按值传递,没有按引用传递。在很多情况下,传递指针(通过值)而不是指针指向的对象是有利的,这接近于通过引用传递,但肯定没有规则或一般惯例表明传递指针普遍优于传递指针指向的对象

    有吗 纯C语言中使用指针等将本地结构传递给 功能

    调用者和被调用者都必须就每个参数的类型达成一致,实现这一点的方法有很多。但是,在如何以有效的方式处理此类问题方面,有一些与C一起发展起来的约定。其中最重要的是:

    • 要在多个翻译单元中使用的任何函数和任何非内置类型都应该在头文件中声明,并且该头文件包含在每个需要它的翻译单元中
    这是你用“全局”定义表述的规则的概括。例如:

    颜色.h

    #ifndef COLOUR_H
    #define COLOUR_H
    
    struct hexColour {
        Uint32 white;
        Uint32 black;
        Uint32 red;
        Uint32 pink;
        Uint32 grey;
    }; // Note that only the type is declared here, not any objects
    
    void function(struct hexColour hc);
    
    #endif
    
    请注意,类型
    struct hexcolor
    的声明出现在具有该类型参数的函数
    function
    的声明之前。 然后,您可以使用具有适当位置的这些类型和函数,例如:

    main.c

    #include "colour.h"
    
    int main(void) {
        struct hexColour hc = {
            .white = 0xFFFFFFFF, .black = 0xFF000000, .red = 0xFFFF0000,
            .pink = 0xFFFF9999,  .grey = 0xFFA0A0A0 };
    
        function(hc);
        return 0;
    }
    
    void function(struct hexColour hc) {
        printf("red is %x\n", hc.red);
    }
    
    请注意,此处构成其定义一部分的
    函数的声明与标题中的声明相匹配。该定义
    function()
    可以很容易地在不同的源文件中定义,只要调用方有头文件告诉它该函数是如何声明的。您可以根据需要将
    #coulour.h包含到任意多个不同的源文件中

    但是请注意,在这种情况下,结构是按值传递的。这是定义良好且完全可以接受的,但由于函数只接收一个副本,因此无法对调用方的原始副本进行更改。如果希望函数能够做到这一点,则需要传递指向结构(按值)的指针,而不是结构本身:

    void function(struct hexColour *hc) {
        // ...
    }
    
    int main(void) {
        // ...
        function(&hc);
        // ...
    }
    
    你可以拿一个本地的def
    void function(struct hexColour *hc) {
        // ...
    }
    
    int main(void) {
        // ...
        function(&hc);
        // ...
    }
    
    void f1(struct s);
    
    int main()
    {
        struct s s1;
        f1(s1);
    }
    
    void f2(struct s *);
    
    int main()
    {
        struct s s2;
        f2(&s2);
    }
    
    struct s f3()
    {
        struct s ret;
        /* ... */
        return ret;
    }
    
    struct s *f4()
    {
        struct s ret;
        /* ... */
        return &ret;     /* WRONG */
    }
    
    void f5();
    
    int main()
    {
        struct s s1;
        f5();
    }
    
    void f5()
    {
        int x = s1.field;    /* WRONG */
    }
    
    void f1(struct s);
    
    int main()
    {
        struct s { int a, b; } s1;
        f1(s1);
    }
    
    void f1(struct s arg)    /* error: this struct s might not be the same as the previous one */
    {
        int x = arg.b;       /* error: compiler might not know that struct s contains a and b */
    }