我们在定义数组的时候,编译器总是让我们事先给数组界定大小,而不管我们实际需要多大的数组,这样我们只能定义一个足够大的数组,那到底多大是足够大呢?有些程序员就怕数组不够用,而将其定义的很大,这样势必造成资源的浪费。那么能不能定义一个数组,我们需要多大时就将其分配多大的空间呢?就是说数组的大小到我们真正用的时候再对其进行分配,而且还可以随意改变。当然可以,实现的简单方法就是将所需要的数据都打包进一个结构。下面是用
C++实现的一个例子,为了简单,我创建的是一个整型数组。
结构的定义
新数组称为IntArray,如下所示:
struct IntArray {
int *elems; // 数组元素
size_t numElems; // 数组大小
};
IntArray将一个指向数组的指针和记录数组大小的值进行了打包。Size_t是在标准头文件stddef.h中定义的,是一个最小无符号类型的typedef,通常就相当于unsigned int 或unsigned long型。
接口函数的声明
我们可以通过接口函数来定义和使用数组。接口函数如下:
void init( IntArray *object ); // 数组初始化
void cleanup( IntArray *object ) // 释放数组空间
void setsize( IntArray *object, size_t value ); // 设置数组大小
size_t getsize( IntArray *object ); // 得到数组大小
void setelem( IntArray *object, size_t index, int value ) // 数组元素赋值
int getelem( IntArray *object, size_t index ) // 引用数组元素
这就完成了基本函数的声明,当然如果你有兴趣,还可以添加一些更有用的函数,如调整数组大小但却不丢失现有信息,或者对数组元素进行排序等。
接口函数的定义
现在来完成这些接口函数的定义:
void init( IntArray *object )
{
object->numElems = 0;
object->elems = 0;
}
这个函数把object参数传递给它的一个新的IntArray对象置于没有元素的初始状态。
void cleanup( IntArray *object )
{
free( object->elems );
}
void setsize( IntArray *object, size_t value )
{
if( object->elems != 0 ) free( object->elems );
object->numElems = value;
object->elems = ( int *)malloc( value * sizeof( int ) );
}
这个函数实现改变数组的大小,首先释放掉旧的元素,然后保存新的元素,并为新元素分配空间。
size_t getsize( IntArray *object )
{
return object->numElems;
}
void setelem( IntArray *object, size_t index, int value )
{
object->elems[index] = value;
}
int getelem( IntArray *object, size_t index )
{
if( index >= object->numElems ) cerr << "bad index" ;
return object->elems[index];
}
这个函数实现访问给定下标所指的元素。
到现在,就实现了一个使用结构和接口函数的IntArray。
使用接口函数
这是一个例子:
void main()
{
IntArray a;
init( &a );
setsize( &a, 10 );
cout << getsize( &a ) << endl;
for( int i=0; i<10; i++ )
setelem( &a, i, i+1 );
for( i=0; i<10; i++ )
cout << getelem( &a, i ) << endl;
cleanup( &a );
}
这样,我们就可以随时使用多大的数组就定义多大的数组了。
当然,我们也可以用类来实现:如
class IntArray {
public:
void init();
void cleanup();
void setsize( size_t vlaue );
size_t getsize();
void setelem( size_t index, int value );
int getelem( size_t index );
private:
int *elems;
size_t numElems;
};
void IntArray::init( )
{
numElems = 0;
elems = 0;
}
void IntArray::cleanup( )
{
free( elems );
}
void IntArray::setsize( size_t value )
{
if( elems != 0 ) free( elems );
numElems = value;
elems = ( int *)malloc( value * sizeof( int ) );
}
size_t IntArray::getsize( )
{
return numElems;
}
void IntArray::setelem( size_t index, int value )
{
elems[index] = value;
}
int IntArray::getelem( size_t index )
{
if( index >= numElems ) cerr << "bad index" ;
return elems[index];
}
使用:
void main()
{
IntArray a;
a.init();
a.setsize( 10 );
cout << a.getsize() << endl;
for( int i=0; i<10; i++ )
a.setelem( i, i+1 );
for( i=0; i<10; i++ )
cout << a.getelem( i ) << endl;
a.cleanup();
}
如果谁有更好的方法,可以对此文进行升级。欢迎指正!