Skip to main content
Tweeted twitter.com/StackCodeReview/status/697322160717750272
Rollback to Revision 3
Source Link
Quill
  • 12.1k
  • 5
  • 41
  • 94
#ifndef VARRAY_H
#define VARRAY_H
#define VARRAY_DISPLAYDEBUG 0
#define VARRAY_STRSIZE(x) ((sizeof(char) * strlen(x)) + 1)
#include <stdlib.h>
#include <string.h>
#include <stdio.h> 

typedef struct {
    int* getInt;
    char* getChar;
    double* getDbl;
    char* str;
    size_tint size;
} varray;

typedef enum {
    v_char = 0,
    v_int = 1,
    v_double = 2,
    v_varray = 3,
    v_tdvarray = 4
} varrayType;

void* createArray(varrayType arrayType, size_tint arraySize);
varray varrayPush(const char* data);
varray allocateNumArray(varrayType type, const size_tint size);
varray allocateCharArray(const size_tint size);
varray* allocateVarray(const size_tint size);
varray** allocateTDVarray(const size_tint size);

inline void* createArray(varrayType arrayType, size_tint arraySize) {
    varray* target;
    varray** vtarget;
    varray*** tdvtarget;
    if (arrayType == v_char) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateCharArray(arraySize);
        return target;
    }
    else if (arrayType == v_int || arrayType == v_double) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateNumArray(arrayType, arraySize);
        return target;
    }
    else if (arrayType == v_varray) {
        vtarget = malloc(sizeof(varray*) * arraySize);
        *vtarget = allocateVarray(arraySize);
        return *vtarget;
    }
    else if (arrayType == v_tdvarray) {
        tdvtarget = malloc(sizeof(varray**) * arraySize);
        *tdvtarget = allocateTDVarray(arraySize);
        return *tdvtarget;
    }
    else {
        return NULL;
    }
}   

inline varray varrayPush(const char* data) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%zu%s%s\n""%s%d%s%s\n", "Allocating array with size: ", (int)VARRAY_STRSIZE(data) - 1, " with contents: ", data);
    }
    target.str = strdupmalloc(VARRAY_STRSIZE(data));
    strcpy(target.str, data);
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%s\n", "String created successfully. Contents reads: ", target.str);
        printf("%s%d\n", "Memory address: ", (int)target.str);
    }
    target.size = VARRAY_STRSIZE(data);
    return target;
}

inline varray allocateNumArray(varrayType type, const size_tint size) {
    int i;
    varray target;
    if (type == v_int) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%zu\n""%s%d\n", "Allocating array of type v_int with size ", size);
        }
        target.getInt = callocmalloc(size, sizeof(int) * size);
        for (i = 0; i < size; i++) {
            target.getInt[i] = 0;
        }
    }
    else if (type == v_double) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%zu\n""%s%d\n", "Allocating array of type v_double with size ", size);
        }
        target.getDbl = callocmalloc(size, sizeof(double) * size);
        for (i = 0; i < size; i++) {
            target.getDbl[i] = 0.0;
        }
    }
    target.size = size;
    return target;
}

inline varray allocateCharArray(const size_tint size) {
    varray target;
    int i;
    if (VARRAY_DISPLAYDEBUG) {
         printf("%s%zu\n""%s%d\n", "Allocating array of type v_char with size ", size);
    }
    target.getChar = callocmalloc(size, sizeof(char) * size);
    for (i = 0; i < size; i++) {
        target.getChar[i] = 0;
    }
    target.size = size;
    return target;
}

inline varray* allocateVarray(const size_tint size) {
    varray* target = malloc(sizeof(varray) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%zu\n""%s%d\n", "Allocated array of type v_varray with size ", size);
    }
    target[0].size = size;
    return target;
}

inline varray** allocateTDVarray(const size_tint size) {
    varray** target = malloc(sizeof(varray*) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%zu\n""%s%d\n", "Allocated array of type v_tdvarray with size ", size);
    }
    target[0] = malloc(sizeof(varray));
    target[0][0].size = size;
    return target;
}

#endif
#include "varray.h"

