我正在创建* create Schedule()函数以生成ScheduleData数据类型的日程表,但是我收到错误消息:分配给类型'ScheduleData'时,类型不兼容。有人可以帮我解决这个问题吗?
在Schedule *函数createSchedule()中,在一行schedule->节点[i] [j] = schData中; 错误发生
struct ScheduleData {
char *initials;
char *classroom;
char *teacher;
};
struct Schedule {
ScheduleData node[8][6];
};
Schedule *createSchedule() {
Schedule *schedule = malloc(sizeof(Schedule));
ScheduleData *schData;
for (int i = 0; i < 8; i++)
for (int j = 0; j < 6; j++) {
schData = malloc(sizeof(ScheduleData));
schData -> initials = NULL;
schData -> classroom = NULL;
schData -> teacher = NULL;
schedule->node[i][j] = schData;
}
return schedule;
}
答案 0 :(得分:3)
您的struct Schedule
拥有一组实际的struct ScheduleData
结构;您尝试将指针分配给这些结构以及编译器对象。您不需要嵌套循环中的malloc()
操作(或对schedule->node[i][j]
的赋值),或者您需要ScheduleData *node[8][6];
。我建议不要在循环中使用malloc()
。
此外,正如Martin Rosenau中提到的comment一样,给定声明Schedule
,C编译器不会生成名称struct Schedule { … };
(在“普通标识符”命名空间中) —尽管C ++编译器可以。您需要添加:
typedef struct Schedule Schedule;
typedef struct ScheduleData ScheduleData;
在使用名称Schedule
或ScheduleData
而不使用前struct
之前。如果您是使用C ++而不是C编写的,则需要修复问题的标签,并且需要停止使用malloc()
等。如果必须在C ++中使用malloc()
等,则需要显式强制转换将void *
转换为正确的类型-在C中,强制转换是不必要的。
malloc()
的电话Schedule *createSchedule(void)
{
Schedule *schedule = calloc(sizeof(Schedule), 1);
return schedule;
}
使用calloc()
将结构中的所有字节清零,通常会将所有指针设置为NULL,等等。(调用代码的责任在于检查是否不返回空指针。)或者:
Schedule *createSchedule()
{
Schedule *schedule = malloc(sizeof(Schedule));
if (schedule != NULL)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 6; j++)
{
schedule->data[i][j].initials = NULL;
schedule->data[i][j].classroom = NULL;
schedule->data[i][j].teacher = NULL;
}
}
}
return schedule;
}
您还可以使用memset()
将malloc()
提供的数据归零,但是使用calloc()
至少可以有效地做到这一点。
malloc()
将struct Schedule
的类型更改为:
struct Schedule
{
ScheduleData *node[8][6];
};
请注意,这会占用更多的内存(每次分配都有开销),并且结构的释放也更加困难(您需要对free()
进行49次调用,而不仅仅是1次)。
.
或箭头->
运算符周围放置空格。它们紧密地捆绑在一起;该空间是不必要的,常规的,并且使您的代码更难阅读。Schedule *createSchedule(void)
,以指示没有参数。 C不是C ++;两者之间的规则是不同的。并且明确声明void
意味着编译器将警告您createSchedule(32, "pink elephants")
,而如果您未明确指定void
,则它没有义务警告您滥用该功能–如果您省略void
,则不会创建原型,而只是创建函数声明。答案 1 :(得分:2)
Schedule *createSchedule(void)
{
// make sure you cast the return arg of malloc!
Schedule *schedule = (Schedule*)malloc(sizeof(Schedule));
// no need to allocate each 6x8node, already done
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 6; j++) {
schedule->node[j][i]->initials = NULL;
schedule->node[j][i]->classroom = NULL;
schedule->node[j][i]->teacher = NULL;
}
}
return schedule;
}
或者,由于Schedule中的每个字节都设置为0,因此您可以在创建后在此处使用memset()
:
Schedule *createSchedule(void)
{
// make sure you cast the return arg of malloc!
Schedule *schedule = (Schedule*)malloc(sizeof(Schedule));
memset(schedule, 0, sizeof(Schedule));
return schedule;
}
答案 2 :(得分:2)
如何修复C语言中的“不兼容类型”错误?
您需要问两个问题:
schedule->node[i][j]
是什么类型?
答案:是ScheduleData
schData
是什么类型?
答案:它是ScheduleData *
(即指向ScheduleData
的指针)
由于两个变量具有不同的类型,因此会出现编译错误。
要解决此问题,您需要更改其中一个变量的类型以匹配另一个变量。
从您的代码看来,您似乎想将schedule->node[i][j]
更改为ScheduleData *
。因此,您所需要做的就是:
struct Schedule {
ScheduleData *node[8][6];
// notice ^
};
顺便说一句:您已经标记了问题C,但似乎您使用的是C ++编译器。如果您确实想要C ++,请修复该标记。如果您真的想要C,请使用C编译器。
答案 3 :(得分:1)
我的答案不是实际答案,而是对Jonathan Leffler's answer的扩展:
我经常阅读像您一样的问题。在大多数情况下,将C和C ++与Java或C#进行比较会引起误解:
在Java中,原始数据类型(如int
的变量保留值,而class
数据类型的值保留对对象的引用。
“参考”表示在以下程序中:
ScheduleData a = b;
a.initials = "ab";
b.initials = "xy";
... 相同变量由语句a.initials
和b.initials
访问。
但是, C和C ++的工作方式不同:
您可以通过在数据类型和数据类型之间使用星号(*
)来决定变量是“指针”(或多或少是“引用”)还是值。变量名。示例:
ScheduleData a, *b;
int c, *d, *e;
d = e;
在此示例中,变量a
和c
保存值,变量b
,d
和e
保存引用。
就像在Java示例中一样,修改值d
指向的效果与修改值e
指向的效果相同,因为d
和e
是引用到相同的整数。
Jonathan Leffler的答案中的第一个解决方案建议使用数据类型为ScheduleData
的值,而不使用引用。
第二种解决方案向您展示了如何使用引用。避免引用通常会使编程更容易,但如果要执行以下Java程序的等效操作,则可能需要引用:
ScheduleData x = node[4][2];
ScheduleData y = node[4][2];
node[4][2] = new ScheduleData();
/* x and y will be a reference to the same data structure but node[4][2]
* is a reference to a different data structure */
顺便
您编写的程序是C ++程序,而不是C程序。
与C ++一样,C不会自动将结构名称识别为数据类型。相反,您必须使用typedef
定义数据类型:
typedef struct _s_ScheduleData {
...
} ScheduleData;
...,或者您必须使用struct
关键字作为数据类型的一部分:
struct ScheduleData node[8][6];
答案 4 :(得分:0)
您可以用简单的分配替换所有循环:
Schedule *createSchedule(void) {
// ^^^^ use this to indicate no parameters
Schedule *schedule = malloc(sizeof(Schedule));
*schedule = (Schedule){0};
return schedule;
}
(Schedule){0}
创建一个临时对象,并且初始化程序意味着所有指针都将设置为空指针。
如果您的编译器很旧,则可以用Schedule blank = {0}; *schedule = blank;
替换赋值行。