Basics zu Arrays und Initialisierung

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 06 10 2024  16:25:47      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Osziloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte


Autor
Basics zu Arrays und Initialisierung

    







BID = 717932

Teletrabi

Schreibmaschine



Beiträge: 2317
Wohnort: Auf Anfrage...
 

  


Moin,

möchte hier ein Programmstricken, dass eine - aus Erweiterungsgründen flexible - Anzahl Elemente überwacht. Eigenschaften der Elemente wie diverse Statusflags usw. werden in einem Vektor abgelegt, der eine struct aus den flags, ein paar int-Werten sowie auch einen Bezeichnungstext enthält.

Um Probleme durch Eingabe zu langer Texte zu vermeiden, wollt ich die Eingaben aus einer Initalisierungs-Variablen ala char[] Name = "Bla1" in die Elemente kopieren und bei zu langen bezeichnungen ggf. nach X Zeichen das Kopieren Abbrechen und \n dranhängen, um eine definierte maximale Bezeichnungslänge zu haben.

Um es konfigurierbar zu halten, wollt ich die Texe als #define Text1 "bla1" in einer Header-Datei Sammeln.

Soo, nur wie löse ich das ganze jetzt möglichst flexibel, ohne im Programmcode selber rumzuwuseln? Ich halte es noch für akzeptabel die Anzahl der Elemente sowie die (ggf überlangen) Namen per Hand eizugeben. Kann ich Beispielsweise ein Array initalisieren ala


#define Elementeanzahl 4

char[Elementeanzahl][] NameArray {"bla1", "bla2", "blubb3", "dumdidum4"};

=> anschließend Kopierschleife, die Elememtananzahl durchläufe zu je max 4 Zeichen in die Felder der jeweiligen Structures kopiert.



sodass die Länge der zweiten Dimension automatisch bestimmt wird in Abhängigkeit vom längsten einkonfigurieten Text?




BID = 717937

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

 

  

Moin!

Ist die Zielumgebung ein µC?


Zitat :
in einem Vektor abgelegt, der eine struct aus den flags, ein paar int-Werten sowie auch einen Bezeichnungstext enthält.

Also so:

struct Eigenschaft
{
 int nummern;
 int flags;
 char bezeichner[maximale_String_Länge];
} Eigenschaften[Anzahl_der_Elemente];

?


Zitat :
Um Probleme durch Eingabe zu langer Texte zu vermeiden, wollt ich die Eingaben aus einer Initalisierungs-Variablen ala char[] Name = "Bla1" in die Elemente kopieren und bei zu langen bezeichnungen ggf. nach X Zeichen das Kopieren Abbrechen und \n dranhängen, um eine definierte maximale Bezeichnungslänge zu haben.


Das erledigt man dann in so einer Art Konstruktor,m der den Vektor mit allen Werten initialisiert.
Nachteil dabei ist allerdings, dass die Werte im RAM zweimal vorliegen, nämlich einmal im Vektor aller Elemente sowie aus den rein statischen Zellen, die den Initialisierungstext enthalten.

Das ist nachteilig, man kann auch im Vektor bloß Zeiger auf die jeweiligen, statischen!, Texte ablegen:

...
char* bezeichner;
...

Im "Konstruktor" initialisiert richtet man die Zeiger dann auf die entsprechenden Strings, ohne kopieren zu müssen.

Gehen wir aber mal davon aus, dass die Strings im Vektor abgelegt werden, wobei der Bezeichner STRING_LÄNGE Zeichen enthalten darf, dann kann das so aussehen:
Header:
/* Alle Texte als kommaseparierte Liste: */
#define    TEXTE       "Text1", "Text2", "Text3", "..."

/* und maximale Stringlänge: */
#define    TEXT_LÄNGE  4

Programmkode:
/* statisches Array mit den Texten: */
static char* stat_texte[] = {TEXTE};

/* Anzahl der Elemente (kann im Präprozessor berechnet werden): */
#define    TEXT_ANZAHL (sizeof stat_texte/sizeof(char*))


/* Struktur (davon ein Vektor mit gleicher Anzahl an Elementen wie es Texte gibt): */
static struct Eigenschaft
{
 int  nummern;
 int  flags;
 char bezeichner[TEXT_LÄNGE+1];
} Eigenschaften[TEXT_ANZAHL];


