为什么在创建结构时需要地址运算符(&)?
Why is address operator (&) needed when creating struct?
我有一些代码可以工作,但我不明白为什么。这是有问题的代码:
struct SceneInterface *TitleAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
我得到了函数指针和指定的初始化程序,但是 &(struct SceneInterface) 部分在做什么?一般是address of,但是括号里的东西是类型,不是变量,那它指的是什么呢?如果它返回一个指向 struct SceneInterface 的指针,那么左侧已经是那个,所以我不明白为什么需要它以及为什么如果删除它会出现分段错误。
这里是完整的工作代码供参考:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
struct SceneInterface {
void (*update)(void *instance);
void (*render)(void *instance);
};
struct Scene {
void *instance;
const struct SceneInterface *interface;
};
struct Scene *scene_create(void *instance, struct SceneInterface *interface)
{
struct Scene *scene = (struct Scene *) malloc(sizeof(struct Scene));
scene->instance = instance;
scene->interface = interface;
return scene;
}
void scene_update(struct Scene *scene)
{
// return this if function has a return type
(scene->interface->update)(scene->instance);
}
void scene_render(struct Scene *scene)
{
(scene->interface->render)(scene->instance);
}
struct Boot {
double x;
};
struct Boot *boot_create(double sideLength)
{
struct Boot *boot = (struct Boot *) malloc(sizeof(struct Boot));
boot->x = sideLength;
return boot;
}
void boot_update(struct Boot *boot)
{
printf("boot update\n");
}
void boot_render(struct Boot *boot)
{
printf("boot render\n");
}
struct Title {
double radius;
};
struct Title *title_create(double radius)
{
struct Title *title = (struct Title *) malloc(sizeof(struct Title));
title->radius = radius;
return title;
}
void title_update(struct Title *title)
{
printf("title update\n");
}
void title_render(struct Title *title)
{
printf("title render\n");
}
int main(int argc, char **argv)
{
struct Boot *boot = boot_create(10.0);
struct Title *title = title_create(5.0);
struct SceneInterface *BootAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) boot_update,
.render = (void (*)(void *)) boot_render,
};
struct SceneInterface *TitleAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
struct Scene *bootScene = scene_create(boot, BootAsScene);
struct Scene *titleScene = scene_create(title, TitleAsScene);
boot_update(boot);
scene_update(bootScene);
boot_render(boot);
scene_render(bootScene);
title_update(title);
scene_update(titleScene);
title_render(title);
scene_render(titleScene);
return 0;
}
struct SceneInterface *BootAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) boot_update,
.render = (void (*)(void *)) boot_render,
};
您不创建结构仅将指针分配给具有的地址(参考)的结构]复合文字。 &
需要得到这个文字的地址。
你必须记住,复合文字只有周围范围的生命周期。
struct SceneInterface *TitleAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
可以读作
"TitleAsScene
是一个指向struct SceneInterface
的指针,其初始值为struct SceneInterface
的地址构造如下..."
换句话说,指针是用您用成员初始化语句初始化的结构的地址初始化的。
您所指的语法是一个复合文字,似乎是强制转换后跟一个初始值设定项列表。它创建给定类型的临时对象。有问题的行然后获取该临时对象的地址并将其放置在指针中。
然而,在这里使用复合文字并没有多大意义。代码可以像这样轻松编写:
struct SceneInterface BootAsScene = {
.update = (void (*)(void *)) boot_update,
.render = (void (*)(void *)) boot_render,
};
struct SceneInterface TitleAsScene = {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
struct Scene *bootScene = scene_create(boot, &BootAsScene);
struct Scene *titleScene = scene_create(title, &TitleAsScene);
但是这段代码还有另一个问题。函数指针被转换为不同的类型,随后通过该转换类型调用。通过不兼容的函数指针类型调用函数会触发 undefined behavior.
应更改函数以接受 void *
参数并将参数转换为函数内部的适当类型。
我有一些代码可以工作,但我不明白为什么。这是有问题的代码:
struct SceneInterface *TitleAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
我得到了函数指针和指定的初始化程序,但是 &(struct SceneInterface) 部分在做什么?一般是address of,但是括号里的东西是类型,不是变量,那它指的是什么呢?如果它返回一个指向 struct SceneInterface 的指针,那么左侧已经是那个,所以我不明白为什么需要它以及为什么如果删除它会出现分段错误。
这里是完整的工作代码供参考:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
struct SceneInterface {
void (*update)(void *instance);
void (*render)(void *instance);
};
struct Scene {
void *instance;
const struct SceneInterface *interface;
};
struct Scene *scene_create(void *instance, struct SceneInterface *interface)
{
struct Scene *scene = (struct Scene *) malloc(sizeof(struct Scene));
scene->instance = instance;
scene->interface = interface;
return scene;
}
void scene_update(struct Scene *scene)
{
// return this if function has a return type
(scene->interface->update)(scene->instance);
}
void scene_render(struct Scene *scene)
{
(scene->interface->render)(scene->instance);
}
struct Boot {
double x;
};
struct Boot *boot_create(double sideLength)
{
struct Boot *boot = (struct Boot *) malloc(sizeof(struct Boot));
boot->x = sideLength;
return boot;
}
void boot_update(struct Boot *boot)
{
printf("boot update\n");
}
void boot_render(struct Boot *boot)
{
printf("boot render\n");
}
struct Title {
double radius;
};
struct Title *title_create(double radius)
{
struct Title *title = (struct Title *) malloc(sizeof(struct Title));
title->radius = radius;
return title;
}
void title_update(struct Title *title)
{
printf("title update\n");
}
void title_render(struct Title *title)
{
printf("title render\n");
}
int main(int argc, char **argv)
{
struct Boot *boot = boot_create(10.0);
struct Title *title = title_create(5.0);
struct SceneInterface *BootAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) boot_update,
.render = (void (*)(void *)) boot_render,
};
struct SceneInterface *TitleAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
struct Scene *bootScene = scene_create(boot, BootAsScene);
struct Scene *titleScene = scene_create(title, TitleAsScene);
boot_update(boot);
scene_update(bootScene);
boot_render(boot);
scene_render(bootScene);
title_update(title);
scene_update(titleScene);
title_render(title);
scene_render(titleScene);
return 0;
}
struct SceneInterface *BootAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) boot_update,
.render = (void (*)(void *)) boot_render,
};
您不创建结构仅将指针分配给具有的地址(参考)的结构]复合文字。 &
需要得到这个文字的地址。
你必须记住,复合文字只有周围范围的生命周期。
struct SceneInterface *TitleAsScene = &(struct SceneInterface) {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
可以读作
"TitleAsScene
是一个指向struct SceneInterface
的指针,其初始值为struct SceneInterface
的地址构造如下..."
换句话说,指针是用您用成员初始化语句初始化的结构的地址初始化的。
您所指的语法是一个复合文字,似乎是强制转换后跟一个初始值设定项列表。它创建给定类型的临时对象。有问题的行然后获取该临时对象的地址并将其放置在指针中。
然而,在这里使用复合文字并没有多大意义。代码可以像这样轻松编写:
struct SceneInterface BootAsScene = {
.update = (void (*)(void *)) boot_update,
.render = (void (*)(void *)) boot_render,
};
struct SceneInterface TitleAsScene = {
.update = (void (*)(void *)) title_update,
.render = (void (*)(void *)) title_render,
};
struct Scene *bootScene = scene_create(boot, &BootAsScene);
struct Scene *titleScene = scene_create(title, &TitleAsScene);
但是这段代码还有另一个问题。函数指针被转换为不同的类型,随后通过该转换类型调用。通过不兼容的函数指针类型调用函数会触发 undefined behavior.
应更改函数以接受 void *
参数并将参数转换为函数内部的适当类型。