void varrayDemo() {
    varray sampleInt;
    /*
     * Functions as a normal array but also stores
     * the size of the array at sampleInt.size.
     * Accessing data elements used the syntax
     * VARRAY.getInt[POSITION]
     */
    varray* sampleString;
    /*
     * Since a C string is an array of char, creating
     * an array of varray objects can easily store multiple
     * strings. The size of the varray array can be accessed
     * via VARRAY[0].size Individual elements can be 
     * accessed at VARRAY[POSITION].str with position >= 1
     */
    varray** sampleContainer;
    /*
     * The container of varrays can store multiple data types
     * at each element's position. For example, the syntax
     * VARRAY[1][1].str will return the string, if stored.
     * while VARRAY[2][2].getDbl[POSITION] returns the double
     */
    sampleInt = *(varray*)createArray(v_int, 5);
    /*
     * The function createArray(TYPE, SIZE) initializes the array
     * NOTE: I am not sure if there is a more "aesthetically pleasing"
     * way to initialize the array, since createArray returns a void
     * pointer. When initialized, all values are set to 0
     */
    printf("The size of sampleInt is: %zu\n"%d\n", sampleInt.size);
    printf("The data at position 0 is: %d\n", sampleInt.getInt[0]);

    sampleString = createArray(v_varray, 2);
    /*
     * Each varray can contain one string. Initialize each element
     * with the createArray command.
     */
    printf("The size of sampleString is: %zu\n"%d\n", sampleString[0].size);
    /*
     * As noted above, the size is stored in a varray at position 0
     * in the container
     */
    sampleString[1] = varrayPush("This is a sample string");
    sampleString[2] = varrayPush("This is also a sample string!"); 
    /*
     * To store a string within a varray, the function varrayPush is used
     * with the desired string as the argument. The function initializes
     * another varray object within the container.
     */
    printf("The string at position 1 is: %s\n", sampleString[1].str);
    printf("The size of the string stored at position 1 is: %zu\n"%d\n", sampleString[1].size); 
    printf("The char at position 5 in sampleString[1] is: %c\n", sampleString[1].str[5]);

    sampleContainer = createArray(v_tdvarray, 2);
    sampleContainer[1] = createArray(v_varray, 1);
    sampleContainer[1][1] = *(varray*)createArray(v_double, 5);
    sampleContainer[1][1].getDbl[4] = 3.14;
    sampleContainer[2] = createArray(v_varray, 1);
    sampleContainer[2][1] = varrayPush("yet another sample string");
    /*
     * As noted with the original sampleInt example, the *(varray*)
     * syntax is used again.
     */
    printf("sampleContainer[1][1] has size: %zu%d with data %lf at position 4\n", sampleContainer[1][1].size, sampleContainer[1][1].getDbl[4]);
    printf("sampleContainer[2][1] has size %zu%d with string \"%s\"\n", sampleContainer[2][1].size, sampleContainer[2][1].str); 
}
#ifndef VARRAY_H
#define VARRAY_H
#define VARRAY_DISPLAYDEBUG 0
#define VARRAY_STRSIZE(x) ((sizeof(char) * strlen(x)) + 1)
#include <stdlib.h>
#include <string.h>
#include <stdio.h> 

typedef struct {
    int* getInt;
    char* getChar;
    double* getDbl;
    char* str;
    size_t size;
} varray;

typedef enum {
    v_char = 0,
    v_int = 1,
    v_double = 2,
    v_varray = 3,
    v_tdvarray = 4
} varrayType;

void* createArray(varrayType arrayType, size_t arraySize);
varray varrayPush(const char* data);
varray allocateNumArray(varrayType type, const size_t size);
varray allocateCharArray(const size_t size);
varray* allocateVarray(const size_t size);
varray** allocateTDVarray(const size_t size);

inline void* createArray(varrayType arrayType, size_t arraySize) {
    varray* target;
    varray** vtarget;
    varray*** tdvtarget;
    if (arrayType == v_char) {
        target = malloc(sizeof(varray));
        *target = allocateCharArray(arraySize);
        return target;
    }
    else if (arrayType == v_int || arrayType == v_double) {
        target = malloc(sizeof(varray));
        *target = allocateNumArray(arrayType, arraySize);
        return target;
    }
    else if (arrayType == v_varray) {
        vtarget = malloc(sizeof(varray*));
        *vtarget = allocateVarray(arraySize);
        return *vtarget;
    }
    else if (arrayType == v_tdvarray) {
        tdvtarget = malloc(sizeof(varray**));
        *tdvtarget = allocateTDVarray(arraySize);
        return *tdvtarget;
    }
    else {
        return NULL;
    }
}   

inline varray varrayPush(const char* data) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%zu%s%s\n", "Allocating array with size: ", VARRAY_STRSIZE(data) - 1, " with contents: ", data);
    }
    target.str = strdup(data);
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%s\n", "String created successfully. Contents reads: ", target.str);
        printf("%s%d\n", "Memory address: ", (int)target.str);
    }
    target.size = VARRAY_STRSIZE(data);
    return target;
}

inline varray allocateNumArray(varrayType type, const size_t size) {
    varray target;
    if (type == v_int) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%zu\n", "Allocating array of type v_int with size ", size);
        }
        target.getInt = calloc(size, sizeof(int));
    }
    else if (type == v_double) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%zu\n", "Allocating array of type v_double with size ", size);
        }
        target.getDbl = calloc(size, sizeof(double));
    }
    target.size = size;
    return target;
}

inline varray allocateCharArray(const size_t size) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
         printf("%s%zu\n", "Allocating array of type v_char with size ", size);
    }
    target.getChar = calloc(size, sizeof(char));
    target.size = size;
    return target;
}

inline varray* allocateVarray(const size_t size) {
    varray* target = malloc(sizeof(varray) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
    printf("%s%zu\n", "Allocated array of type v_varray with size ", size);
    }
    target[0].size = size;
    return target;
}

inline varray** allocateTDVarray(const size_t size) {
    varray** target = malloc(sizeof(varray*) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%zu\n", "Allocated array of type v_tdvarray with size ", size);
    }
    target[0] = malloc(sizeof(varray));
    target[0][0].size = size;
    return target;
}

#endif
#include "varray.h"

