Navigation

C-Vector Library

Ein dynamisches Array in C

Sehr häufig steht man vor der Situation, in einem Programm eine vorher nicht bekannte Anzahl von Objekten verwalten zu müssen. In nicht gänzlich trivialen Programmen mag dies sogar eine der häufigsten Aufgaben darstellen. Während C++ mit STL verschiedene vorgefertigte Templates zu diesem Zweck bereitstellt, muß man sich in C mit der Low-Level Routinen wie etwa realloc begnügen. Verwaltet man ein dynamisches Array, so sieht die Verwaltung für alle Arrays gleich aus, unahängig davon, ob das Array nun einfach Zahlen, Strings variabler Länge, oder benutzerdefinierte Objekte enthält. Unterschiede gibt es vor allem hinsichtlich der Verarbeitung der eigentlichen Elemente:

  • Elementtypen variabler Größe, etwa Strings, werden typischenweise nicht direkt im Array gespeichert; stattdessen werden nur Zeiger auf einzelnen Elemente im Array gespeichert. Hat ein Elemwenttyp eine feste Größe, etwa long Werte, so werden die Elemente direkt im Array gespeichert.
  • Manche Elementtypen erfordern eine tiefe Kopie, andere böntigen hingegen nur eine bitweise Kopie. Beispielsweise benötigen Strings tiefe Kopien: für den Stringinhlat muß noch extra Speicher angefordertwerden.

Sieht man also von diesen typspezifischen Variantionsmöglichkeiten ab, so ist der Rest der Implementierung eines dynamischen Array stets der gleiche Aufwasch. Für eine generelles dynamisches Array welches für alle Typen gilt muß lediglich ein Weg gefunden werden, wie man die typspezifischen Besonderheiten formuliert. Die hier vorgestellte Library abstrahiert von den diesen Besonderheiten und erlaubt es damit prinzipiell, mit einem geringen satz von Routinen dynamische Arrays für wohl die meisten Elementtypen zu verwalten. Die Library habe ich "CVector Library" genannt, in Anlehnung an das vector Template der STL C++, welches eben auch dynamische Arrays mit C++ Mitteln abbildet.

Inhalt dieses Textes ist:

1. Quellcode

Quellcode Zunächstmal das Wesentliche: Hier gibt es den Quellcode. Unterstützte Plattformen Das Programm ist in ANSI gemäß dem C99 Standard geschrieben. Insbesondere Compiler, die keine inline Funktionen in C oder lokale Arrays variabler Größe kennen werden somit nicht in der Lage sein, den Quellcode zu kompilieren. Weitere Hinweise befinden sich in der Datei README, welche dem Quellcode beiliegt. Für Fragen stehe ich - soweit es meine Zeit und Lust zuläßt - gerne zur Verfügung. Darüberhinaus liegen og. Paket noch ein paar Beispielprogramme bei

2. Allgemeines Design

Arrays sind Sammlungen von Objekten gleichen Typs, wobei die einzelenen Objekte (auch Elemente genannt), in einem zusammenhängenden Speicher verwaltet werden und z.B. mit Hilfe eines Index adressiert werden können. Dynamische Arrays sind Arrays, die ihre Größe ändern können. Als Synonym für "dynamisches Array" wird im folgenden auch oft der Begriff "Vektor" verwendet, in Anlehnung an das gleichnamige Template aus der C++ Welt. Die CVector Library ist ein Satz von Funktionen, welche es erlauben, solche dynamischen Arrays zu verwalten.

Betrachtet man die typischen Operationen, die man mit einem dynamischen Array ausführen kann (Elemente hinzufügen, entfernen, ersetzen, abfragen, usw.), so stellt man schnell fest, daß all diese Operationen sehr ähnlich sind, ganz unabhängig davon, welchen Typen die Elemente des Arrays haben. So ist der allg. Algorithmus zum Einfügen eines neuen Elements im wesentlichen unabhängig von dem konkreten Elementtyp, ein Umstand den die STL in C++ ganz massiv ausnutzt. Ein wesentlicher Designaspekt der CVector Library ist daher die Abstraktion vom Elementtypen:

