Skip to main content
Improve the naming conventions
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327

A popular naming convention is to prefix all the operations with the type name. That means they are predictable, and they fall together alphabetically when listing all symbols


#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double **data;
    size_t rows;
    size_t cols;
};

struct Array *NewArray*array_calloc(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->rows = rows;
    array->cols = cols;

    array->data = malloc(rows * sizeof *array->data);
    if (!array->data) {
        free(array);
        return NULL;
    }

    for (size_t i = 0; i < rows; ++i) {
        array->data[i] = malloc(cols * sizeof *array->data[i]);
        if (!array->data[i]) {
            while (i-->0) {
                free(array->data[i]);
            }
            free(array->data);
            free(array);
            return NULL;
        }
        for (size_t j = 0;  j < cols;  ++j) {
            array->data[i][j] = 0.0;
        }
    }

    return array;
}

void FreeArrayarray_free(struct Array *array)
{
    if (array) {
        assert (array->data);
        for (size_t i = 0; i < array->rows; ++i) {
            free(array->data[i]);
        }
        free(array->data);
        free(array);
    }
}

void PrintArrayarray_print(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2lf2f ", array->data[i][j]);
        }
        printf("\n");
    }
    return;
}

#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *M*a = NewArrayarray_calloc(2, 4);
    if (!Ma) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    PrintArrayarray_print(Ma);
    FreeArrayarray_free(Ma);
}
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double *data;
    size_t rows;
    size_t cols;
};

/* private helper */
static double *array_element(const struct Array *a, size_t row, size_t col)
{
   return a->data + row * a->cols + col;
}

/* public interface */
double array_value(const struct Array *a, size_t row, size_t col)
{
    return *array_element(a, row, col);
}

void array_set_value(const struct Array *a, size_t row, size_t col, double v)
{
    *array_element(a, row, col) = v;
}

struct Array *NewArray*array_new(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->data = malloc(sizeof *array->data * rows * cols);
    if (!array->data) {
        free(array);
        return NULL;
    }

    array->rows = rows;
    array->cols = cols;
    for (size_t j = 0;  j < rows * cols;  ++j) {
        array->data[j] = 0.0;
    }

    return array;
}

void FreeArrayarray_free(struct Array *array)
{
    if (array) {
        free(array->data);
        free(array);
    }
}

void PrintArrayarray_print(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2lf2f ", array_value(array, i, j));
        }
        printf("\n");
    }
} 


#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *M*a = NewArrayarray_calloc(2, 4);
    if (!Ma) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    PrintArrayarray_print(Ma);
    FreeArrayarray_free(Ma);
}
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double **data;
    size_t rows;
    size_t cols;
};

struct Array *NewArray(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->rows = rows;
    array->cols = cols;

    array->data = malloc(rows * sizeof *array->data);
    if (!array->data) {
        free(array);
        return NULL;
    }

    for (size_t i = 0; i < rows; ++i) {
        array->data[i] = malloc(cols * sizeof *array->data[i]);
        if (!array->data[i]) {
            while (i-->0) {
                free(array->data[i]);
            }
            free(array->data);
            free(array);
            return NULL;
        }
        for (size_t j = 0;  j < cols;  ++j) {
            array->data[i][j] = 0.0;
        }
    }

    return array;
}

void FreeArray(struct Array *array)
{
    if (array) {
        assert (array->data);
        for (size_t i = 0; i < array->rows; ++i) {
            free(array->data[i]);
        }
        free(array->data);
        free(array);
    }
}

void PrintArray(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2lf ", array->data[i][j]);
        }
        printf("\n");
    }
    return;
}

#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *M = NewArray(2, 4);
    if (!M) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    PrintArray(M);
    FreeArray(M);
}
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double *data;
    size_t rows;
    size_t cols;
};

/* private helper */
static double *array_element(const struct Array *a, size_t row, size_t col)
{
   return a->data + row * a->cols + col;
}

/* public interface */
double array_value(const struct Array *a, size_t row, size_t col)
{
    return *array_element(a, row, col);
}

void array_set_value(const struct Array *a, size_t row, size_t col, double v)
{
    *array_element(a, row, col) = v;
}

