I am trying to convert this C code to C. The C class needs to be converted to struct.
Also, we need to use pointers.
Following is the C code:
#include <iostream>
class rectangle {
private:
double width,height;
public:
rectangle(double w, double h) {
width = w;
height = h;
}
double get_area() {
return width * height;
}
bool compare(rectangle* rf) {
return (this->get_area() > rf->get_area());
}
};
int main() {
rectangle* r1=new rectangle(1.5,2.6);
rectangle* r2=new rectangle(2.5,1.6);
bool ans=r1->compare(r2);
printf("%s\n", ans?"true":"false");
return 0;
}
My code in C does not raise any errors but does not print anything. Here is my code. Cannot seem to find the issue. Can you please help out?
#include <stdio.h>
#include <stdbool.h>
struct Rectangle
{
double width;
double height;
void (*new_rectangle)(double, double);
double (*get_area)();
bool (*compare)(struct Rectangle*);
};
void new_rectangle(struct Rectangle* self, double w, double h)
{
self->width = w;
self->height = h;
}
double get_area(struct Rectangle* self)
{
return self->width*self->height;
}
bool compare(struct Rectangle* this, struct Rectangle* other) {
return (this->get_area() > other->get_area());
}
int main()
{
struct Rectangle* r1;
new_rectangle(r1, 1.5, 2.6);
struct Rectangle* r2;
new_rectangle(r2, 2.5, 1.6);
bool ans = r1->compare(r2);
printf("%s\n", ans?"true":"false");
// printf("%c", );
// bool ans=r1->compare(r2);
// printer(r1)
// printf("%s\n", ans?"true":"false");
return 0;
}
CodePudding user response:
Your C code is not setting up the function pointers in the struct
, and is not using pointers correctly in main()
.
Try this instead:
#include <stdio.h>
#include <stdbool.h>
struct Rectangle
{
double width;
double height;
double (*get_area)(struct Rectangle*);
bool (*compare)(struct Rectangle*);
};
double get_area(struct Rectangle* this)
{
return this->width * this->height;
}
bool compare(struct Rectangle* this, struct Rectangle* other) {
return this->get_area(this) > other->get_area(other);
}
void new_rectangle(struct Rectangle* this, double w, double h)
{
this->width = w;
this->height = h;
this->get_area = &get_area;
this->compare = &compare;
}
int main()
{
struct Rectangle r1;
new_rectangle(&r1, 1.5, 2.6);
struct Rectangle r2;
new_rectangle(&r2, 2.5, 1.6);
bool ans = r1.compare(&r1, &r2);
printf("%s\n", ans ? "true" : "false");
return 0;
}
Alternatively:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct Rectangle
{
double width;
double height;
double (*get_area)(struct Rectangle*);
bool (*compare)(struct Rectangle*);
};
double get_area(struct Rectangle* this)
{
return this->width * this->height;
}
bool compare(struct Rectangle* this, struct Rectangle* other) {
return this->get_area(this) > other->get_area(other);
}
struct Rectangle* new_rectangle(double w, double h)
{
struct Rectangle* r = malloc(sizeof(struct Rectangle));
if (!r) return NULL;
r->width = w;
r->height = h;
r->get_area = &get_area;
r->compare = &compare;
return r;
}
void delete_rectangle(struct Rectangle* this)
{
free(this);
}
int main()
{
struct Rectangle* r1 = new_rectangle(1.5, 2.6);
struct Rectangle* r2 = new_rectangle(2.5, 1.6);
bool ans = r1->compare(r1, r2);
printf("%s\n", ans ? "true" : "false");
delete_rectangle(r1);
delete_rectangle(r2);
return 0;
}
That being said, it doesn't really make sense to have get_area()
and compare()
be members of Rectangle
in C:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct Rectangle
{
double width;
double height;
};
double get_area(struct Rectangle* this)
{
return this->width * this->height;
}
bool compare(struct Rectangle* this, struct Rectangle* other) {
return get_area(this) > get_area(other);
}
struct Rectangle* new_rectangle(double w, double h)
{
struct Rectangle* r = malloc(sizeof(struct Rectangle));
if (!r) return NULL;
r->width = w;
r->height = h;
return r;
}
void delete_rectangle(struct Rectangle* this)
{
free(this);
}
int main()
{
struct Rectangle* r1 = new_rectangle(1.5, 2.6);
struct Rectangle* r2 = new_rectangle(2.5, 1.6);
bool ans = compare(r1, r2);
printf("%s\n", ans ? "true" : "false");
delete_rectangle(r1);
delete_rectangle(r2);
return 0;
}
CodePudding user response:
Your translation is not semantically correct: the Rectangle
structure does not need to have function pointers for the methods. In the C code, the methods are not virtual
, so the compiler determines which functions to call from the type of the arguments: translating this to C puts this burden on the programmer, who must name the methods more explicitly and call them appropriately.
Here is a closer translation (ie: closer to what the c compiler actually generates):
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct rectangle {
double width, height;
} rectangle;
rectangle *rectangle_construct(rectangle *this, double w, double h) {
this->width = w;
this->height = h;
return this;
}
rectangle *rectangle_new(double w, double h) {
return rectangle_construct(malloc(sizeof(rectangle)), w, h);
}
void rectangle_destroy(rectangle *this) {
// no members need destroying
}
void rectangle_delete(rectangle *this) {
rectangle_destroy(this);
free(this);
}
double rectangle_get_area(rectangle *this) {
return this->width * this->height;
}
bool compare(rectangle *this, rectangle *that) {
return rectangle_get_area(this) > rectangle_get_area(that);
}
int main() {
rectangle *r1 = rectangle_new(1.5, 2.6);
rectangle *r2 = rectangle_new(2.5, 1.6);
bool ans = rectangle_compare(r1, r2);
printf("%s\n", ans ? "true" : "false");
// in your code, you should add these lines
//delete r1;
//delete r2;
// emulated as
rectangle_delete(r1);
rectangle_delete(r2);
return 0;
}