void varrayDemo() {
    varray sampleInt;
    /*
     * Functions as a normal array but also stores
     * the size of the array at sampleInt.size.
     * Accessing data elements used the syntax
     * VARRAY.getInt[POSITION]
     */
    varray* sampleString;
    /*
     * Since a C string is an array of char, creating
     * an array of varray objects can easily store multiple
     * strings. The size of the varray array can be accessed
     * via VARRAY[0].size Individual elements can be 
     * accessed at VARRAY[POSITION].str with position >= 1
     */
    varray** sampleContainer;
    /*
     * The container of varrays can store multiple data types
     * at each element's position. For example, the syntax
     * VARRAY[1][1].str will return the string, if stored.
     * while VARRAY[2][2].getDbl[POSITION] returns the double
     */
    sampleInt = *(varray*)createArray(v_int, 5);
    /*
     * The function createArray(TYPE, SIZE) initializes the array
     * NOTE: I am not sure if there is a more "aesthetically pleasing"
     * way to initialize the array, since createArray returns a void
     * pointer. When initialized, all values are set to 0
     */
    printf("The size of sampleInt is: %zu\n", sampleInt.size);
    printf("The data at position 0 is: %d\n", sampleInt.getInt[0]);

    sampleString = createArray(v_varray, 2);
    /*
     * Each varray can contain one string. Initialize each element
     * with the createArray command.
     */
    printf("The size of sampleString is: %zu\n", sampleString[0].size);
    /*
     * As noted above, the size is stored in a varray at position 0
     * in the container
     */
    sampleString[1] = varrayPush("This is a sample string");
    sampleString[2] = varrayPush("This is also a sample string!"); 
    /*
     * To store a string within a varray, the function varrayPush is used
     * with the desired string as the argument. The function initializes
     * another varray object within the container.
     */
    printf("The string at position 1 is: %s\n", sampleString[1].str);
    printf("The size of the string stored at position 1 is: %zu\n", sampleString[1].size); 
    printf("The char at position 5 in sampleString[1] is: %c\n", sampleString[1].str[5]);

    sampleContainer = createArray(v_tdvarray, 2);
    sampleContainer[1] = createArray(v_varray, 1);
    sampleContainer[1][1] = *(varray*)createArray(v_double, 5);
    sampleContainer[1][1].getDbl[4] = 3.14;
    sampleContainer[2] = createArray(v_varray, 1);
    sampleContainer[2][1] = varrayPush("yet another sample string");
    /*
     * As noted with the original sampleInt example, the *(varray*)
     * syntax is used again.
     */
    printf("sampleContainer[1][1] has size: %zu with data %lf at position 4\n", sampleContainer[1][1].size, sampleContainer[1][1].getDbl[4]);
    printf("sampleContainer[2][1] has size %zu with string \"%s\"\n", sampleContainer[2][1].size, sampleContainer[2][1].str); 
}
#ifndef VARRAY_H
#define VARRAY_H
#define VARRAY_DISPLAYDEBUG 0
#define VARRAY_STRSIZE(x) ((sizeof(char) * strlen(x)) + 1)
#include <stdlib.h>
#include <string.h>
#include <stdio.h> 

typedef struct {
    int* getInt;
    char* getChar;
    double* getDbl;
    char* str;
    int size;
} varray;

typedef enum {
    v_char = 0,
    v_int = 1,
    v_double = 2,
    v_varray = 3,
    v_tdvarray = 4
} varrayType;

void* createArray(varrayType arrayType, int arraySize);
varray varrayPush(const char* data);
varray allocateNumArray(varrayType type, const int size);
varray allocateCharArray(const int size);
varray* allocateVarray(const int size);
varray** allocateTDVarray(const int size);

inline void* createArray(varrayType arrayType, int arraySize) {
    varray* target;
    varray** vtarget;
    varray*** tdvtarget;
    if (arrayType == v_char) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateCharArray(arraySize);
        return target;
    }
    else if (arrayType == v_int || arrayType == v_double) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateNumArray(arrayType, arraySize);
        return target;
    }
    else if (arrayType == v_varray) {
        vtarget = malloc(sizeof(varray*) * arraySize);
        *vtarget = allocateVarray(arraySize);
        return *vtarget;
    }
    else if (arrayType == v_tdvarray) {
        tdvtarget = malloc(sizeof(varray**) * arraySize);
        *tdvtarget = allocateTDVarray(arraySize);
        return *tdvtarget;
    }
    else {
        return NULL;
    }
}   

inline varray varrayPush(const char* data) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d%s%s\n", "Allocating array with size: ", (int)VARRAY_STRSIZE(data) - 1, " with contents: ", data);
    }
    target.str = malloc(VARRAY_STRSIZE(data));
    strcpy(target.str, data);
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%s\n", "String created successfully. Contents reads: ", target.str);
        printf("%s%d\n", "Memory address: ", (int)target.str);
    }
    target.size = VARRAY_STRSIZE(data);
    return target;
}

inline varray allocateNumArray(varrayType type, const int size) {
    int i;
    varray target;
    if (type == v_int) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%d\n", "Allocating array of type v_int with size ", size);
        }
        target.getInt = malloc(sizeof(int) * size);
        for (i = 0; i < size; i++) {
            target.getInt[i] = 0;
        }
    }
    else if (type == v_double) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%d\n", "Allocating array of type v_double with size ", size);
        }
        target.getDbl = malloc(sizeof(double) * size);
        for (i = 0; i < size; i++) {
            target.getDbl[i] = 0.0;
        }
    }
    target.size = size;
    return target;
}

inline varray allocateCharArray(const int size) {
    varray target;
    int i;
    if (VARRAY_DISPLAYDEBUG) {
         printf("%s%d\n", "Allocating array of type v_char with size ", size);
    }
    target.getChar = malloc(sizeof(char) * size);
    for (i = 0; i < size; i++) {
        target.getChar[i] = 0;
    }
    target.size = size;
    return target;
}

inline varray* allocateVarray(const int size) {
    varray* target = malloc(sizeof(varray) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d\n", "Allocated array of type v_varray with size ", size);
    }
    target[0].size = size;
    return target;
}

inline varray** allocateTDVarray(const int size) {
    varray** target = malloc(sizeof(varray*) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d\n", "Allocated array of type v_tdvarray with size ", size);
    }
    target[0] = malloc(sizeof(varray));
    target[0][0].size = size;
    return target;
}

#endif
#include "varray.h"

void varrayDemo() {
    varray sampleInt;
    /*
     * Functions as a normal array but also stores
     * the size of the array at sampleInt.size.
     * Accessing data elements used the syntax
     * VARRAY.getInt[POSITION]
     */
    varray* sampleString;
    /*
     * Since a C string is an array of char, creating
     * an array of varray objects can easily store multiple
     * strings. The size of the varray array can be accessed
     * via VARRAY[0].size Individual elements can be 
     * accessed at VARRAY[POSITION].str with position >= 1
     */
    varray** sampleContainer;
    /*
     * The container of varrays can store multiple data types
     * at each element's position. For example, the syntax
     * VARRAY[1][1].str will return the string, if stored.
     * while VARRAY[2][2].getDbl[POSITION] returns the double
     */
    sampleInt = *(varray*)createArray(v_int, 5);
    /*
     * The function createArray(TYPE, SIZE) initializes the array
     * NOTE: I am not sure if there is a more "aesthetically pleasing"
     * way to initialize the array, since createArray returns a void
     * pointer. When initialized, all values are set to 0
     */
    printf("The size of sampleInt is: %d\n", sampleInt.size);
    printf("The data at position 0 is: %d\n", sampleInt.getInt[0]);

    sampleString = createArray(v_varray, 2);
    /*
     * Each varray can contain one string. Initialize each element
     * with the createArray command.
     */
    printf("The size of sampleString is: %d\n", sampleString[0].size);
    /*
     * As noted above, the size is stored in a varray at position 0
     * in the container
     */
    sampleString[1] = varrayPush("This is a sample string");
    sampleString[2] = varrayPush("This is also a sample string!"); 
    /*
     * To store a string within a varray, the function varrayPush is used
     * with the desired string as the argument. The function initializes
     * another varray object within the container.
     */
    printf("The string at position 1 is: %s\n", sampleString[1].str);
    printf("The size of the string stored at position 1 is: %d\n", sampleString[1].size); 
    printf("The char at position 5 in sampleString[1] is: %c\n", sampleString[1].str[5]);

    sampleContainer = createArray(v_tdvarray, 2);
    sampleContainer[1] = createArray(v_varray, 1);
    sampleContainer[1][1] = *(varray*)createArray(v_double, 5);
    sampleContainer[1][1].getDbl[4] = 3.14;
    sampleContainer[2] = createArray(v_varray, 1);
    sampleContainer[2][1] = varrayPush("yet another sample string");
    /*
     * As noted with the original sampleInt example, the *(varray*)
     * syntax is used again.
     */
    printf("sampleContainer[1][1] has size: %d with data %lf at position 4\n", sampleContainer[1][1].size, sampleContainer[1][1].getDbl[4]);
    printf("sampleContainer[2][1] has size %d with string \"%s\"\n", sampleContainer[2][1].size, sampleContainer[2][1].str); 
}
Changed int size to size_t type; fixed extra allocation of memory in createArray function
Source Link
#ifndef VARRAY_H
#define VARRAY_H
#define VARRAY_DISPLAYDEBUG 0
#define VARRAY_STRSIZE(x) ((sizeof(char) * strlen(x)) + 1)
#include <stdlib.h>
#include <string.h>
#include <stdio.h> 

typedef struct {
    int* getInt;
    char* getChar;
    double* getDbl;
    char* str;
    intsize_t size;
} varray;

typedef enum {
    v_char = 0,
    v_int = 1,
    v_double = 2,
    v_varray = 3,
    v_tdvarray = 4
} varrayType;

void* createArray(varrayType arrayType, intsize_t arraySize);
varray varrayPush(const char* data);
varray allocateNumArray(varrayType type, const intsize_t size);
varray allocateCharArray(const intsize_t size);
varray* allocateVarray(const intsize_t size);
varray** allocateTDVarray(const intsize_t size);

inline void* createArray(varrayType arrayType, intsize_t arraySize) {
    varray* target;
    varray** vtarget;
    varray*** tdvtarget;
    if (arrayType == v_char) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateCharArray(arraySize);
        return target;
    }
    else if (arrayType == v_int || arrayType == v_double) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateNumArray(arrayType, arraySize);
        return target;
    }
    else if (arrayType == v_varray) {
        vtarget = malloc(sizeof(varray*) * arraySize);
        *vtarget = allocateVarray(arraySize);
        return *vtarget;
    }
    else if (arrayType == v_tdvarray) {
        tdvtarget = malloc(sizeof(varray**) * arraySize);
        *tdvtarget = allocateTDVarray(arraySize);
        return *tdvtarget;
    }
    else {
        return NULL;
    }
}   

