繁体   English   中英

在没有多态的情况下优化 C 代码大小

[英]Optimizing C code size without polymorphism

我在这个网站和其他地方读过关于 C 中多态的内容,大多数评论员不鼓励这样做,或者建议改用 C++。 我有彼此非常相似的结构和例程,它们仅在成员和参数类型上有所不同。 这是代码:

h文件:

typedef struct {
  double *array;
  size_t used;
  size_t size;
} dArray;
void init_dArray(dArray *a, size_t initialSize);
void insert_dArray(dArray *a, double element); 

typedef struct {
  char** array;
  size_t used;
  size_t size;
} sArray;
void init_sArray(sArray *a, size_t initialSize);
void insert_sArray(sArray *a, char* element); 

typedef struct {
  int* array;
  size_t used;
  size_t size;
} iArray;
void init_iArray(iArray *a, size_t initialSize);
void insert_iArray(iArray *a, int element); 

void free_dArray(dArray *a);
void free_sArray(sArray *a);
void free_iArray(iArray *a);

c文件:

void init_dArray(dArray *a, size_t initialSize) {
  a->array = (double *)malloc(initialSize * sizeof(double));
  a->used = 0;
  a->size = initialSize;
}

void init_sArray(sArray *a, size_t initialSize) {
  a->array = (char**)malloc(initialSize * sizeof(char*));
  a->used = 0;
  a->size = initialSize;
}

void init_iArray(iArray *a, size_t initialSize) {
  a->array = (int *)malloc(initialSize * sizeof(int));
  a->used = 0;
  a->size = initialSize;
}

void insert_dArray(dArray *a, double element) {
  if (a->used == a->size) {
    a->size = (a->size*3)/2+8;
    a->array = (double *)realloc(a->array, a->size * sizeof(double));
  }
  a->array[a->used++] = element;
}

void insert_sArray(sArray *a, char* element) {
  if (a->used == a->size) {
    a->size = (a->size*3)/2+8;
    a->array = (char**)realloc(a->array, a->size * sizeof(char*));
  }
  a->array[a->used++] = element;
}

void insert_iArray(iArray *a, int element) {
  if (a->used == a->size) {
    a->size = (a->size*3)/2+8;
    a->array = (int*)realloc(a->array, a->size * sizeof(int));
  }
  a->array[a->used++] = element;
}

void free_dArray(dArray *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

void free_sArray(sArray *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

void free_iArray(iArray *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

主要的:

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
        iArray a;
        init_iArray(&a,5);
        for(int i=0; i<10; i++)
                insert_iArray(&a, i+1);
        for(int i=0; i<10; i++)
                printf("%d\n", a.array[i]);
        free_iArray(&a);
        exit(0);
}

有没有办法减少代码大小,不管有没有多态?

您可以简单地抽象出元素的类型 你的数组只需要知道这些元素有多大。 您可以完全允许用户通过函数指针提供复制构造函数和析构函数,或者您可以将数组的范围限制为memcpy()可移动类型。

为普通数据元素提供数组

您只需将元素的大小作为参数添加到数组struct

typedef struct {
  char *array;
  size_t elementSize;
  size_t used;
  size_t size;
} Array;

void Array_init(Array *a, size_t elementSize, size_t initialSize);
void Array_insert(Array *a, const void* element);
const void* Array_at(Array *a, size_t index);
void Array_destruct(Array *a);

所有对数组的索引只是将索引与给定的元素大小相乘以索引内部char数组。 内部char指针被隐式转换为接口的void指针,而后者又被隐式转换为double指针,或插入此数组的任何其他类型。

只要元素可以简单地复制,这个方法就很好用 如果元素需要自己管理内存,则需要以下方法:

为复杂数据元素提供数组

如果您的对象在复制时需要执行自定义操作,则需要为用户提供一种方法来提供必要的行为。 这是通过函数指针完成的:

typedef void (*Array_callback_copy_construct)(void* this, const void* original);
typedef void (*Array_callback_destruct)(void* this);
typedef struct {
  char *array;
  size_t elementSize;
  size_t used;
  size_t size;
  Array_callback_copy_construct copy_construct;
  Array_callback_destruct destruct;
} Array;

void Array_init(Array *a, size_t elementSize, size_t initialSize, Array_callback_copy_construct copy_construct, Array_callback_destruct destruct);
void Array_insert(Array *a, const void* element);
const void* Array_at(Array *a, size_t index);
void Array_destruct(Array *a);

Array_insert()Array_destruct()方法现在只需使用用户提供的回调函数来复制和销毁数组元素。

更高级的版本也可能使用移动构造函数回调和/或(移动)赋值回调。 复制构造 + 销毁是您需要的最小集合,使用更高级的回调可以实现更好的性能。


第一种方法很简单,可用于各种应用程序,我会毫不犹豫地使用它。 但是,必须清楚记录使用memcpy()过程

第二种方法适用于第一种方法失败的地方,但它通常比它的价值要麻烦得多。 避免它,除非您认为它确实是唯一的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM