C 使用函数指针、结构、联合和枚举进行子类型化
前言:是的,这是家庭作业。上个星期左右,我一直在做这件事,谷歌搜索也帮不上忙。我不是在找人帮我完成作业,我更关心的是理解材料,我只是在寻找任何建设性的批评或朝着正确的方向推进 我有3个形状结构(圆形、三角形和矩形)、3个形状结构的并集、函数指针的结构、形状的枚举以及上述所有结构(并集、形状类型和函数指针)的结构 问题:我需要完成子类型/超级类型,以便驱动程序在不知道形状细节的情况下操作形状。我相信我已经完成了大部分框架,但是在函数指针和使用ShapeType enum和Shape struct实现它们方面有点迷失 原型.hC 使用函数指针、结构、联合和枚举进行子类型化,c,struct,enums,unions,subtyping,C,Struct,Enums,Unions,Subtyping,前言:是的,这是家庭作业。上个星期左右,我一直在做这件事,谷歌搜索也帮不上忙。我不是在找人帮我完成作业,我更关心的是理解材料,我只是在寻找任何建设性的批评或朝着正确的方向推进 我有3个形状结构(圆形、三角形和矩形)、3个形状结构的并集、函数指针的结构、形状的枚举以及上述所有结构(并集、形状类型和函数指针)的结构 问题:我需要完成子类型/超级类型,以便驱动程序在不知道形状细节的情况下操作形状。我相信我已经完成了大部分框架,但是在函数指针和使用ShapeType enum和Shape struct实
#include <my_struct.h>
void InitializeCircle(struct Shape *, double radius, double origin, double originY);
void InitializeRectangle(struct Shape *, double minX, double maxX, double minY, double maxY);
void InitializeTriangle(struct Shape *, Triangle *, double pt1X, double pt2X, double minY, double maxY);
double GetCircleArea(struct Shape *);
double GetCircleArea(struct Shape *);
double GetTriangleArea(struct Shape *);
void GetCircleBoundingBox(struct Shape *, double *);
void GetRectangleBoundingBox(struct Shape *, double *);
void GetTriangleBoundingBox(struct Shape *, double *);
// DEFINITIONS FOR THE THREE SHAPES:
typedef struct {
double radius, origin, originY, area;
} Circle;
typedef struct {
double pt1X, pt2X, minY, maxY, area;
} Triangle;
typedef struct {
double minX, maxX, minY, maxY, area;
} Rectangle;
// SUBTYPING/SUPERTYPING:
struct Shape; // Defined later
typedef struct {
// Pointers to functions -> two data members: GetArea & GetBoundingBox
double (*GetArea)(struct Shape *);
GetArea = // NEED TO IMPLEMENT
double (*GetBoundingBox)(struct Shape *, double *bbox);
GetBoudingBox = // NEED TO IMPLEMENT
} FunctionTable;
typedef union {
// Shape structs:
Circle c;
Triangle t;
Rectangle r;
} ShapeUnion;
typedef enum {
// Identifies the 3 types
Circle,
Rectangle,
Triangle
} ShapeType;
typedef struct {
ShapeUnion su;
ShapeType st;
FunctionTable ft;
} Shape;
我的结构c
/* This file should contain the 9 functions defined in prototypes.h */
#include <prototypes.h>
// Initialize Structs
void InitializeCircle(struct Shape *c, double r, double o, double oY) {
c->radius = r;
c->origin = o;
c->originY = oY;
}
void InitializeRectangle(struct Shape *r, double miX, double maX, double miY, double maY) {
r->minX = miX;
r->maxX = maX;
r->minY = miY;
r->maxY = maY;
}
void InitializeTriangle(struct Shape *t, double p1X, double p2X, double miY, double maY) {
t->pt1X = p1X;
t->pt2X = p2X;
t->minY = miY;
t->maxY = maY;
}
// Get Area
double GetCircleArea(struct Shape *c) {
c->area = 3.14159*c->radius*c->radius;
return c->area;
}
double GetRectangleArea(struct Shape *r) {
r->area = ((r->maxX-r->minX)*(r->maxY-r->minY));
return r->area;
}
double GetTriangleArea(struct Shape *t) {
t->area = (((t->pt2X-t->pt1X)*(t->maxY-t->minY))/2);
return t->area;
}
// Get Bounding Box
void GetCircleBoundingBox(struct Shape *c, double *bbox) {
bbox[0] = c->origin-c->radius; // lower left corner
bbox[1] = c->origin+c->radius; // lower right corner
bbox[2] = c->originY-c->radius; // upper left corner
bbox[3] = c->originY+c->radius; // upper right corner
}
void GetRectangleBoundingBox(struct Shape *r, double *bbox) {
bbox[0] = r->minX;
bbox[1] = r->maxX;
bbox[2] = r->minY;
bbox[3] = r->maxY;
}
void GetTriangleBoundingBox(struct Shape *t, double *bbox) {
bbox[0] = t->pt1X; // minX
bbox[1] = t->pt2X; // maxX
bbox[2] = 0; // minY
bbox[3] = t->maxY; // maxY
}
#include <prototypes.h>
#include <stdio.h>
int main()
{
struct Shape shapes[9];
int i;
InitializeCircle(shapes+0, 1, 0, 0);
InitializeCircle(shapes+1, 1.5, 6, 8);
InitializeCircle(shapes+2, 0.5, -3, 4);
InitializeRectangle(shapes+3, 0, 1, 0, 1);
InitializeRectangle(shapes+4, 1, 1.1, 10, 20);
InitializeRectangle(shapes+5, 1.5, 3.5, 10, 12);
InitializeTriangle(shapes+6, 0, 1, 0, 1);
InitializeTriangle(shapes+7, 0, 1, 0, 0.1);
InitializeTriangle(shapes+8, 0, 10, 0, 50);
for (i = 0 ; i < 9 ; i++)
{
double bbox[4];
printf("Shape %d\n", i);
printf("\tArea: %f\n", shapes[i].ft.GetArea(shapes+i));
shapes[i].ft.GetBoundingBox(shapes+i, bbox);
printf("\tBbox: %f-%f, %f-%f\n", bbox[0], bbox[1], bbox[2], bbox[3]);
}
}
/*此文件应包含prototype.h中定义的9个函数*/
#包括
//初始化结构
无效初始值圆形(结构形状*c,双r,双o,双oY){
c->半径=r;
c->origin=o;
c->originY=oY;
}
void InitializeRectangle(结构形状*r,双重混合,双重最大值,双重最小值,双重可能){
r->minX=miX;
r->maxX=maX;
r->minY=miY;
r->maxY=maY;
}
void InitializeTriangle(结构形状*t,双p1X,双p2X,双miY,双maY){
t->pt1X=p1X;
t->pt2X=p2X;
t->minY=miY;
t->maxY=maY;
}
//获取区域
双GetCircleArea(结构形状*c){
c->面积=3.14159*c->半径*c->半径;
返回c->区域;
}
双GetRectangleArea(结构形状*r){
r->area=((r->maxX-r->minX)*(r->maxY-r->minY));
返回r->区域;
}
双GetTriangelArea(结构形状*t){
t->area=((t->pt2X-t->pt1X)*(t->maxY-t->minY))/2);
返回t->区域;
}
//获取边界框
void GetCircleBoundingBox(结构形状*c,双*bbox){
bbox[0]=c->原点-c->半径;//左下角
bbox[1]=c->原点+c->半径;//右下角
bbox[2]=c->originY-c->radius;//左上角
bbox[3]=c->originY+c->radius;//右上角
}
void GetRectangleBoundingBox(结构形状*r,双*bbox){
bbox[0]=r->minX;
bbox[1]=r->maxX;
bbox[2]=r->minY;
bbox[3]=r->maxY;
}
void gettriangelboundingbox(结构形状*t,双*bbox){
bbox[0]=t->pt1X;//minX
bbox[1]=t->pt2X;//maxX
bbox[2]=0;//minY
bbox[3]=t->maxY;//maxY
}
驱动程序.c
/* This file should contain the 9 functions defined in prototypes.h */
#include <prototypes.h>
// Initialize Structs
void InitializeCircle(struct Shape *c, double r, double o, double oY) {
c->radius = r;
c->origin = o;
c->originY = oY;
}
void InitializeRectangle(struct Shape *r, double miX, double maX, double miY, double maY) {
r->minX = miX;
r->maxX = maX;
r->minY = miY;
r->maxY = maY;
}
void InitializeTriangle(struct Shape *t, double p1X, double p2X, double miY, double maY) {
t->pt1X = p1X;
t->pt2X = p2X;
t->minY = miY;
t->maxY = maY;
}
// Get Area
double GetCircleArea(struct Shape *c) {
c->area = 3.14159*c->radius*c->radius;
return c->area;
}
double GetRectangleArea(struct Shape *r) {
r->area = ((r->maxX-r->minX)*(r->maxY-r->minY));
return r->area;
}
double GetTriangleArea(struct Shape *t) {
t->area = (((t->pt2X-t->pt1X)*(t->maxY-t->minY))/2);
return t->area;
}
// Get Bounding Box
void GetCircleBoundingBox(struct Shape *c, double *bbox) {
bbox[0] = c->origin-c->radius; // lower left corner
bbox[1] = c->origin+c->radius; // lower right corner
bbox[2] = c->originY-c->radius; // upper left corner
bbox[3] = c->originY+c->radius; // upper right corner
}
void GetRectangleBoundingBox(struct Shape *r, double *bbox) {
bbox[0] = r->minX;
bbox[1] = r->maxX;
bbox[2] = r->minY;
bbox[3] = r->maxY;
}
void GetTriangleBoundingBox(struct Shape *t, double *bbox) {
bbox[0] = t->pt1X; // minX
bbox[1] = t->pt2X; // maxX
bbox[2] = 0; // minY
bbox[3] = t->maxY; // maxY
}
#include <prototypes.h>
#include <stdio.h>
int main()
{
struct Shape shapes[9];
int i;
InitializeCircle(shapes+0, 1, 0, 0);
InitializeCircle(shapes+1, 1.5, 6, 8);
InitializeCircle(shapes+2, 0.5, -3, 4);
InitializeRectangle(shapes+3, 0, 1, 0, 1);
InitializeRectangle(shapes+4, 1, 1.1, 10, 20);
InitializeRectangle(shapes+5, 1.5, 3.5, 10, 12);
InitializeTriangle(shapes+6, 0, 1, 0, 1);
InitializeTriangle(shapes+7, 0, 1, 0, 0.1);
InitializeTriangle(shapes+8, 0, 10, 0, 50);
for (i = 0 ; i < 9 ; i++)
{
double bbox[4];
printf("Shape %d\n", i);
printf("\tArea: %f\n", shapes[i].ft.GetArea(shapes+i));
shapes[i].ft.GetBoundingBox(shapes+i, bbox);
printf("\tBbox: %f-%f, %f-%f\n", bbox[0], bbox[1], bbox[2], bbox[3]);
}
}
#包括
#包括
int main()
{
结构形状[9];
int i;
初始化圆形(形状+0,1,0,0);
初始化圆形(形状+1,1.5,6,8);
初始化圆形(形状+2,0.5,-3,4);
初始化矩形(形状+3,0,1,0,1);
初始化矩形(形状+4,1,1.1,10,20);
初始化矩形(形状+5,1.5,3.5,10,12);
初始化角度(形状+6,0,1,0,1);
初始化角度(形状+7,0,1,0,0.1);
初始化角度(形状+8,0,10,0,50);
对于(i=0;i<9;i++)
{
双bbox[4];
printf(“形状%d\n”,i);
printf(“\tArea:%f\n”,shapes[i].ft.GetArea(shapes+i));
shapes[i].ft.GetBoundingBox(shapes+i,bbox);
printf(“\tbox:%f-%f,%f-%f\n”,bbox[0],bbox[1],bbox[2],bbox[3]);
}
}
如有任何见解,将不胜感激。再说一次,我不是在找人帮我做作业,我只是希望能克服这个障碍。您需要为每种类型定义函数表:
// This is global, and used for all circle types.
// Could be declared 'static' if table and init functions are in the same file.
FunctionTable const CircleFuncs = {
GetCircleArea,
GetCircleBoundingBox
};
由于表可以为同一类型的所有形状共享,因此我们只需要指针:
typedef struct Shape { // <- note the fixed type name also
ShapeUnion su;
ShapeType st;
FunctionTable const * ft;
} Shape;
您不能用InitializeXYZ中的相关函数指针设置函数表吗?@AlanAu谢谢您的输入!我相信我可以,但是如果这个任务的重点是在我的FunctionTable结构中实现函数指针“GetArea”和“GetBoundingBox”。不幸的是,没有办法解决这个问题。但您不能将代码体直接放入结构定义中。因此,您必须在其他地方实现这些功能。然后在初始化函数中,用指向实际实现的函数的指针填充FunctionTable结构成员。除非我完全误解了你的要求代码>和
typedef结构{…}形状代码>不是相同的类型。后者需要是typedef结构形状{…}形状代码>