2.1. Abstraktion vom Elementtypen

Aus Sicht der CVector Library unterscheiden sich verschiedene Elementtypen nur durch zwei Aspekte: der Größe des Typs (also der Platzbedarf den ein einzelne Element hat) sowie hinsichtlich der Frage, ob ein Element eine innere Struktur hat und in besonderer Weise erzeugt und gelöscht werden muß (also ob es eine tiefe Kopie benötigt):

  • Hinsichtlich der Größe ist denkbar, daß alle Elemente eines Typs die gleiche feste Größe haben (z.B. long Werte), so daß die Größe eines Elements nicht typabhängig sondern elementabhängig ist (z.B. Zeichenketten). Während im ersten Fall die einzelnen Elemente direkt im Array gespeichert werden können, müssen im zweiten Fall die Elemente indirekt über einen Zeiger in dem Array gespeichert werden.

  • Bzgl. der tiefen Kopie unterscheiden sich Elemente, ob spezielle Funktionen zum erstellen bzw. Löschen aufgerufen werden müssen. Die Alternative heißt "flache Kopie" und bedeutet, daß ein Elemnt einfach bitweise kopiert werden kann.

Die CVector Library benutzt den Typen struct cv_vmt_s, diese vom Elementtypen abhängenden Eigenschaften zu beschreiben. Ein struct cv_vmt_s wird angegbenen, wenn ein dynamisches Array erzeugt wird (siehe cv_create für Details).










10 
typedef size_t (*cv_get_size_cb_t)(const void* item);
typedef cv_error_t (*cv_copy_cb_t)(void* dest, const void* source);
typedef void (*cv_destroy_cb_t)(void* item);
...
typedef struct cv_vmt_s {
    size_t item_size;
    cv_get_size_cb_t get_size_cb;
    cv_copy_cb_t copy_cb;
    cv_destroy_cb_t destroy_cb;
} cv_vmt_t;

Man erkennt, daß ein struct cv_vmt_s (Zeile 5-10) eine Struktur ist, welche aus vier Komponenten besteht:

  1. size ist die Größe eines Elements durch den Typ vorgegeben, also wenn alle Elemente gleich groß sind, so enthält size genau diese Größe. Ist die Größe der Elemente hingegen variabel, so steht in size eine 0 und stattdessen wird mit Hilfe der folgenden Komponente die Größe bestimmt:

  2. get_size_cb ist ein Zeiger auf eine Funktion die benutzt wird, um die Größe eines Elements zu bestimmen. Letztlich wird diese Funktion nur dann benötigt, wenn die Elemente eine variable Größe haben, man kann dieses Feld also ansosnten auf NULL setzen. Der Funktion übergibt man einen Zeiger auf das Element, dessen größe ermittelt werden soll und der Rückgaebwert der Funktion is die gesucht Größe (vgl. Typdefinition in Zeile 1)

  3. copy_cb ist ein Zeiger auf eine Funktion die benutzt wird, wenn ein Element eine tiefe Kopie benötigt. Wenn hier eine NULL angegeben wird, wird implizit angenommen, daß keine tiefe Kopie erfoderlich ist (in diesem fall ist meist auch destroy_cb NULL). Dei Funktion erwartet zwei Zeiger auf Elemente: der erste Zeiger zeigt auf einen Speicherbereich für das neue Element, der zweite zeigt auf ein bereit sexistierendes. Üblicherweise besteht die Aufgabe von copy_cb Speicher für das zu initialisierende Element zu belegen.

  4. destroy_cb ist das Gegenstück zu copy_cb und wird benutzt, um ein vorher mittels copy_cb initialisiertes Element wieder freizugeben.

2.2. Basisroutinen