/* Struktur initialisieren: */
static void _ctor(void)
{
  register unsigned char i;

  for(i=0;i<TEXT_ANZAHL;i++)
  {
    strncpy(Eigenschaften[i].bezeichner, stat_texte[i], TEXT_LÄNGE);
    Eigenschaften[i].bezeichner[TEXT_LÄNGE] = '\0';
  }
}


So könnte das aussehen.
Es werden auf jeden Fall nur soviele Bytes kopiert, wie Platz vorhanden ist. Dann wird mit einem NUL, also Null-Byte, terminiert. \n ist ein Zeilenumbruch und terminiert den String nicht.

Das einzige, was benötigt wird, sind die diversen Bezeichner (Texte), der Rest erledigt sich automatisch. Das einzige, was im Programm noch erledigt werden muss, ist, den Vektor zu initialisieren (_ctor).

Nachteile sind aber weiterhin:
1. Die Strings sind eigentlich doppelt vorhanden und überlange Texte verbrauchen auf jeden Fall unnötig Speicherplatz. Mit dem Präprozessor kommt man nicht groß weiter, denn Zuweisungen wie

static char text[5] = "Hallogggggg";

Werden ganz brav (gibt beim GCC ne Warnung) umgesetzt: Fünf Bytes (die ersten) werden im Array abgelegt, es fehlt aber die Terminierung! Absolut tödlich, wenn man mit reinen C-Strings arbeitet.

Arbeitet man jedoch mit Zeigern im Vektor, werden die Strings bei statischer Zuweisung nur einmal im RAM abgelegt, dafür fehlt entweder die Terminierung (String zu lang) oder aber man kann sie nicht in der Länge beschänken.

Wird das ganze auf AVRs umgesetzt, empfiehlt es sich außerdem, die konstanten Strings im ROM abzulegen. Der Datentyp heißt dann prog_char* und pgmspace.h muss inkludiert werden.

Edit:
Man kann _ctor sogar so mit Attributen versehen, dass der Konstruktor automatisch ausgeführt wird, also im "Konstuktorsegment" landet. Ergibt nur dann Sinn, wenn es eine argumentlose Prozedur ist.

P.S.: sollen die Bezeichner zur Laufzeit verändert werden können? Wenn nein, dann würde ich das wirklich statisch machen (auf Kosten einer nicht festgelegten Stringlänge).



_________________


[ Diese Nachricht wurde geändert von: DonComi am  2 Okt 2010  2:02 ]

BID = 718028

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Achso


Zitat :

sodass die Länge der zweiten Dimension automatisch bestimmt wird in Abhängigkeit vom längsten einkonfigurieten Text?


Ist meines Wissens nicht möglich oder dann wieder nur über üblen Präprozessormissbrauch...

Möglich ist aber natürlich folgendes:

#define MEINE_TEXT "bla1", "bla2", "blablup3", "dumdiddeldum4"

static char Texte[][12] = {MEINE_TEXTE};

Sorge dann dafür, dass der Compiler pedantisch mit dem Source umgeht bzw. lass mehr Warnungen anzeigen. Ein guter Compiler meckert, wenn die Literale länger sind, als Platz verfügbar ist.
Das schützt aber beim GCC z.B. nicht davor, dass eine Zeichenkette mit der maximalen Länge ohne Terminierung abgelegt wird. Für die reicht der Platz nämlich aus, und es wird nicht gemotzt.
Wenn du dann reine C-String-Funktionen nimmst (wie sie die libc traditionell verarbeitet, bis man sie auf Operationen erweiterte, wo Stringlängen explizit mitangegeben werden (strncmp, strncpy, snprintf, ...), um Pufferüberläufen vorzubeugen) kann das völlig harmlos verlaufen (zufällige NUL am Stringende, aber in illegalem Speicherbereich) oder zum Gau führen. Die Sache wird also, ohne Meldung, unsicher. Das ist halt der größte Nachteil an C.

_________________


Zurück zur Seite 1 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 19 Beiträge im Durchschnitt pro Tag       heute wurden bisher 2 Beiträge verfasst
© x sparkkelsputz        Besucher : 182134969   Heute : 3341    Gestern : 5445    Online : 737        6.10.2024    16:25
4 Besucher in den letzten 60 Sekunden        alle 15.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.0544619560242