向量实现和数据成员定义

时间:2016-01-04 14:33:38

标签: c vector data-structures dynamic-arrays

在我看过的许多矢量实现中,使用了以下矢量结构定义:

struct vector {
   void **data;
   int size;
   int count;
};

为什么我们需要指向指针的成员?

3 个答案:

答案 0 :(得分:3)

因为它可以是指针元素的向量,它可以具有任何类型(包括指针),因为void *可以转换为 1中的任何指针类型。此外,元素将以指针的大小分隔,使其更易于使用。

然后,您可以通过在转换为适当的指针类型后取消引用该元素的void *指针来获取实际值,或者只是在元素是指针时获取指针。

示例实现(远非完成当然 2

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

struct vector
{
    void **data;
    size_t count;
    size_t size;
};

void
vector_new(struct vector *vector, size_t size, size_t nmemb)
{
    vector->data = NULL;
    vector->count = 0;
    vector->size = size;
}

void
vector_push_back(struct vector *vector, void *value)
{
    unsigned char **data;    
    data = realloc(vector->data, sizeof(*data) * (vector->count + 1));
    if (data == NULL)
        return; // Probably return an error indicator
    vector->data = (void *) data;

    data[vector->count] = malloc(vector->size);
    if (data[vector->count] == NULL)
        return; // Probably return an error indicator
    memcpy(data[vector->count], value, vector->size);
    vector->count++;
}

void *
vector_get(struct vector *vector, size_t index)
{
    return (unsigned char *) vector->data[index];
}

int
main(void)
{
    struct vector vector;

    vector_new(&vector, sizeof(float), 100);

    for (int i = 0 ; i < 10 ; ++i)
    {
        float value;
                value = (float) rand() / RAND_MAX;
        fprintf(stdout, "vector[%d] %f\n", i, value);
        vector_push_back(&vector, &value);
    }

    fprintf(stdout, "Read them to check!\n");

    for (int i = 0 ; i < 10 ; ++i)
    {
        float value;
        value = *(float *) vector_get(&vector, i);
        fprintf(stdout, "vector[%d] %f\n", i, value);
    }
    return 0;
}

1 这种结构通常是一个糟糕的设计选择,因为它很难维护,并且编写访问器功能更难。然而,当然还有一些geniune用例。 语言不应该用于泛型类型,试图强制执行通常比问题更少的好处。

2 例如,它没有free / destroy函数。

答案 1 :(得分:0)

vector查看vector所期望的功能的精彩概述(该链接转到C ++中的vector,但有关其功能的信息适用于vector in一般来说,用C或C ++或任何其他语言表达。)

以下是抽象点。该功能为您提供了有关数据结构原因的线索。

  

向量是表示可以更改的数组的序列容器   大小

     

就像数组一样......也可以使用偏移来访问它们的元素   关于其元素的常规指针......但与数组不同,它们的大小   可以动态改变......

     

...向量容器可以分配一些额外的存储空间来容纳   为了可能的增长...因此,矢量不会每次都重新分配   将一个元素添加到容器中。

struct vector {
   void **data; // needs to act like an array of pointers i.e. void *data[]
   int size;    // actual memory allocated may be in access of count
   int count;   // current count of elements in data
};

答案 2 :(得分:-2)

这很常见。您可以将其视为:

char *data[size];

因此每个元素都是一个字符串,或任何大小在运行时都未知的存储类型。例如int i=123; data=malloc(sizeof(int)); memcpy(data, &i, sizeof(i));