struct Array *NewArray(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->data = malloc(sizeof *array->data * rows * cols);
    if (!array->data) {
        free(array);
        return NULL;
    }

    array->rows = rows;
    array->cols = cols;
    for (size_t j = 0;  j < rows * cols;  ++j) {
        array->data[j] = 0.0;
    }

    return array;
}

void FreeArray(struct Array *array)
{
    if (array) {
        free(array->data);
        free(array);
    }
}

void PrintArray(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2lf ", array_value(array, i, j));
        }
        printf("\n");
    }
}

#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *M = NewArray(2, 4);
    if (!M) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    PrintArray(M);
    FreeArray(M);
}

A popular naming convention is to prefix all the operations with the type name. That means they are predictable, and they fall together alphabetically when listing all symbols


#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double **data;
    size_t rows;
    size_t cols;
};

struct Array *array_calloc(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->rows = rows;
    array->cols = cols;

    array->data = malloc(rows * sizeof *array->data);
    if (!array->data) {
        free(array);
        return NULL;
    }

    for (size_t i = 0; i < rows; ++i) {
        array->data[i] = malloc(cols * sizeof *array->data[i]);
        if (!array->data[i]) {
            while (i-->0) {
                free(array->data[i]);
            }
            free(array->data);
            free(array);
            return NULL;
        }
        for (size_t j = 0;  j < cols;  ++j) {
            array->data[i][j] = 0.0;
        }
    }

    return array;
}

void array_free(struct Array *array)
{
    if (array) {
        assert (array->data);
        for (size_t i = 0; i < array->rows; ++i) {
            free(array->data[i]);
        }
        free(array->data);
        free(array);
    }
}

void array_print(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2f ", array->data[i][j]);
        }
        printf("\n");
    }
    return;
}

#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *a = array_calloc(2, 4);
    if (!a) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    array_print(a);
    array_free(a);
}
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double *data;
    size_t rows;
    size_t cols;
};

/* private helper */
static double *array_element(const struct Array *a, size_t row, size_t col)
{
   return a->data + row * a->cols + col;
}

/* public interface */
double array_value(const struct Array *a, size_t row, size_t col)
{
    return *array_element(a, row, col);
}

void array_set_value(const struct Array *a, size_t row, size_t col, double v)
{
    *array_element(a, row, col) = v;
}

struct Array *array_new(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->data = malloc(sizeof *array->data * rows * cols);
    if (!array->data) {
        free(array);
        return NULL;
    }

    array->rows = rows;
    array->cols = cols;
    for (size_t j = 0;  j < rows * cols;  ++j) {
        array->data[j] = 0.0;
    }

    return array;
}

void array_free(struct Array *array)
{
    if (array) {
        free(array->data);
        free(array);
    }
}

void array_print(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2f ", array_value(array, i, j));
        }
        printf("\n");
    }
} 


#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *a = array_calloc(2, 4);
    if (!a) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    array_print(a);
    array_free(a);
}
Show how to use pointers into data array
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327

If you're really attached to using indexing rather than a function to access array elements, then (assuming that switching to C++ isn't an option!) we can add an array of row pointers into data. To maintain locality of reference, it's best if we can allocate the storage and pointers together, like this:

struct Array {
    double *data;
    double **rows;
    size_t height;
    size_t width;
};
    array->data = malloc(sizeof *array->data * height * width
                         + sizeof *array->rows * height);
    if (!array->data) {
        free(array);
        return NULL;
    }
    array->rows = (double **)((char*)array->data + sizeof *array->data * height * width);
    array->height = height;
    array->width = width;

    for (size_t i = 0;  i < height;  ++i) {
        array->rows[i] = array->data + i * width;
    }

No changes required to any other functions.

Then we can access elements using the accessor functions or using indexing as array->rows[i][j].


If you're really attached to using indexing rather than a function to access array elements, then (assuming that switching to C++ isn't an option!) we can add an array of row pointers into data. To maintain locality of reference, it's best if we can allocate the storage and pointers together, like this:

struct Array {
    double *data;
    double **rows;
    size_t height;
    size_t width;
};
    array->data = malloc(sizeof *array->data * height * width
                         + sizeof *array->rows * height);
    if (!array->data) {
        free(array);
        return NULL;
    }
    array->rows = (double **)((char*)array->data + sizeof *array->data * height * width);
    array->height = height;
    array->width = width;

    for (size_t i = 0;  i < height;  ++i) {
        array->rows[i] = array->data + i * width;
    }