inline varray varrayPush(const char* data) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d%s%s\n""%s%zu%s%s\n", "Allocating array with size: ", (int)VARRAY_STRSIZE(data) - 1, " with contents: ", data);
    }
    target.str = malloc(VARRAY_STRSIZEstrdup(data));
    strcpy(target.str, data);
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%s\n", "String created successfully. Contents reads: ", target.str);
        printf("%s%d\n", "Memory address: ", (int)target.str);
    }
    target.size = VARRAY_STRSIZE(data);
    return target;
}

inline varray allocateNumArray(varrayType type, const intsize_t size) {
    int i;
    varray target;
    if (type == v_int) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%d\n""%s%zu\n", "Allocating array of type v_int with size ", size);
        }
        target.getInt = malloccalloc(size, sizeof(int) * size);
        for (i = 0; i < size; i++) {
            target.getInt[i] = 0;
        }
    }
    else if (type == v_double) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%d\n""%s%zu\n", "Allocating array of type v_double with size ", size);
        }
        target.getDbl = malloccalloc(size, sizeof(double) * size);
        for (i = 0; i < size; i++) {
            target.getDbl[i] = 0.0;
        }
    }
    target.size = size;
    return target;
}

inline varray allocateCharArray(const intsize_t size) {
    varray target;
    int i;
    if (VARRAY_DISPLAYDEBUG) {
         printf("%s%d\n""%s%zu\n", "Allocating array of type v_char with size ", size);
    }
    target.getChar = malloccalloc(size, sizeof(char) * size);
    for (i = 0; i < size; i++) {
        target.getChar[i] = 0;
    }
    target.size = size;
    return target;
}

inline varray* allocateVarray(const intsize_t size) {
    varray* target = malloc(sizeof(varray) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d\n""%s%zu\n", "Allocated array of type v_varray with size ", size);
    }
    target[0].size = size;
    return target;
}

inline varray** allocateTDVarray(const intsize_t size) {
    varray** target = malloc(sizeof(varray*) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d\n""%s%zu\n", "Allocated array of type v_tdvarray with size ", size);
    }
    target[0] = malloc(sizeof(varray));
    target[0][0].size = size;
    return target;
}

#endif
#include "varray.h"

void varrayDemo() {
    varray sampleInt;
    /*
     * Functions as a normal array but also stores
     * the size of the array at sampleInt.size.
     * Accessing data elements used the syntax
     * VARRAY.getInt[POSITION]
     */
    varray* sampleString;
    /*
     * Since a C string is an array of char, creating
     * an array of varray objects can easily store multiple
     * strings. The size of the varray array can be accessed
     * via VARRAY[0].size Individual elements can be 
     * accessed at VARRAY[POSITION].str with position >= 1
     */
    varray** sampleContainer;
    /*
     * The container of varrays can store multiple data types
     * at each element's position. For example, the syntax
     * VARRAY[1][1].str will return the string, if stored.
     * while VARRAY[2][2].getDbl[POSITION] returns the double
     */
    sampleInt = *(varray*)createArray(v_int, 5);
    /*
     * The function createArray(TYPE, SIZE) initializes the array
     * NOTE: I am not sure if there is a more "aesthetically pleasing"
     * way to initialize the array, since createArray returns a void
     * pointer. When initialized, all values are set to 0
     */
    printf("The size of sampleInt is: %d\n"%zu\n", sampleInt.size);
    printf("The data at position 0 is: %d\n", sampleInt.getInt[0]);

    sampleString = createArray(v_varray, 2);
    /*
     * Each varray can contain one string. Initialize each element
     * with the createArray command.
     */
    printf("The size of sampleString is: %d\n"%zu\n", sampleString[0].size);
    /*
     * As noted above, the size is stored in a varray at position 0
     * in the container
     */
    sampleString[1] = varrayPush("This is a sample string");
    sampleString[2] = varrayPush("This is also a sample string!"); 
    /*
     * To store a string within a varray, the function varrayPush is used
     * with the desired string as the argument. The function initializes
     * another varray object within the container.
     */
    printf("The string at position 1 is: %s\n", sampleString[1].str);
    printf("The size of the string stored at position 1 is: %d\n"%zu\n", sampleString[1].size); 
    printf("The char at position 5 in sampleString[1] is: %c\n", sampleString[1].str[5]);

    sampleContainer = createArray(v_tdvarray, 2);
    sampleContainer[1] = createArray(v_varray, 1);
    sampleContainer[1][1] = *(varray*)createArray(v_double, 5);
    sampleContainer[1][1].getDbl[4] = 3.14;
    sampleContainer[2] = createArray(v_varray, 1);
    sampleContainer[2][1] = varrayPush("yet another sample string");
    /*
     * As noted with the original sampleInt example, the *(varray*)
     * syntax is used again.
     */
    printf("sampleContainer[1][1] has size: %d%zu with data %lf at position 4\n", sampleContainer[1][1].size, sampleContainer[1][1].getDbl[4]);
    printf("sampleContainer[2][1] has size %d%zu with string \"%s\"\n", sampleContainer[2][1].size, sampleContainer[2][1].str); 
}
#ifndef VARRAY_H
#define VARRAY_H
#define VARRAY_DISPLAYDEBUG 0
#define VARRAY_STRSIZE(x) ((sizeof(char) * strlen(x)) + 1)
#include <stdlib.h>
#include <string.h>
#include <stdio.h> 

typedef struct {
    int* getInt;
    char* getChar;
    double* getDbl;
    char* str;
    int size;
} varray;

typedef enum {
    v_char = 0,
    v_int = 1,
    v_double = 2,
    v_varray = 3,
    v_tdvarray = 4
} varrayType;

void* createArray(varrayType arrayType, int arraySize);
varray varrayPush(const char* data);
varray allocateNumArray(varrayType type, const int size);
varray allocateCharArray(const int size);
varray* allocateVarray(const int size);
varray** allocateTDVarray(const int size);

inline void* createArray(varrayType arrayType, int arraySize) {
    varray* target;
    varray** vtarget;
    varray*** tdvtarget;
    if (arrayType == v_char) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateCharArray(arraySize);
        return target;
    }
    else if (arrayType == v_int || arrayType == v_double) {
        target = malloc(sizeof(varray) * arraySize);
        *target = allocateNumArray(arrayType, arraySize);
        return target;
    }
    else if (arrayType == v_varray) {
        vtarget = malloc(sizeof(varray*) * arraySize);
        *vtarget = allocateVarray(arraySize);
        return *vtarget;
    }
    else if (arrayType == v_tdvarray) {
        tdvtarget = malloc(sizeof(varray**) * arraySize);
        *tdvtarget = allocateTDVarray(arraySize);
        return *tdvtarget;
    }
    else {
        return NULL;
    }
}   

inline varray varrayPush(const char* data) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d%s%s\n", "Allocating array with size: ", (int)VARRAY_STRSIZE(data) - 1, " with contents: ", data);
    }
    target.str = malloc(VARRAY_STRSIZE(data));
    strcpy(target.str, data);
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%s\n", "String created successfully. Contents reads: ", target.str);
        printf("%s%d\n", "Memory address: ", (int)target.str);
    }
    target.size = VARRAY_STRSIZE(data);
    return target;
}

