从现有结构数组中查找并返回指向结构的指针

时间:2016-03-26 02:28:53

标签: c pointers struct

尝试使用数组返回指向已存在结构的指针时,出现不兼容的类型错误。

以下是相关的结构定义:

typedef struct cust_t* Customer;
typedef struct item_t* Item;

struct item_t {
    int id;
    char *label;
};


struct cust_t {
    int id;
    int basket_size;
    Item basket;
};

正如您所看到的,这些结构定义了一个拥有一篮子物品的顾客。因此basketItem的数组。

然后我有以下两个功能:

/*
Add data to the item with id item_id in the basket of cust
*/
void add_item_data(Customer cust, int item_id, void* data) {
    Item *v;
    v = find_item(cust, item_id);

    //Use the pointer to the item, v, and attribute data to it (unimplemented)
}

/*
Find the item with id id in the basket of cust, and return a pointer to it.

Assumes that the id of all items have been previously defined.
*/
Item *find_item(Customer cust, int id){

    Item *v;

    //Iterate over the length of basket looking for a match in the id's...
    for (int i = 0; i < cust->basket_size; i++){
        if (cust->basket[i].id == id){
            v = cust->basket[i];
            return v;
        }
    }
    //if the item is not in the basket, return null. program should not reach here
    return NULL;
} 

你可以看到第二个函数假设篮子已经有许多项目,其id已经设置好了。 void* data将包含label和其他信息。

我的问题出在find_item函数中,我希望它返回指向Item中已存在的basket结构的指针,因此add_item_data可以使用它。< / p>

编译时,我收到以下错误:

error: incompatible types when assigning to type 'struct item_t **' from type 'struct item_t'
v = cust->basket[i];

我猜我的指针语法已关闭,但我看不到。

2 个答案:

答案 0 :(得分:1)

vItem*类型的变量,item_t**

cust->basket属于Item类型,item_t*,因此任何cust->basket[i]都是item_t

现在你正试图这样做:

v = cust->basket[i];

我认为错误很明显:您的错误消息指出,您正在尝试将item_t类型的值分配到item_t**变量中。

考虑不使用typedef来屏蔽这样的指针,因此您总是可以一眼就知道变量是否是指针。

答案 1 :(得分:1)

您已将Item作为指针键入item_t结构。您对Customer的typedef有类似的情况。这在语义上很尴尬。 Item *可以更好地解释为Items数组,特别是指向数组中第一个Item的地址的指针。如果你不熟悉数组和指针的想法,这里有一个启动器(对于C ++,但两种语言的概念是相同的,唯一的C ++特定部分是使用std::cout <<打印到控制台):http://www.learncpp.com/cpp-tutorial/6-8-pointers-and-arrays/(这个和下一个,特别是关于[]运算符的部分)

您的函数find_item将返回指向Item的指针。而Item是指向item_t的指针,因此您最终得到item_t **类型。指向item_t的指针。

如上所述,

v最终是item_t **。 cust是cust_t *。在if语句中,您实际上正确地使用了链接中的概念:cust->basket[i].id

basket指向item_t。使用[]运算符,它将指针偏移i,然后取消引用该指针。换句话说,basket[i]*(basket + i)

相同

这意味着你得到一个实际的item_t,而不是指针。然后在它下面你误用了这个概念。 basket[i]会返回实际的item_t,并且您尝试将其分配给item_t **(因此您的错误)。演员没有帮助,这不是你的问题。你正试图将一个苹果变成一块奶酪。

我建议你从顶部开始,不要在typedef中隐藏指针。这使得阅读令人困惑。基于你的话,“我希望它返回一个指向已经存在的Item结构的指针”我认为你误解了你所做的事情。你没有返回一个指向项结构的指针,你正在返回指针......指向一个项结构的指针。

无论如何,你说你不能因为某种原因改变typedef,所以只是为了让你至少工作(虽然我不确定这实际上会按照你的想法),改变函数的返回类型只是一个项目,并将你从数组中提取出来的地址分配给v。像这样:(未经过验证,但希望你明白这一点)

Item find_item(Customer cust, int id){

    Item v;
     //snip snip
            v = &(cust->basket[i]); //using & as address-of operator here
            return v;
     //snip snip

编辑:查看您的评论,我认为您可能不熟悉“地址”运算符。这就是你如何获得指向存在的东西的指针。 cust->basket[i]是item_t,而&amp;获取item_t的地址,您可以将其分配给item_t指针,该指针已作为Item键入。