No changes required to any other functions.

Then we can access elements using the accessor functions or using indexing as array->rows[i][j].

added 2 characters in body
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double *data;
    size_t rows;
    size_t cols;
};

/* private helper */
static double *array_element(const struct Array *a, size_t row, size_t col)
{
   return a->data + row * a->cols + col;
}

/* public interface */
double array_value(const struct Array *a, size_t row, size_t col)
{
    return *array_element(a, row, col);
}

void array_set_value(const struct Array *a, size_t row, size_t col, double v)
{
    *array_element(a, row, col) = v;
}

struct Array *NewArray(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->rows = rows;
    array->cols = cols;

    array->data = malloc(sizeof *array->data * rows * cols);
    if (!array->data) {
        free(array);
        return NULL;
    }

    array->rows = rows;
    array->cols = cols;
    for (size_t j = 0;  j < rows * cols;  ++j) {
        array->data[j] = 0.0;
    }

    return array;
}

void FreeArray(struct Array *array)
{
    if (array) {
        free(array->data);
        free(array);
    }
}

void PrintArray(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2lf ", array_value(array, i, j));
        }
        printf("\n");
    }
}

#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *M = NewArray(2, 4);
    if (!M) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    PrintArray(M);
    FreeArray(M);
}
```
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double *data;
    size_t rows;
    size_t cols;
};

/* private helper */
static double *array_element(const struct Array *a, size_t row, size_t col)
{
   return a->data + row * a->cols + col;
}

/* public interface */
double array_value(const struct Array *a, size_t row, size_t col)
{
    return *array_element(a, row, col);
}

void array_set_value(const struct Array *a, size_t row, size_t col, double v)
{
    *array_element(a, row, col) = v;
}

struct Array *NewArray(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->rows = rows;
    array->cols = cols;

    array->data = malloc(sizeof *array->data * rows * cols);
    if (!array->data) {
        free(array);
        return NULL;
    }

    for (size_t j = 0;  j < rows * cols;  ++j) {
        array->data[j] = 0.0;
    }

    return array;
}

void FreeArray(struct Array *array)
{
    if (array) {
        free(array->data);
        free(array);
    }
}

void PrintArray(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2lf ", array_value(array, i, j));
        }
        printf("\n");
    }
}

#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *M = NewArray(2, 4);
    if (!M) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    PrintArray(M);
    FreeArray(M);
}
```
#include <stdio.h>
#include <stdlib.h>

struct Array {
    double *data;
    size_t rows;
    size_t cols;
};

/* private helper */
static double *array_element(const struct Array *a, size_t row, size_t col)
{
   return a->data + row * a->cols + col;
}

/* public interface */
double array_value(const struct Array *a, size_t row, size_t col)
{
    return *array_element(a, row, col);
}

void array_set_value(const struct Array *a, size_t row, size_t col, double v)
{
    *array_element(a, row, col) = v;
}

struct Array *NewArray(const size_t rows, const size_t cols)
{
    struct Array *array = malloc(sizeof *array);
    if (!array) {
        return array;
    }

    array->data = malloc(sizeof *array->data * rows * cols);
    if (!array->data) {
        free(array);
        return NULL;
    }

    array->rows = rows;
    array->cols = cols;
    for (size_t j = 0;  j < rows * cols;  ++j) {
        array->data[j] = 0.0;
    }

    return array;
}

void FreeArray(struct Array *array)
{
    if (array) {
        free(array->data);
        free(array);
    }
}

void PrintArray(const struct Array *array)
{
    for (size_t i = 0;  i < array->rows;  ++i) {
        for (size_t j = 0;  j < array->cols;  ++j) {
            printf("%.2lf ", array_value(array, i, j));
        }
        printf("\n");
    }
}

#include <errno.h>
#include <string.h>
int main(void)
{
    struct Array *M = NewArray(2, 4);
    if (!M) {
        fputs(strerror(ENOMEM), stderr);
        return EXIT_FAILURE;
    }
    PrintArray(M);
    FreeArray(M);
}
added 3374 characters in body
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327
Loading
added 690 characters in body
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327
Loading
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327
Loading