inline varray allocateNumArray(varrayType type, const int size) {
    int i;
    varray target;
    if (type == v_int) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%d\n", "Allocating array of type v_int with size ", size);
        }
        target.getInt = malloc(sizeof(int) * size);
        for (i = 0; i < size; i++) {
            target.getInt[i] = 0;
        }
    }
    else if (type == v_double) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%d\n", "Allocating array of type v_double with size ", size);
        }
        target.getDbl = malloc(sizeof(double) * size);
        for (i = 0; i < size; i++) {
            target.getDbl[i] = 0.0;
        }
    }
    target.size = size;
    return target;
}

inline varray allocateCharArray(const int size) {
    varray target;
    int i;
    if (VARRAY_DISPLAYDEBUG) {
         printf("%s%d\n", "Allocating array of type v_char with size ", size);
    }
    target.getChar = malloc(sizeof(char) * size);
    for (i = 0; i < size; i++) {
        target.getChar[i] = 0;
    }
    target.size = size;
    return target;
}

inline varray* allocateVarray(const int size) {
    varray* target = malloc(sizeof(varray) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d\n", "Allocated array of type v_varray with size ", size);
    }
    target[0].size = size;
    return target;
}

inline varray** allocateTDVarray(const int size) {
    varray** target = malloc(sizeof(varray*) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%d\n", "Allocated array of type v_tdvarray with size ", size);
    }
    target[0] = malloc(sizeof(varray));
    target[0][0].size = size;
    return target;
}

#endif
#include "varray.h"

