我在table.c
中定义了几个相当大的数组(每个数组大约有1500个成员)。我需要将它们传递给不同的模块和/或提供一种如何更新它们的方法。
我的问题是如何使它最有效,而不是浪费记忆。我的想法是做标准getters/setters
。因此,如果get
我将拥有公共职能:
void getTable(tableID, *table)
tableID
将枚举我想要的女巫表,*table
将指向表格。我想只是一个引用被传递,所以表不是"重复"在记忆中。
然后在otherModule.c中我将jsut调用
table *myPointer;
getTable(TableA, myPointerTable).
这是对的吗?
答案 0 :(得分:2)
我在table.c中定义了几个非常大的数组(每个数组大约有1500个成员)。
在目前的笔记本电脑上(拥有数十亿字节的RAM),十几万个数字的阵列并不大,它是一个很小的阵列。今天,大型阵列至少拥有数百万(机器)数字,您最好使用C dynamic memory allocation。
(当然,如果数组的每个元素都是一些复杂而繁重的数据结构 - 例如某些bignum - 事情就不同了)
您可以传递一个指针(指向数组,或指向以flexible array member结尾的某些struct
)。
extern double bigarray[123456];
foo(bigarray);
不要复制数组(但只传递其地址)。
我的想法是做标准的getter / setter。
这可能很好,而且可能更具可读性。
顺便说一句,你可以定义这些吸气剂& setter在公共头文件中起一些static inline
函数的作用(适当地#include
编辑)。这将使您的代码可读且快速。
答案 1 :(得分:2)
数组表达式"衰变"在大多数情况下指向,所以如果你定义类似
的东西T humongous[50000]; // for some arbitrary type T
并将其传递给类似
的函数foo( humongous );
foo
收到的只是指向第一个元素的指针,而不是整个数组:
void foo( T *arr ) { ... }
请注意,在函数参数声明的上下文中,T a[N]
和T a[]
被视为与T *a
相同 - 它们都将a
声明为指针到T
。基本上,你不能通过值"传递数组。到C.中的函数。
现在,如果您的数组是struct
或union
类型的成员,并且您将该类型的表达式传递给函数,那么您将创建函数中整个数组的副本:
struct blah {
...
T humongous[50000];
...
} bletch;
foo( bletch );
void foo( struct blah b ) { ... } // b is a full copy of bletch
因此,在这种情况下,您可能希望将指针传递给bletch
而不是:
foo( &bletch );
void foo( struct blah *b ) { ... }
答案 2 :(得分:1)
对于较小的程序,Setter / getter可能是个好主意,尽管您可能希望格式为
table_t* getTable (tableID)
但是,这不是OO意义上的纯getter函数,因为您通过指针公开私有数据。此外,重新入侵可能会成为这种方法的一个问题。对于需要在较长时间内维护的较大的专业课程,这不会做。
最佳解决方案是将分配留给调用者。您可以使用 opaque指针间接执行此操作:
table.h
typedef struct table_t table_t; // forward declaration
table_t* table_init (size_t size, /* stuff */);
void table_free (table_t* table);
table.c:
#include "table.h"
struct table_t // this will be unknown to the caller
{
// private, encapsulated data:
size_t size;
int data[]; // flexible array member
};
table_t* table_init (size_t size, /* stuff */)
{
table_t* result = malloc(sizeof(*result) + int[size]);
if(result == NULL) { /* handle errors */ }
result->size = size;
do_something(result->data);
return result;
}
void table_free (table_t* table)
{
free(table);
/* optionally, make the parameter table_t** and set the pointer
to NULL after calling free() */
}
caller.c:
#include "table.h"
table_t* table = table_init(n, /* stuff */);
table_do_stuff(table); // either setter/getter or actual algorithm
table_free(table);
这给出了一个合适的设计并允许多个实例,这也解决了重新进入的问题。