I've discovered this hack in a website in Spanish (http://trucosinformaticos.wordpress.com/2010/12/12/programacion-orientado-a-objetos-en-c/).
I want create a "class" in C (not C++), but when I compile, I obtain the next errors:
source.c(25): warning C4047: 'function' : 'Car' differs in levels of indirection from 'Car *'
source.c(25): warning C4024: 'changeYears' : different types for formal and actual parameter 1
This is my code:
#include <string.h>
typedef struct Car* Car;
// class Car
// {
struct Car
{
int years;
//char model[100];
};
void changeYears(Car this, int years)
{
this->years = years;
}
// }
int main(void)
{
Car my_cars[10];
//nombrar(mis_alumnos[0], "Pepito");
changeYears(&my_cars[0], 6); // My car has now 6 years
return 0;
}
I would agree with #Oli Charlesworth that hiding a pointer behind a typedef is a very easy way to confuse yourself and others.
However, to make your code compile and work, you can just remove the & operator in front of my_cars. You also need to allocate memory for those pointers. I would say the reason why you made this mistake in the first place was that you confused yourself with the pointer hiding.
#include <string.h>
typedef struct Car* Car;
struct Car
{
int years;
//char model[100];
};
void changeYears(Car this, int years)
{
this->years = years;
}
int main(void)
{
// An array of struct char*
Car my_cars[10];
int i;
for (i = 0; i < 10; i++)
my_cars[i] = malloc(sizeof(struct Car));
changeYears(my_cars[0], 6); // My car has now 6 years
return 0;
}
Here is a more reasonable way to implement this without hiding pointers.
#include <string.h>
typedef struct
{
int years;
//char model[100];
} Car;
void changeYears(Car* this, int years)
{
this->years = years;
}
int main(void)
{
Car my_cars[10];
changeYears(&my_cars[0], 6); // My car has now 6 years
return 0;
}
I think this is what you are looking for:
(A much cleaner implementation, of what you want)
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int years;
} Car;
void changeYears(Car *this, int years)
{
this->years = years;
}
int main(void)
{
Car *car = malloc(sizeof(Car));
changeYears(car, 2014);
printf("car.years = %d\n", car->years);
free(car);
return 0;
}
OUTPUT:
car.year = 2014
Related
I am trying to implement a basic strategy pattern for understanding. I am new to programming. what am i doing wrong in the following code.
Can some one give a basic c implementation of strategy pattern.Thanks in adavance
#include <stdio.h>
#include <stdlib.h>
typedef int (*CustomerPriceStrategy)(int);
int bronzePriceStrategy(int);
int silverPriceStrategy(int);
int goldPriceStrategy(int);
struct Customer
{
const char* name;
CustomerPriceStrategy priceStrategy;
};
void placeOrder(struct Customer* customer)
{
int a;
a=customer->priceStrategy(3);
printf("%d",a);
}
int main(void) {
struct Customer *customer;
customer->name="bronze";
customer->priceStrategy=&bronzePriceStrategy;
placeOrder(customer);
return EXIT_SUCCESS;
}
int bronzePriceStrategy(int a)
{
printf(" 40+ shipping");
return (a+40);
}
int silverPriceStrategy(int a)
{
printf(" 25+ shipping");
return (a+25);
}
int goldPriceStrategy(int a)
{
/* Free shipping for gold customers. */
printf(" no shipping fee");
return a;
}
struct Customer *customer;
Is an uninialized pointer so:
customer->name="bronze";
customer->priceStrategy=&bronzePriceStrategy;
Will invoke undefined behavior.
You can replace this by:
struct Customer customer;
customer.name="bronze";
customer.priceStrategy=&bronzePriceStrategy;
placeOrder(&customer);
Hi I am currently attempting to learn C and I was wondering if there is a way to attain polymorphism in structures which contain a list of other different type of structures?
An example case of this is as such:
#include <stdlib.h>
#include <stdio.h>
typedef void (*update_t)(void *);
typedef struct entity entity_t;
typedef struct compA compA_t;
typedef struct compB compB_t;
struct compA{
update_t update;
};
struct compB{
update_t update;
};
struct entity{
update_t update;
int curSize;
void **components;
};
void compA_update(void *c){
printf("updating: componentA\n");
}
compA_t *compA_create(){
compA_t *c = malloc(sizeof(compA_t));
c->update = compA_update;
return c;
}
void compB_update(void *c){
printf("updating: componentB\n");
}
compB_t *compB_create(){
compB_t *c = malloc(sizeof(compB_t));
c->update = compB_update;
return c;
}
void entity_update(void *en){
entity_t *e = (entity_t *)en;
for(int i = 0; i < e->curSize; i++){
//would like to somehow update all the components with one line just iterating through the array but does not seem possible
}
return;
}
entity_t *entity_create(){
entity_t *e = malloc(sizeof(entity_t));
e->curSize = 0;
e->update = entity_update;
calloc(32, sizeof(void *));
return e;
}
void add_component(entity_t *e, void *c){
printf("%d\n", e->curSize);
e->components[e->curSize] = c;
e->curSize++;
return;
}
int main(void){
entity_t *e = entity_create();
compA_t *a = compA_create();
compB_t *b = compB_create();
add_component(e, a);
add_component(e, b);
e->update(e);
return 0;
}
So far my approach to this problem has been solved with void pointer arrays of a tuple structure which contains a enum type which identifies the structure as well as the structure itself and then in a potential update function a fairly ugly switch statement has to be implemented with a case for each specific type.
Is there a better way to do this? As the switch approach will get fairly crazy pretty fast if there are a lot of different types within the array. which means one must explicitly add cases for each type and every case does exactly the same thing, which in this case is call a function pointer named "update".
You can try data polymorphism instead of function pointer. That is, different data produce different behavior, using the same code.
For example, a simple polymorphic behavior:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
typedef const char* ccstr;
typedef struct animal_attr_t
{
bool is_body_segmented;
float gill_completeness;
float lung_completeness;
} animal_attr_t;
typedef struct species
{
ccstr name, kingdom, domain;
animal_attr_t animal_attr[0];
} species;
void initialize_species_base(species *this, ccstr name, ccstr kingdom, ccstr domain)
{
this->name = name;
this->kingdom = kingdom;
this->domain = domain;
}
void initialize_animal_attr(animal_attr_t *this, bool is_body_segmented, float gill_completenss, float lung_completeness)
{
this->is_body_segmented = is_body_segmented;
this->gill_completeness = gill_completenss;
this->lung_completeness = lung_completeness;
}
void print_species(species*);
int main(int argc, char *argv[])
{
species *yeast = calloc(sizeof(species), 1);
assert(yeast);
initialize_species_base(yeast, "yeast", "fungus", "eukaryote");
print_species(yeast);
species *dog = calloc(sizeof(species) + sizeof(animal_attr_t), 1);
assert(dog);
initialize_species_base(dog, "dog", "animal", "eukaryote");
initialize_animal_attr(dog->animal_attr, true, 0.0f, 1.0f);
print_species(dog);
free(yeast);
free(dog);
}
void print_species(species *this)
{
printf("name = %s, kingdom = %s, domain = %s",
this->name, this->kingdom, this->domain);
if (strcmp(this->kingdom, "animal") == 0) {
animal_attr_t *ani_attr = this->animal_attr;
printf(", has %s, %f completeness of gill, %f completeness of lung",
ani_attr->is_body_segmented ? "segmented body" : "unsegmented body",
ani_attr->gill_completeness, ani_attr->lung_completeness);
}
printf(".\n");
}
yeast and dog is 2 completely different types, yet with species it is expressed in an unified way and print_species has polymorphic behavior.
I'm doing an assignment for my data structures class and I have very little experience with C structures and C in general.
This is the .h file that I was given to do the assignment:
#ifndef C101IntVec
#define C101IntVec
typedef struct IntVecNode* IntVec;
static const int intInitCap = 4;
int intTop(IntVec myVec);
int intData(IntVec myVec, int i);
int intSize(IntVec myVec);
int intCapacity(IntVec myVec);
IntVec intMakeEmptyVec(void);
void intVecPush(IntVec myVec, int newE);
void intVecPop(IntVec myVec);
#endif
This is the .c implementation that I've made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "intVec.h"
typedef struct IntVecNode {
int* data;
int sz; // Number of elements that contain data
int capacity; // How much is allocated to the array
} IntVecNode;
typedef struct IntVecNode* IntVec;
//static const int intInitCap = 4;
int intTop(IntVec myVec) {
return *myVec->data;
}
int intData(IntVec myVec, int i) {
return *(myVec->data + i);
}
int intSize(IntVec myVec) {
return myVec->sz;
}
int intCapacity(IntVec myVec) {
return myVec->capacity;
}
IntVec intMakeEmptyVec(void) {
IntVec newVec = malloc(sizeof(struct IntVecNode));
newVec->data = malloc(intInitCap * sizeof(int));
newVec->sz = 0;
newVec->capacity = intInitCap;
return newVec;
}
void intVecPush(IntVec myVec, int newE) {
if (myVec->sz >= myVec->capacity) {
int newCap = myVec->capacity * 2;
myVec->data = realloc(myVec->data, newCap * sizeof(int));
} else {
for (int i = 0; i < myVec->capacity; i++) {
*(myVec->data + i) = *(myVec->data + i + 1);
}
myVec->data = &newE;
}
myVec->sz++;
}
void intVecPop(IntVec myVec) {
for (int i = 0; i < myVec->capacity; i++) {
*(myVec->data - i) = *(myVec->data - i + 1);
}
myVec->sz--;
}
This is the test file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "intVec.c"
int main() {
struct IntVec v;
v.intVecPush(v,0);
return 0;
}
Every time I run the test file, I get the error:
test.c:7:16: error: variable has incomplete type 'struct IntVec'
struct IntVec v;
^
test.c:7:9: note: forward declaration of 'struct IntVec'
struct IntVec v;
^
1 error generated.
I've tried changing the #include "intVec.c" to "intVec.h" in the test file, however that produces the same error. What would I need to change in order to not get this error?
There is no structure definition struct IntVec.
So the compiler is unable to define the object v
struct IntVec v;
I think you mean
IntVec v;
And this call
v.intVecPush(v,0);
is invalid and does not make sense. I think there should be something like
IntVec v = intMakeEmptyVec();
intVecPush(v,0);
instead of
struct IntVec v;
v.intVecPush(v,0);
Also it is a bad idea to include the whole module in another module. You should place the structure definition in the header and include this header in the compilation unit with main.
That is move these definitions
typedef struct IntVecNode {
int* data;
int sz; // Number of elements that contain data
int capacity; // How much is allocated to the array
} IntVecNode;
typedef struct IntVecNode* IntVec;
in the header.
I wrote a code which produces the following error:
Thread 1: EXC_BAD_ACCESS (code=1, adress=0x7.....)
I want the program to link the countries, states, cities and shops within an structure. But when I try to run my program it gives me the error you see above.
I already tried deleting the strcpy and the for but the error still occurs. So the error must be within the structures. What is it I'm doing wrong?
#include <stdio.h>
#include <string.h>
#define SMAX 16
#define CMAX 256
#define SHMAX 300
int main() {
struct country {
char cname[50];
struct state {
char sname[50];
struct city {
char cityname[50];
struct shop {
char shopname[50];
int countshop;
} shop[SHMAX];
int countcity;
} city[CMAX];
int countstate;
} state[SMAX];
} country;
// country = Germany;
strcpy(country.state[0].sname, "bayern");
strcpy(country.state[1].sname, "berlin");
strcpy(country.state[0].city[0].cityname, "ingolstadt");
strcpy(country.state[0].city[0].shop[0].shopname, "westpark");
strcpy(country.state[0].city[0].shop[1].shopname, "edeka");
for (int i = 0; i < SHMAX; i++) {
printf("%s\n", country.state[0].city[0].shop[i].shopname);
}
return 0;
}
The size of the struct is 69043124 bytes which is too much to fit on the stack.
As thread safety is no concern, the struct could be made static:
int main(void) {
static struct country {
I am trying to get familiar with struct and pointers in C and I am running into a bunch of syntax errors like "missing ';' before type", "missing ')' before type" and "undeclared identifier: 'i'". Everything seems fine, I know i is declared and I don't seem to be missing any ; or ).
#include <stdlib.h>
#include <stdio.h>
#pragma warning(disable: 4996)
struct Room;
struct House;
struct Room
{
float width;
float length;
float height;
char *name;
};
struct House
{
char *address;
struct Room *rooms[10];
};
int main(int argc, char* argv[])
{
struct House h;
h.address = "10 Palace Road";
for(int i = 0; i < 10; i++) // 6 errors occur here
{
h.rooms[i] = NULL;
}
struct Room hall;
hall.width = 10;
hall.length = 12;
hall.height = 9;
hall.name = "Hall";
h.rooms[0] = &hall;
printHouse(h);
system("PAUSE");
return 0;
}
void printHouse(struct House house)
{
printf(house.address);
printf("\n\n\n");
for (int i=0; i<10; i++)
{
if (house.rooms[i] != NULL)
{
struct Room r = *house.rooms[i];
printf("Room # %d: %s", i+1, r.name);
}
}
}
printf(house.address);
should be
printf("%s",house.address);
Also you must declare your function printhouse, since you have defined it after main.
#include <stdlib.h>
#include <stdio.h>
#pragma warning(disable: 4996)
struct Room; //you don't need this
**EDIT**
struct House
{
char *address;
struct Room *rooms[10];
};
void printHouse(struct House house);
Declare House first then the function.
int i;
for (i = 0; i < 10; i++){
//...
}
In earlier versions of C, you cannot declare I inside a loop.
Some versions of C compilers do not allow 'i' to be declared in the loop. Try declaring 'i' separately at the beginning of 'main()'. That should work.