Implement a basic stratergy pattern in c - c

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);

Related

Ways to illicit polymorphic properties in regular C?

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.

Bad access in Xcode

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 {

scanf doesn't take all in inputs

I supposed to perform a project which allocate N bytes of memory of struct person
and scanning f every person's name initial_money and some other variables
the problem for me when i run the code is that it is terminating at some point of taking input process and i don't why
also this problem faced me yesterday in code forces contest
#include <stdio.h>
#include <stdlib.h>
struct person
{
char name[15];
int initial_money;
int g;
int final_money;
int money;
};
int main()
{
int NP,i,j;
char target1[15];
scanf("%d",&NP);
struct person *p=malloc(NP*sizeof(struct person));
for(i=0;i<NP;i++)
{
scanf("%s",(p+i)->name);
}
for(i=0;i<NP;i++)
{
scanf("%s",target1);
for(j=0;j<NP;j++)
{
if((p+j)->name==target1)
{
scanf("%d%d",(p+j)->initial_money,(p+j)->g);
(p+j)->final_money=(p+j)->initial_money%(p+j)->g;
}
}
}
for(i=0;i<NP;i++)
{
printf("%s %d %d %d",(p+i)->name,(p+i)->initial_money,(p+i)->g,(p+i)->final_money);
}
return 0;
}
The scanf function need pointers for inputed values.
The line:
scanf("%d%d",(p+j)->initial_money,(p+j)->g);
Should be:
scanf("%d %d",&(p+j)->initial_money,&(p+j)->g);
When comparing strings you usually can't compare pointers directly:
if((p+j)->name==target1)
shoul be:
if(strcmp((p+j)->name, target1) == 0)

Class in C (not C++)

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

Code wont compile

I'm trying to use a queue in my program, but it won't compile and I don't know why. The relevant part of the code is as follows.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#ifndef CUSTOMER
#define CUSTOMER
typedef int bool;
int r;
typedef struct{
int arrival;
int leaving;
} Customer;
static const int MAX_LENGTH = 100;
typedef struct{
int head;
int length;
Customer customer[MAX_LENGTH];
} CustomerLine;
void initializeQueue(CustomerLine* queue)
{
(*queue).head = 0;
(*queue).length = 0;
}
bool hasNext(CustomerLine* queue)
{
return (*queue).length > 0;
}
bool isFull(CustomerLine* queue)
{
return (*queue).length == MAX_LENGTH;
}
bool enqueue(CustomerLine* queue, Customer* customer)
{
if(isFull(queue))
return 0;
int index = ((*queue).head + (*queue).length) % MAX_LENGTH;
(*queue).customer[index] = *customer;
(*queue).length++;
return 1;
}
Customer* dequeue(CustomerLine* queue)
{
if(!hasNext(queue))
return 0;
Customer* result = &(*queue).customer[(*queue).head];
(*queue).length--;
(*queue).head = ((*queue).head + 1) % MAX_LENGTH;
return result;
}
The error says "Variably Modified 'customer' at file scope" I am a beginner at programming and just doing this is starting to get beyond my abilities so any help would be very much appreciated.
The line
static const int MAX_LENGTH = 100
is the problem. Replace it with
#define MAX_LENGTH 100
See why here and more explanations here or here or again here.
Furthermore:
You need an #endif after the #ifndef.
You need a main function somewhere.
In C, const means read-only, not constant and usable just like a macro. You cannot use a variable to specify the dimension of an array as you do here:
static const int MAX_LENGTH = 100;
typedef struct{
int head;
int length;
Customer customer[MAX_LENGTH]; /* Wrong. MAX_LENGTH is not a compile time constant. */
} CustomerLine;

Resources