尝试使用数组返回指向已存在结构的指针时,出现不兼容的类型错误。
以下是相关的结构定义:
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;
};
正如您所看到的,这些结构定义了一个拥有一篮子物品的顾客。因此basket
是Item
的数组。
然后我有以下两个功能:
/*
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];
我猜我的指针语法已关闭,但我看不到。
答案 0 :(得分:1)
v
是Item*
类型的变量,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键入。