Auf Basis einer struct cv_vmt_s Struktur für einen bestimmten Typen können allgmeinegültige Funktion definiert werden, welche generelle Operationen mit dynamischen Arrays erlauben. Da die struct cv_vmt_s Struktur alle typspezifischen informationen enthält, sind die Basisroutinen typunabhängig. Ein Beispiel: cv_insert ist einen Basisroutine, welche ein oder mehrere Elemente an einer beliebigen Stelle in dem dynamischen Array einfügen kann. Sowohl die Frage, wieviel Platz die Elemente im Array benötigen alsauch wie genau die Elemente in das Array zu kopieren sind (tiefe oder flache Kopie) ist bereits in der struct cv_vmt_s Struktur definiert. Die typischen Bearbeitungsschritte, die beim Einfügen von Elementen erforderlich sind (z.B. bereits existierende Elemente weiter ans Ende des Arrays verschieben, um Platz für die neuen Elemente zu machen, das Array bei Bedarf zu vergrößern usw.), sind jedoch typunabhängig und allgemeingültig in cv_insert implementiert.

Die ganze Sache hat nur einen Haken: Die Basisroutinen sind allgemeingültig und daher tendenziell unpraktisch zu bedienen. cv_insert ist etwa so deklariert:

cv_error_t cv_insert(
    cv_vector_t v,
    size_t index,
    const void* items,
    size_t count);

Zwar kann die Routine - entsprechende struct cv_vmt_s Struktur vorausgesetzt - prinzipiell für jede Art von Datentypen angewendet werden, allerdings teilweise nur auf recht umständliche Art und weise: Nehmen wir an, wir hätten ein dynamisches Array für int Werte und wir wollten nun an den Anfang des Arrays genau eine Zahl (sagen wir 4711) einfügen. Der Code würde wie folgt aussehen:

int n = 4711;
int* p = &n;
cv_insert(v, 0, p, 1);

Da das nicht so richtig intuitiv ist, gibt es neben den Basisroutinen die Wrapperroutinen:

2.3. Wrapperrotuinen

Unter einer Wrapperroutine versteht man eine Routine, welche um eine Basisroutine "herumgebaut" ist. Diese Wrapperroutinen sind typspezifisch, d.h. z.B. daß zu der oben erwähnten Routine cv_insert Wrapperroutinen für int Werte definiert werden, etwa derart:










10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
// Allg. Wrapper für int
inline cv_error_t
cv_int_insert(  cv_vector_t v, size_t index, const int* items, size_t count) {
    return cv_insert(v, index, items, count);
}

// Spezieller Wrapper: genau ein int einfügen:
inline cv_error_t cv_int_insert_single(cv_vector_t v, size_t index,   int item) {
    return cv_insert(v, index, &item, 1);
}

// Spezieller Wrapper: genau ein int am Anfang einfügen:
inline cv_error_t
cv_int_push_front(cv_vector_t v, int item) {
    return cv_insert(v, 0, &item, 1);
}

// Spezieller Wrapper: genau ein int am Ende einfügen:
inline cv_error_t
cv_int_push_back(cv_vector_t v, int item) {
    return cv_insert(v, cv_size(v),&item, 1);
}

All diese Routinen sind im Prinzip einfache Aufrufe von cv_insert. Allen gemeinsam ist, daß sie als Typ für die Elemente nicht mehr void* sondern der "wahren" Elementtyp des dynamischen Arrays benutzen. Weiterhin beginnt jeder Routinennamen mit cv_int_, um zu verdeutlichen daß es sich um eine Routine für int-basierte dynamische Arrays handelt. Da nun sicherlich nicht für jeden erdenklichen Elementtypen ein solcher Satz von Routinen vordefiniert werden kann, definiert die CVector Library kurzerhand Macros, welche es erlauben, die entsprechenden Routinen für einen konkreten Datentypen zu definieren. Wie diese Macro heißen und wie sie benutzt werden, wird im folgenden beschrieben:


3. API Dokumentation

3.1. Inhalt


3.2. Macros

Die folgenden Macro dienen dazu, die Wrapperroutinen zu definieren. Es gibt drei Versionen dieser Macros:


