C 我什么时候需要一个带结构的指针

C 我什么时候需要一个带结构的指针,c,pointers,C,Pointers,我真的不明白是否以及何时需要声明指向数据结构的指针 我有两个程序,都是一样的,但我不知道我应该在哪里需要一个指针或不 以下是节目: #include <stdio.h> #include <stdlib.h> #include <string.h> struct data { char *ptr; }; void printStruct( struct data pers ); int main (void) { struct data

我真的不明白是否以及何时需要声明指向数据结构的指针

我有两个程序,都是一样的,但我不知道我应该在哪里需要一个指针或不

以下是节目:

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

struct data
{
    char *ptr;
};

void printStruct( struct data pers );

int main (void)
{
    struct data pers;   // Here pers is not a POINTER

    pers.ptr = malloc(sizeof (char) * 256);
    strcpy(pers.ptr, "Hello World");

    printStruct(pers);
    free(pers.ptr);
}

void printStruct( struct data pers ){
    printf("PTR = %s\n", pers.ptr);
}

有四种情况需要使用指向结构的指针:

  • 您希望函数写入
    struct
    类型的参数:
    struct foo { int member; }
    
    void updateFoo( struct foo *bar )
    {
      bar->member = some_new_value();
    }
    
    int main( void )
    {
      struct foo f = {0};
      ...
      updateFoo( &f );
    }
    
  • 要动态分配
    结构的一个或多个实例
    类型:
    struct foo *farr = malloc( sizeof *farr * NUM_ELEMENTS );
    
  • 您正在使用带有灵活数组成员的
    struct
    类型:
    struct foo { int x; char y[]; }
    
    struct foo *instance = malloc( sizeof *instance + LENGTH_FOR_Y_MEMBER );
    
  • 您希望定义一个自引用类型(即,
    struct foo
    的每个实例指向
    struct foo
    的不同实例):
    struct list_node { int data; struct list_node *next; }
    
    这是单链接列表的常见实现-列表中的每个元素都显式指向列表中的下一个元素(如果位于最后一个元素,则为
    NULL
    )。 您也可以选择将指向
    struct
    的指针传递给函数,即使该函数不修改参数,这只是为了节省在被调用函数中创建副本的开销,特别是当
    struct
    类型较大时:

    struct ginormous { /* define many large members here */ };
    
    void blah( const struct ginormous *g )
    {
      // do stuff with g
    }
    

    经验法则:除非你需要指针,否则你不需要指针。如果你不使用指针就能实现目标,就不要使用它。这同样适用于每一个概念,尤其是那些你还没有掌握的概念。我不是问我应该在何时何地使用指针,但在这种情况下使用结构变量,我真的不知道哪里需要指针。可以吗请给我一个需要指针的例子。有时,有几种方法可以实现同一用例的解决方案。当您在编译时不知道对象的地址时,就需要指针。例如,动态分配内存时(因为它可能在任何地方),当“通过引用”传递对象时(因为可以使用不同的对象调用函数),在扫描数组时(因为下一项是由程序计算的)。一般来说,如果您继续使用C编程(首先避免使用指针),您很快就会达到需要指针的程度。因此,我之前的建议是:继续编程:)作为一般规则,除非确实需要复制结构,否则要避免复制结构。因此,与其将结构作为函数参数传递,不如传递指向它的指针,避免复制整个结构。很少需要将结构本身作为函数参数传递。有什么特别的好处吗如果
    3
    以这种方式分配整个结构,而不是分配
    sizeof(*实例)
    然后再分配
    char y[]
    ?当我尝试这种方法时,我的linter对我大喊大叫。@DevNull:TBH,我从来没有在我自己的代码中使用过灵活的数组成员。我认为主要的好处是使序列化更容易;你可以
    memcpy
    一次复制整个实例,而不是复制它的一部分,追踪指针,然后复制其余的。
    struct ginormous { /* define many large members here */ };
    
    void blah( const struct ginormous *g )
    {
      // do stuff with g
    }