【问题标题】:Dereferencing the fields of a structure in C在 C 中取消引用结构的字段
【发布时间】:2013-11-05 23:26:27
【问题描述】:

我有:

typedef struct table {

int size;

} Table;

所以我有一个方法的参数:

Table **table

但是当我这样做时:

table->size = 5;

或者:

*table->size = 5;

它不起作用,我的标志给了我错误:在不是结构或联合的东西中请求成员“大小”

请帮忙。

【问题讨论】:

  • 不,我需要 Table **table 作为这个项目的参数参数

标签: c data-structures struct dereference


【解决方案1】:

取消引用运算符 (*) 的优先级较低,因此:

*table->size

被评估为:

*(table->size)

由于table 是指向指针的指针,并且指针不能有成员,因此会出现错误。你需要的是:

(*table)->size = 5;

现在,首先计算*table,产生一个指向Table 的指针。然后可以将-> 应用于它。

无关的:

我注意到您对结构名称和它的 typedef 使用了不同的标识符。这是没有必要的。您可以使用:

typedef struct Table {
    int size;
} Table;

【讨论】:

    【解决方案2】:

    为了避免所有奇怪的间接,使用局部变量更容易:

    void myfunc(Table ** my_table) {
        Table * ptable = *my_table;
        ptable->size = 5;
    
        /*  etc  */
    }
    

    但正如其他人指出的那样,(*table)->size = 5 之类的会做同样的事情。

    如果您需要修改指向的内容,那么:

    void myfunc(Table ** my_table) {
        Table * ptable = malloc(sizeof(*ptable));
    
        /*  Do stuff with new table, then update argument  */
    
        *my_table = ptable;
    }
    

    这是后者的一个例子:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct table {
        int size;
    } Table;
    
    int create_table(Table ** table, int size) {
        Table * new_table = malloc(sizeof(*new_table));
        if ( new_table == NULL ) {
            return -1;
        }
    
        new_table->size = size;
    
        *table = new_table;
        return 0;
    }
    
    int main(void) {
        Table * my_table;
    
        if ( create_table(&my_table, 5) == -1 ) {
            fprintf(stderr, "Couldn't allocate memory for new table.\n");
            return EXIT_FAILURE;
        }
    
        printf("New table size is %d\n", my_table->size);
    
        free(my_table);
    
        return 0;
    }
    

    当然,您可以只让create_table()Table * 返回到新创建的表,但在您的情况下,该函数已被声明为返回int。可能有多种原因,但在上面我只是假设它是返回一个错误代码。正如我们所知,C 中的函数只能返回一个值,所以如果它返回 int,它也不能返回 Table *,所以获取新指针的唯一方法是修改参数,并且如果你想修改Table *,你必须传递Table *的地址,所以你的函数必须接受Table **

    【讨论】:

    • Ok Table **table 参数作为参数传入以创建表。
    • 喜欢:int create_table(Table **table, int size, etc...) {
    • 那么在这种情况下,为什么table会有双指针呢?不是没用吗?
    • 大概你传递了一个指向它的指针的地址,我来举个简单的例子。
    • @user2817240:添加了一个例子和一个解释来说明为什么这种类型的东西不是没用的。
    【解决方案3】:

    如果使用table_t **mytable(*mytable)-&gt;size = 5;

    如果使用table_t *mytablemytable-&gt;size = 5;

    typedef struct /* table */ {
        int size;
    } table_t;  //conventional naming
    
    int main() {
        table_t *mytable = malloc((sizeof *mytable)); //avoid "Access Violation", by allocating memory
        mytable->size = 5; //set size to '5'
        return 0; //conventional return
    }
    

    【讨论】:

    • 这与问题无关:-/需要通过引用获得Table*的函数参数,将需要使用Table**(对于任何类型foo,如果您需要要通过引用传递,您需要使用foo*。)这就是问题所在。
    • 那么他所要做的就是添加一个额外的'*'
    • 然后你得到table_t **mytable 并且你没有回答任何问题就回到了原来的问题:-P
    • 并更改main() 中除return 0; 之外的所有其他行。
    • 顺便说一句,_t 是某些操作系统(如 Mac OS X 和 Linux,以及通常在所有试图支持 POSIX 的系统)上的保留后缀,除非您知道自己,否则不应使用不在那些系统上。
    猜你喜欢
    • 2017-01-13
    • 1970-01-01
    • 2023-04-07
    • 2017-02-26
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    相关资源
    最近更新 更多