3.2.1. Funktionsdefinitionen für Arrays beliebigen Typs - CV_DECL_CUSTOM_VECTOR

Definition

CV_DECL_CUSTOM_VECTOR(type, prefix, vmt)

Beschreibung

Diese Macro definiert alle Routinen die notwendig sind, um mit einem Array des Typs type zu arbeiten. Dabei kann man mit dem Parameter prefix beeinflussen, welchen Namen diese Routinen haben sollen. Die Routinen sind allesamt inline definiert. Dieses Macro ist die allgemeinste Möglichkeit, die Routinen zu deklararieren. Für die primitiven Datentypen sowie für C Strings gibt es gesonderte, spezialisierte Macros, welche noch einfacher sind.

Parameter

3.2.2. Funktionsdefinitionen für C String Arrays - CV_DECL_STRING_VECTOR

Definition

CV_DECL_STRING_VECTOR

Beschreibung

CV_DECL_STRING_VECTOR ist eine Abkürzung für CV_DECL_CUSTOM_VECTOR(char*, str, cv_str_vmt). Der letzte Parameter (cv_str_vmt) ist eine von der CVector Library vordefinierte struct cv_vmt_s Struktur für C Strings. Wird also dieses Macro aufgerufen, hat man die Routinen für ein dynamisches Array von C Strings.

Parameter
Keine.

3.2.3. Funktionsdefinitionen für Arrays von primitiven Datentypen - CV_DECL_PRIMITIVE_VECTOR

Definition

CV_DECL_PRIMITIVE_VECTOR(type, prefix)

Beschreibung

