I am constrained to using C for a competition and I have a need to emulate classes. I am trying to construct a simple "point" class that can return and set the X and Y coordinates of a point. Yet, the below code returns errors such as "unknown type name point", "expected identifier or (" and "expected parameter declarator." What do these errors mean? How do I correct them? Is this the correct approach to writing a "pseudo-class"?
typedef struct object object, *setCoordinates;
struct object {
float x, y;
void (*setCoordinates)(object *self, float x, float y);
void (*getYCoordinate)(object *self);
void (*getXCoordinate)(object *self);
};
void object_setCoordinates(object *self, float x, float y){
self->x = x;
self->y = y;
}
float object_getXCoordinate(object *self){
return self->x;
}
float object_getYCoordinate(object *self){
return self->y;
}
object point;
point.setCoordinates = object_setCoordinates;
point.getYCoordinate = object_getYCoordinate;
point.getXCoordinate = object_getXCoordinate;
point.setCoordinates(&point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f", point.getXCoordinate, point.getYCoordinate);
Reference: 1. C - function inside struct 2. How do you implement a class in C?
You would do much better to implement it as follows:
#include <stdio.h>
struct point {
float x;
float y;
};
void point_setCoordinates(struct point *self, float x, float y){
self->x = x;
self->y = y;
}
float point_getXCoordinate(struct point *self){
return self->x;
}
float point_getYCoordinate(struct point *self){
return self->y;
}
int main(void) {
struct point my_point;
point_setCoordinates(&my_point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f\n",
point_getXCoordinate(&my_point),
point_getYCoordinate(&my_point));
return 0;
}
A few things to note:
point_*()
functions that you call on the point
'thing'.printf()
you used point.getXCoordinate
- that is to say you took it's address and asked printf()
to display it as though it were a float
Many libraries / APIs provide opaque datatypes. This means that you can get a 'handle' to a 'thing'... but you have no idea what's being stored within the 'thing'. The library then provides you with access functions, as shown below. This is how I'd advise you approach the situation.
Don't forget to free the memory!
I've implemented an example below.
point.h
#ifndef POINT_H
#define POINT_H
struct point;
struct point *point_alloc(void);
void point_free(struct point *self);
void point_setCoordinates(struct point *self, float x, float y);
float point_getXCoordinate(struct point *self);
float point_getYCoordinate(struct point *self);
#endif /* POINT_H */
point.c
#include <stdlib.h>
#include <string.h>
#include "point.h"
struct point {
float x;
float y;
};
struct point *point_alloc(void) {
struct point *point;
point = malloc(sizeof(*point));
if (point == NULL) {
return NULL;
}
memset(point, 0, sizeof(*point));
return point;
}
void point_setCoordinates(struct point *self, float x, float y) {
self->x = x;
self->y = y;
}
float point_getXCoordinate(struct point *self) {
return self->x;
}
float point_getYCoordinate(struct point *self) {
return self->y;
}
void point_free(struct point *self) {
free(self);
}
main.c
#include <stdio.h>
#include "point.h"
int main(void) {
struct point *point;
point = point_alloc();
point_setCoordinates(point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f\n",
point_getXCoordinate(point),
point_getYCoordinate(point));
point_free(point);
return 0;
}
Your code has some minor errors. That's why it doesn't compile.
Fixed here:
typedef struct object object;
struct object {
float x, y;
void (*setCoordinates)(object *self, float x, float y);
float (*getYCoordinate)(object *self);
float (*getXCoordinate)(object *self);
};
void object_setCoordinates(object *self, float x, float y){
self->x = x;
self->y = y;
}
float object_getXCoordinate(object *self){
return self->x;
}
float object_getYCoordinate(object *self){
return self->y;
}
int main()
{
object point;
point.setCoordinates = object_setCoordinates;
point.getYCoordinate = object_getYCoordinate;
point.getXCoordinate = object_getXCoordinate;
point.setCoordinates(&point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f",
point.getXCoordinate(&point), point.getYCoordinate(&point));
}
As for the approach, there's probably no need to store the pointers to your methods inside the struct when you can simply call them directly:
object x;
object_setCoordinates(x, 1, 2);
//...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With