Run Code
|
API
|
Code Wall
|
Misc
|
Feedback
|
Login
|
Theme
|
Privacy
|
Patreon
object-oriented C by Henry Kroll III www.thenerdshow.com
//gcc 4.9.3 //object-oriented C Copyright(C) 2016 Henry Kroll III www.thenerdshow.com //usr/local/bin/anch -std=c99 -keep -run "$0" "$@" ; exit $? #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <string.h> //list the types #define TYPELIST \ X(int, "%i") \ X(float, "%3.1lf") \ X(double, "%3.1lf") \ X(char, "'%c'") //unify the types #define X(type, fmt) type *type##_t; typedef union { TYPELIST } utype; #undef X //dope vector "object" template typedef struct obj { char *name; size_t pos, length; //methods utype *(*iter)(struct obj *); void (*increment)(struct obj *); void (*decrement)(struct obj *); void (*print)(struct obj *); #define X(type, fmt) type *type##_ptr; union{TYPELIST}; #undef X char mem; } obj, *object; //template expands methods for each type #define X(type, fmt) \ utype *iter_##type (object d) { \ return d->pos < d->length?(utype*)&d->type##_ptr[d->pos++]:NULL; \ } \ void increment_##type (object d) { \ for(int i=d->length;i--;) d->type##_ptr[i]++; \ } \ void decrement_##type (object d) { \ for(int i=d->length;i--;) d->type##_ptr[i]--; \ } \ void print_##type (object d) { \ printf(#type " %s={", d->name); \ for(int i=0;i<d->length;i++) \ printf(fmt ",", d->type##_ptr[i]); \ puts("}"); \ } TYPELIST; #undef X /* define some global object prototypes (classes) * containing pre-packaged methods for each type of object * NEW objects will be mem copied (inherited) from these classes */ #define X(type, fmt) \ obj type##_obj={"", 0, 0, \ iter_##type, increment_##type, decrement_##type, print_##type }; TYPELIST; #undef X //convenience macros for dot.objects (dope wrappers) //define a new local variable and wrap it into a dot.object class #define NEW_dot(type, id, len, ...) type id##_data[]={__VA_ARGS__}; \ obj id = type##_obj; id.name = #id, \ id.length = len, id.type##_ptr = id##_data; #define F_dot(a, b) b.a(&(b)) #define NEXT_dot(b) *F_dot(iter, b) //convenience macros for arrow->objects (dope objects) /* allocate enough NEW memory for the struct + contents * copy (inherit) new object from object's prototype (class) * initialize object's pointer to its internal memory * copy any supplied data into the new object */ #define NEW(alloc, type, id, len, ...) \ object id = alloc(sizeof *id + len * sizeof(type)); \ *id = type##_obj, id->name = #id, id->length = len, \ id->type##_ptr = (type*)&id->mem; /* point to internal memory */ \ type id##_tmp[]={__VA_ARGS__}; /* copy data into object */ \ memcpy(id->type##_ptr, &id##_tmp, len * sizeof(type)); #define F(a, b) b->a((b)) #define NEXT(b) *F(iter, b) //main int main (void) { //"dot" objects are declared in local scope NEW_dot(int, idot, 5, 1,2,3,4,5); NEW_dot(double,fdot, 3, 0.0, 4.5, 2.7); NEW(malloc, float, farr, 3, 2.1, 2.5, 2.7); NEW_dot(char, cdot, 4, "uijt"); //F_dot function wrapper hides ugly object.method(&object) calls idot.increment(&idot); F_dot(increment, idot); F_dot(decrement, cdot); F_dot(decrement, fdot); F_dot(print, idot); F_dot(print, fdot); F_dot(print, cdot); //F function hides ugly object->method(object) calls farr->increment(farr); F(increment, farr); //iter method can be invoked several ways //accessing .iter directly printf ("%i ", *idot.iter(&idot)); //using F_dot function macro printf ("%i ", *F_dot(iter, idot)); //using NEXT_dot iter macro printf ("%i ", NEXT_dot(idot)); //non-int types still require awkward recast to actually use printf ("%3.1lf ", *(double*)&NEXT_dot(fdot)); printf ("%3.1lf ", *(double*)&NEXT_dot(fdot)); printf ("%3.1f ", *(float*)&NEXT(farr)); printf ("%3.1f ", *(float*)&NEXT(farr)); printf ("%c ", NEXT_dot(cdot)); printf ("%c ", NEXT_dot(cdot)); printf ("%c ", NEXT_dot(cdot)); printf ("%c ", NEXT_dot(cdot)); free (farr); return 0; }
run
|
edit
|
history
|
help
0
array and its sum
diagonal sum
c4
Lab 11 v1.0
Add sum.c
150108_RecursivoPrimo
c program for hollow rhombus
Sumit
Largest and smallest
Largest and Second Largest number in an array