CV_DECL_PRIMITIVE_VECTOR wird benutzt, um die Routinen für dynamische Arrays primitiver Datentypen zu definieren. Solche primitiven Datentypen sind z.B. long, char, double usw.; Im prinzip ist aber auch jeder andere Datentyp denkbar, welcher eine feste Größe ausweist und keine tiefe Kopie erforderlich macht. Auch CV_DECL_PRIMITIVE_VECTOR ist im prinzip eine Abkürzung, nämlich für CV_DECL_CUSTOM_VECTOR(char*, str, cv_##prefix##_vmt). D.h. das Macro setzt voraus, daß es eine struct cv_vmt_s Struktur gibt, deren Namen sich u.a. aus dem Präfix prefix ergibt. Um diese Struktur zu definieren, ist ein weiterer Macroaufruf notwendig, nämlich der von CV_DEF_PRIMITIVE_VECTOR.

Parameter
  • type - ist der Typ der Elemente in dem Dynamischen Array, also etwa int, long, oder double usw.

  • prefix - ist der Prefix für die Routinen namen, um diese von Wrapperroutinen für andere Typen zu unterscheiden. Setzt man diesen Parameter etwa auf xyz, so wird allen Routinen ein cv_xyz_ vorangestellt.


3.2.4. Definition einer struct cv_vmt_s Struktur für primitive Datentypen - CV_DEF_PRIMITIVE_VECTOR

Definition

CV_DEF_PRIMITIVE_VECTOR(type, prefix)

Beschreibung
pWenn man die Funktionen für das dynamische Array mittels des Macros
CV_DECL_PRIMITIVE_VECTOR definiert, so gibt man keine struct cv_vmt_s Struktur an; diese muß man explizit definieren. Dieses Macro Its genau zu diesem Zweck gedacht und definiert passend zum CV_DECL_PRIMITIVE_VECTOR eine entsprechende Struktur für einen Elementtyp fester Größe (nämlich sizeof(type), welcher keine feste Kopie erwartet.
Parameter
  • type - ist der Typ der Elemente in dem Dynamischen Array, also etwa int, long, oder double usw.

  • prefix - ist der Prefix für die Struktur. Setzt man diesen Parameter etwa auf xyz, so wird dem Namen der Strukturvariablen ein cv_xyz_ vorangestellt.


3.3. Funktionen

Im folgenden werden die Funktionen des CVector Library API beschrieben. Dabei werden jedoch primär die Wrapperroutinen beschrieben, welche mit den o.g. Macros definiert werden. Daher enthalten alle hier beschriebenen Routinen einen Variablen Anteil im Namen, nämlich das, was bei den macros als der prefix Parameter bezeichnet ist. Im Folgenden wird daher in den Routinennamen das Präfix mit * abgekürzt. Der Elementyp wird mit TYPE gekennzeichnet.


3.3.1. cv_*_create

Definition
cv_error_t cv_*_create(cv_vector_t* v);
Beschreibung

Initialisiert das dynamische Array v. Diese Routine sollte vor jeder anderen aufgerufen werden. Wenn die Routine erfolgreich war und v nicht mehr genutzt wird, muß cv_destroy aufgerufen werden, um den Speicher freizugeben, den v belegt. Zu beachten ist weiterhin, daß diese Routine implizit eine struct cv_vmt_s Struktur an v bindet, welche den Elementtypen beschreibt.

Parameter
  • v - der cv_vector_t, welcher zu initialisieren ist.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall (nur möglich bei zuwenig Speicher) CV_ERR_NOMEM


3.3.2. cv_*_destroy

Definition
void cv_*_destroy(cv_vector_t* v);
Beschreibung

Löscht das dynamische Array v. Es werden also alle Elemente freigegeben und der Speicher, der intern zu Verwaltung des Arrays benutzt wurde. Diese Funktion darf nur nach cv_create aufgerufen werden.

Parameter
  • v - der cv_vector_t, welcher frei zu geben ist.

Rückgabe
Keine.

3.3.3. cv_*_reserve

Definition
cv_error_t cv_*_reserve(cv_vector_t* v, size_t space);
Beschreibung

Reserviert ausreichend Speicher, damit in das dynamische Array v mindestens space weitere Elemente eingefügt werden können, ohne daß intern das Array abermals vergrößert werden muß. Die Routine kann dafür einegsetzt werden, das Array im Voraus zu vergrößern, wenn ungefähr bekannt ist, wie viele Elemente eingefügt werden sollen. Es wird gewissermßen Speicher auf Halde belegt. Das Gegenstück zu dieser Funkion ist cv_shrink

Parameter
  • v - der cv_vector_t, welcher zu vergrößern ist.

  • space - Anzahl der Elemente, die v zusätzlich aufnehmen können soll.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall (nur möglich bei zuwenig Speicher) CV_ERR_NOMEM


3.3.4. cv_*_shrink

Definition
cv_error_t cv_*_shrink(cv_vector_t* v);
Beschreibung

Minimiert den Sopeicherbedarf des dynamischen Arrays v. Intern hält v meist etwas Speicher auf Halde, damit nicht bei jeder Einfügeoperation das Array vergrößert werden muß (cv_reserve besorgt diesen Speicher explizit). cv_shrink wird genutzt, um nicht benötigten Speicher freizugeben.

Parameter
  • v - der cv_vector_t, welcher zu verkleinern ist.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall (nur möglich bei zuwenig Speicher) CV_ERR_NOMEM


3.3.5. cv_*_array

Definition
const TYPE* cv_*_array(const cv_vector_t* v);
Beschreibung

Gibt einen Zeiger auf das erste Element des Arrays zurück. Ist das Array leer, ist der Rückgabewert nicht definiert. Die Routine ist dafür gedacht, gezielt auf Arrayelemente zuzugreifen, weil es keine Routinen zum setzen oder auslesen eines einzelnen Elementes gibt.

Parameter
  • v - der cv_vector_t, der die Elemente enthält.

Rückgabe

Zeiger auf das erste Element oder - wenn das Array leer ist - ein undefinierter Wert.


3.3.6. cv_*_size

Definition
size_t cv_*_size(const cv_vector_t* v);
Beschreibung

Ermittelt die Anzahl der Elemente in dem Array.

Parameter
  • v - der cv_vector_t, der die Elemente enthält.

Rückgabe

Anzahl der Elemente.


3.3.7. cv_*_push_front

Definition
cv_error_t cv_*_push_front(cv_vector_t* v, const TYPE item);
Beschreibung

Fügt item am Anfang von v ein. D.h. daß alle bisher in v enthaltenen Elemente verschoben werden, um für item Platz zu machen. Die Funktion ist im Prinzip eine Abkürzung für folgenden Aufruf: cv_*_insert(v, 0, &item, 1). Die Routine vergrößert bei Bedarf automatisch das Array.

Parameter
  • v - der cv_vector_t, in den eingefügt wird.

  • item - das Element, welches eingefügt wird.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall (nur möglich bei zuwenig Speicher) CV_ERR_NOMEM


3.3.8. cv_*_push_back

Definition
cv_error_t cv_*_push_back(cv_vector_t* v, const TYPE item);
Beschreibung

Hängt item am Ende von v an. Die Funktion ist im Prinzip eine Abkürzung für folgenden Aufruf: cv_*insert(v, cv_*_size(v), &item, 1). Die Routine vergrößert bei Bedarf automatisch das Array.

Parameter
  • v - der cv_vector_t, in den eingefügt wird.

  • item - das Element, welches eingefügt wird.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall (nur möglich bei zuwenig Speicher) CV_ERR_NOMEM


3.3.9. cv_*_insert_single

Definition
cv_error_t cv_*_insert_single(cv_vector_t* v, size_t index, const TYPE item);
Beschreibung

Fügt item an Position index in v ein, ggf. nachfolgende Elemente werden entsprechend verschoben. Die Funktion ist im Prinzip eine Abkürzung für folgenden Aufruf: cv_*insert(v, index, &item, 1). Die Routine vergrößert bei Bedarf automatisch das Array.

Parameter
  • v - der cv_vector_t, in den eingefügt wird.

  • index - Einfügeposition (zwischen 0 und cv_size(v) ist alles erlaubt.

  • item - das Element, welches eingefügt wird.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_NOMEM (bei zuwenig Speicher) oder CV_ERR_BADINDEX (wenn index nicht im erlaubten Bereich).


3.3.10. cv_*_insert

Definition
cv_error_t cv_*_insert(cv_vector_t* v, size_t index, const TYPE* items, size_t count);
Beschreibung

Dies ist die allgemeinste Funktion zum Einfügen von neuen Elementen in das Array. Sie fügt in v an Position index count neue Elemente ein, wobei items auf das erste einzufügende Element zeigt. Ggf. nach der Einfügeposition bereits existierende Elemente in v werden entsprechend verschoben. Die Routine vergrößert bei Bedarf automatisch das Array.

Parameter
Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_NOMEM (bei zuwenig Speicher) oder CV_ERR_BADINDEX (wenn index nicht im erlaubten Bereich).


3.3.11. cv_*_pop_front

Definition
cv_error_t cv_*_pop_front(cv_vector_t* v);
Beschreibung

Diese Routinen entfernt das erste Element aus dem Array v und sorgt dafür, daß alle folgenden Elemente um eine Position nach vorne rücken. Im Prinzip ist diese Routine eine Abkürzung für den Aufruf cv_remove(v, 0, 1). Zu beachten ist, daß diese Routine den intern reservierten Speicher für das Array nicht verkleinert. Ist dies gewünscht, muß cv_shrink verwendet werden.

Parameter
  • v - der cv_vector_t, dessen erstes Element entfernt werden soll.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_BADINDEX (wenn Array bereits vor Aufruf leer war).


3.3.12. cv_*_pop_back

Definition
cv_error_t cv_*_pop_back(cv_vector_t* v);
Beschreibung

Diese Routine entfernt das letzte Element aus dem Array v. Im Prinzip ist diese Routine eine Abkürzung für den Aufruf cv_remove(v, cv_size(v)-1, 1). Zu beachten ist, daß diese Routine den intern reservierten Speicher für das Array nicht verkleinert. Ist dies gewünscht, muß cv_shrink verwendet werden.

Parameter
  • v - der cv_vector_t, aus dem entfernt werden soll.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_BADINDEX (wenn Array bereits vor Aufruf leer war).


3.3.13. cv_*_remove_single

Definition
cv_error_t cv_*_remove_single(cv_vector_t* v, size_t index);
Beschreibung

Diese Routine entfernt das Element an Position index aus dem Array v und sorgt dafür, daß alle folgenden Elemente um eine Position nach vorne rücken. Im Prinzip ist diese Routine eine Abkürzung für den Aufruf cv_remove(v, index, 1). Zu beachten ist, daß diese Routine den intern reservierten Speicher für das Array nicht verkleinert. Ist dies gewünscht, muß cv_shrink verwendet werden.

Parameter
  • v - der cv_vector_t, aus dem entfernt werden soll.

  • index - Index des zu entfernenden Elements.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_BADINDEX (wenn index nicht im erlaubten Bereich war).


3.3.14. cv_*_remove

Definition
cv_error_t cv_*_remove(cv_vector_t* v, size_t index, size_t count);
Beschreibung

Diese Routine entfernt count Elemente ab Position index aus dem Array v und sorgt dafür, daß alle folgenden Elemente um eine Position nach vorne rücken. Zu beachten ist, daß diese Routine den intern reservierten Speicher für das Array nicht verkleinert. Ist dies gewünscht, muß cv_shrink verwendet werden.

Parameter
  • v - der cv_vector_t, aus dem entfernt werden soll.

  • index - Index des ersten zu entfernenden Elements.

  • count - Anzahl der zu entfernenden Elemente.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_BADINDEX (wenn index und count keinen gültigen bereich angeben).


3.3.15. cv_*_remove_all

Definition
void cv_*_remove_all(cv_vector_t* v);
Beschreibung

Diese Routine entfernt alle Elemente aus dem Array v. Im Prinzip ist diese Routine eine Abkürzung für den Aufruf cv_remove(v, 0, cv_size(v)). Zu beachten ist, daß diese Routine den intern reservierten Speicher für das Array nicht verkleinert. Ist dies gewünscht, muß cv_shrink verwendet werden.

Parameter
  • v - der cv_vector_t, dessen Elemente entfernt werden sollen.

Rückgabe

Keine.


3.3.16. cv_*_replace_single

Definition
cv_error_t cv_*_replace_single(cv_vector_t* v, size_t index, const TYPE item);
Beschreibung

Diese Routine ersetzt das Element an Stelle index im Array v durch eine Kopie von item. Diese Routine is eine Abkürzung für den Aufruf cv_replace(v, index, &item, 1).

Parameter
  • v - der cv_vector_t, in dem ersetzt werden soll.

  • index - Index des zu ersetzenden Elements.

  • item - Neues Elements

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_BADINDEX (wenn index nicht im gültigen Bereich) oder CV_ERR_NOMEM (Wenn Kopie von item fehlschlug).


3.3.17. cv_*_replace

Definition
cv_error_t cv_*_replace(cv_vector_t* v, size_t index, const TYPE* items, size_t count);
Beschreibung

Diese Routine ersetzt ab Stelle index count Elemente im Array v durch eine Kopie von den Elementen, die ab items im Speicher stehen. Für jedes Element von items wird eine Kopie gemacht.

Parameter
  • v - der cv_vector_t, in dem ersetzt werden soll.

  • index - Index des ersten zu ersetzenden Elements.

  • items - Zeiger auf das erste neue Element

  • count - Anazhl der zu ersetzenden Elemente.

Rückgabe

Wenn die Funktion erfolgreich war, wird CV_ERR_NONE zurückgegeben. Im Fehlerfall CV_ERR_BADINDEX (wenn index und count nicht im gültigen Bereich) oder CV_ERR_NOMEM (Wenn Kopie von items fehlschlug).


Ihre Meinung ist mir wichtig

Haben Sie einen Fehler gefunden, wollen etwas anmerken oder fragen? Gefällt Ihnen etwas nicht oder wollen Sie ein Lob loswerden? - Nur raus damit!