void varrayDemo() {
    varray sampleInt;
    /*
     * Functions as a normal array but also stores
     * the size of the array at sampleInt.size.
     * Accessing data elements used the syntax
     * VARRAY.getInt[POSITION]
     */
    varray* sampleString;
    /*
     * Since a C string is an array of char, creating
     * an array of varray objects can easily store multiple
     * strings. The size of the varray array can be accessed
     * via VARRAY[0].size Individual elements can be 
     * accessed at VARRAY[POSITION].str with position >= 1
     */
    varray** sampleContainer;
    /*
     * The container of varrays can store multiple data types
     * at each element's position. For example, the syntax
     * VARRAY[1][1].str will return the string, if stored.
     * while VARRAY[2][2].getDbl[POSITION] returns the double
     */
    sampleInt = *(varray*)createArray(v_int, 5);
    /*
     * The function createArray(TYPE, SIZE) initializes the array
     * NOTE: I am not sure if there is a more "aesthetically pleasing"
     * way to initialize the array, since createArray returns a void
     * pointer. When initialized, all values are set to 0
     */
    printf("The size of sampleInt is: %d\n", sampleInt.size);
    printf("The data at position 0 is: %d\n", sampleInt.getInt[0]);

    sampleString = createArray(v_varray, 2);
    /*
     * Each varray can contain one string. Initialize each element
     * with the createArray command.
     */
    printf("The size of sampleString is: %d\n", sampleString[0].size);
    /*
     * As noted above, the size is stored in a varray at position 0
     * in the container
     */
    sampleString[1] = varrayPush("This is a sample string");
    sampleString[2] = varrayPush("This is also a sample string!"); 
    /*
     * To store a string within a varray, the function varrayPush is used
     * with the desired string as the argument. The function initializes
     * another varray object within the container.
     */
    printf("The string at position 1 is: %s\n", sampleString[1].str);
    printf("The size of the string stored at position 1 is: %d\n", sampleString[1].size); 
    printf("The char at position 5 in sampleString[1] is: %c\n", sampleString[1].str[5]);

    sampleContainer = createArray(v_tdvarray, 2);
    sampleContainer[1] = createArray(v_varray, 1);
    sampleContainer[1][1] = *(varray*)createArray(v_double, 5);
    sampleContainer[1][1].getDbl[4] = 3.14;
    sampleContainer[2] = createArray(v_varray, 1);
    sampleContainer[2][1] = varrayPush("yet another sample string");
    /*
     * As noted with the original sampleInt example, the *(varray*)
     * syntax is used again.
     */
    printf("sampleContainer[1][1] has size: %d with data %lf at position 4\n", sampleContainer[1][1].size, sampleContainer[1][1].getDbl[4]);
    printf("sampleContainer[2][1] has size %d with string \"%s\"\n", sampleContainer[2][1].size, sampleContainer[2][1].str); 
}
#ifndef VARRAY_H
#define VARRAY_H
#define VARRAY_DISPLAYDEBUG 0
#define VARRAY_STRSIZE(x) ((sizeof(char) * strlen(x)) + 1)
#include <stdlib.h>
#include <string.h>
#include <stdio.h> 

typedef struct {
    int* getInt;
    char* getChar;
    double* getDbl;
    char* str;
    size_t size;
} varray;

typedef enum {
    v_char = 0,
    v_int = 1,
    v_double = 2,
    v_varray = 3,
    v_tdvarray = 4
} varrayType;

void* createArray(varrayType arrayType, size_t arraySize);
varray varrayPush(const char* data);
varray allocateNumArray(varrayType type, const size_t size);
varray allocateCharArray(const size_t size);
varray* allocateVarray(const size_t size);
varray** allocateTDVarray(const size_t size);

inline void* createArray(varrayType arrayType, size_t arraySize) {
    varray* target;
    varray** vtarget;
    varray*** tdvtarget;
    if (arrayType == v_char) {
        target = malloc(sizeof(varray));
        *target = allocateCharArray(arraySize);
        return target;
    }
    else if (arrayType == v_int || arrayType == v_double) {
        target = malloc(sizeof(varray));
        *target = allocateNumArray(arrayType, arraySize);
        return target;
    }
    else if (arrayType == v_varray) {
        vtarget = malloc(sizeof(varray*));
        *vtarget = allocateVarray(arraySize);
        return *vtarget;
    }
    else if (arrayType == v_tdvarray) {
        tdvtarget = malloc(sizeof(varray**));
        *tdvtarget = allocateTDVarray(arraySize);
        return *tdvtarget;
    }
    else {
        return NULL;
    }
}   

inline varray varrayPush(const char* data) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%zu%s%s\n", "Allocating array with size: ", VARRAY_STRSIZE(data) - 1, " with contents: ", data);
    }
    target.str = strdup(data);
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%s\n", "String created successfully. Contents reads: ", target.str);
        printf("%s%d\n", "Memory address: ", (int)target.str);
    }
    target.size = VARRAY_STRSIZE(data);
    return target;
}

inline varray allocateNumArray(varrayType type, const size_t size) {
    varray target;
    if (type == v_int) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%zu\n", "Allocating array of type v_int with size ", size);
        }
        target.getInt = calloc(size, sizeof(int));
    }
    else if (type == v_double) {
        if (VARRAY_DISPLAYDEBUG) {
            printf("%s%zu\n", "Allocating array of type v_double with size ", size);
        }
        target.getDbl = calloc(size, sizeof(double));
    }
    target.size = size;
    return target;
}

inline varray allocateCharArray(const size_t size) {
    varray target;
    if (VARRAY_DISPLAYDEBUG) {
         printf("%s%zu\n", "Allocating array of type v_char with size ", size);
    }
    target.getChar = calloc(size, sizeof(char));
    target.size = size;
    return target;
}

inline varray* allocateVarray(const size_t size) {
    varray* target = malloc(sizeof(varray) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
    printf("%s%zu\n", "Allocated array of type v_varray with size ", size);
    }
    target[0].size = size;
    return target;
}

inline varray** allocateTDVarray(const size_t size) {
    varray** target = malloc(sizeof(varray*) * (size + 1));
    if (VARRAY_DISPLAYDEBUG) {
        printf("%s%zu\n", "Allocated array of type v_tdvarray with size ", size);
    }
    target[0] = malloc(sizeof(varray));
    target[0][0].size = size;
    return target;
}

#endif
#include "varray.h"

void varrayDemo() {
    varray sampleInt;
    /*
     * Functions as a normal array but also stores
     * the size of the array at sampleInt.size.
     * Accessing data elements used the syntax
     * VARRAY.getInt[POSITION]
     */
    varray* sampleString;
    /*
     * Since a C string is an array of char, creating
     * an array of varray objects can easily store multiple
     * strings. The size of the varray array can be accessed
     * via VARRAY[0].size Individual elements can be 
     * accessed at VARRAY[POSITION].str with position >= 1
     */
    varray** sampleContainer;
    /*
     * The container of varrays can store multiple data types
     * at each element's position. For example, the syntax
     * VARRAY[1][1].str will return the string, if stored.
     * while VARRAY[2][2].getDbl[POSITION] returns the double
     */
    sampleInt = *(varray*)createArray(v_int, 5);
    /*
     * The function createArray(TYPE, SIZE) initializes the array
     * NOTE: I am not sure if there is a more "aesthetically pleasing"
     * way to initialize the array, since createArray returns a void
     * pointer. When initialized, all values are set to 0
     */
    printf("The size of sampleInt is: %zu\n", sampleInt.size);
    printf("The data at position 0 is: %d\n", sampleInt.getInt[0]);

    sampleString = createArray(v_varray, 2);
    /*
     * Each varray can contain one string. Initialize each element
     * with the createArray command.
     */
    printf("The size of sampleString is: %zu\n", sampleString[0].size);
    /*
     * As noted above, the size is stored in a varray at position 0
     * in the container
     */
    sampleString[1] = varrayPush("This is a sample string");
    sampleString[2] = varrayPush("This is also a sample string!"); 
    /*
     * To store a string within a varray, the function varrayPush is used
     * with the desired string as the argument. The function initializes
     * another varray object within the container.
     */
    printf("The string at position 1 is: %s\n", sampleString[1].str);
    printf("The size of the string stored at position 1 is: %zu\n", sampleString[1].size); 
    printf("The char at position 5 in sampleString[1] is: %c\n", sampleString[1].str[5]);

    sampleContainer = createArray(v_tdvarray, 2);
    sampleContainer[1] = createArray(v_varray, 1);
    sampleContainer[1][1] = *(varray*)createArray(v_double, 5);
    sampleContainer[1][1].getDbl[4] = 3.14;
    sampleContainer[2] = createArray(v_varray, 1);
    sampleContainer[2][1] = varrayPush("yet another sample string");
    /*
     * As noted with the original sampleInt example, the *(varray*)
     * syntax is used again.
     */
    printf("sampleContainer[1][1] has size: %zu with data %lf at position 4\n", sampleContainer[1][1].size, sampleContainer[1][1].getDbl[4]);
    printf("sampleContainer[2][1] has size %zu with string \"%s\"\n", sampleContainer[2][1].size, sampleContainer[2][1].str); 
}
added 18 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

I recently have been working on moving from projects written in Java and C++ to C and realized that the lack of std::vectorstd::vector in C makes it a bit more difficult to create multi-dimensional arrays. Also, without the std::stringstd::string in C, it's harder to store arrays of strings and keep track of their sizes. To automate the process, I created a typedef'd structtypedef'd struct: varrayvarray. Varrayvarray attempts to emulate some basic functions of std::vectorstd::vector, e.g. storing sizes of the elements in an easily accessible location and allowing for allocation of multi-dimensional objects with "relative easy" Below, I've attached the header "varray.h" and a bit of sample code with comments to demonstrate its use. Please note that at this point, I haven't tried to dynamically expand the arrays, though I'll look into it as I practice more with the languageease".

I've attached the header "varray.h" and a bit of sample code with comments to demonstrate its use. Please note that at this point, I haven't tried to dynamically expand the arrays, though I'll look into it as I practice more with the language.

###VARRAY.Hvarray.h

###EXAMPLE IMPLEMENTATIONExample implementation

I recently have been working on moving from projects written in Java and C++ to C and realized that the lack of std::vector in C makes it a bit more difficult to create multi-dimensional arrays. Also, without the std::string in C, it's harder to store arrays of strings and keep track of their sizes. To automate the process, I created a typedef'd struct: varray. Varray attempts to emulate some basic functions of std::vector, e.g. storing sizes of the elements in an easily accessible location and allowing for allocation of multi-dimensional objects with "relative easy" Below, I've attached the header "varray.h" and a bit of sample code with comments to demonstrate its use. Please note that at this point, I haven't tried to dynamically expand the arrays, though I'll look into it as I practice more with the language.

###VARRAY.H

###EXAMPLE IMPLEMENTATION

I recently have been working on moving from projects written in Java and C++ to C and realized that the lack of std::vector in C makes it a bit more difficult to create multi-dimensional arrays. Also, without the std::string in C, it's harder to store arrays of strings and keep track of their sizes. To automate the process, I created a typedef'd struct: varray. varray attempts to emulate some basic functions of std::vector, e.g. storing sizes of the elements in an easily accessible location and allowing for allocation of multi-dimensional objects with "relative ease".

I've attached the header "varray.h" and a bit of sample code with comments to demonstrate its use. Please note that at this point, I haven't tried to dynamically expand the arrays, though I'll look into it as I practice more with the language.

varray.h

Example implementation

added 6 characters in body
Source Link
Phrancis
  • 20.5k
  • 6
  • 70
  • 155
Loading
Source Link
Loading