mikrocontroller.net

Forum: PC-Programmierung Variablenname inkrementieren


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich möchte in einer Schleife neue Variablen vom Typ Struct erstellen und 
deren Namen durchnummerieren.

z.B. soll im ersten Schleifendurchlauf var1 erstellt werden, im zweiten 
Durchlauf dann var2...

Wie kann ich eine in der Schleife inkrementierte Zahl einem 
Variablennamen anfügen?

Gruß
Daniel

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In welcher Sprache?

Allerdings: in den meisten Sprachen geht sowas überhaupt nicht.
Was du willst ist, du willst ein Array (ein Feld) von einem
bestimmten Typ anlegen und dann aus diesem Array einzelne
Elemente benutzen.

Arrays gibt es, je nach Programmiersprache, in verschiedenen
Ausführungen. Bei manchen ist die Größe, also die Anzahl der
Elemente, bereits zur Compilierzeit fix. Andere Arrays können
zur Laufzeit selbsttätig wachsen und schrumpfen.

Näheres dazu findest du in deinem Lehrbuch, das auf deine
Programmiersprache abgestimmt ist.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Variablennamen einfach durchnummerieren lassen wird wohl schwer.
Aber schreib am besten mal bissl mehr über dein Vorhaben.

In welcher Sprache?
Ist die Anzahl der zu erzeugenden Variablen fix? oder kann diese vom 
Benutzer geändert werden?
Warum unbedingt durchnummerierte Variablennamen?

Was mir da spontan einfallen würde, wäre ne Liste mit dienen structs zu 
machen und einfach zu viele Elemente einfügen lassen wie du willst.
Dann hast aber keine direkten Variablennamen.
Man könnte natürlich in die struct ein Element einfügen das den Namen 
representiert.

char name[10];

dann könntest zB. name[9] mit durchnummerierung belegen bzw. name[8] und 
name[9] falls du mehr als 10 brauchst.

Autor: LISP (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In LISP kann man Variablennamen inkrementieren.
Und noch andere fiese Dinge tun.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird LISP überhaupt noch benutzt?
Ich kenn das nur von den LISP Maschinen aus den 80ern. Aber kenn jetzt 
niemand der das könnte.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, ich arbeite hier mit dem C++ Compiler des Visual Studio 2008

Ich hab an meinem REchner mehrere Cypress-USB-Chips hängen, und deren 
Konfigurationen möchte ich nacheinander in einer Schleife abfragen. Und 
diese Daten sollen in Strukturen übernommen werden. Da eine beliebige 
Anzahl von Chips ausgelesen werden soll, soll nach Bedarf eine neue 
Struct-Variable angelegt werden... Und die für Namensgebung dieser 
Variablen wollte ich halt ein Wort und eine sich erhöhende Zahl 
nehmen...

So, das war die Zusammenfassung meines Problemchens

Eure Aussagen klangen bis jetzt ja nicht so vielversprechend, ich hoffe 
da ändert sich noch was :-)

Gruß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel wrote:
> Ach ja, ich arbeite hier mit dem C++ Compiler des Visual Studio 2008
>
> Ich hab an meinem REchner mehrere Cypress-USB-Chips hängen, und deren
> Konfigurationen möchte ich nacheinander in einer Schleife abfragen. Und
> diese Daten sollen in Strukturen übernommen werden. Da eine beliebige
> Anzahl von Chips ausgelesen werden soll, soll nach Bedarf eine neue
> Struct-Variable angelegt werden... Und die für Namensgebung dieser
> Variablen wollte ich halt ein Wort und eine sich erhöhende Zahl
> nehmen...

Ganz klar: Du suchst nach einer Containerklasse.
In Standard C++ wäre zb ein std::vector geeignet
In MFC wäre ein CArray oder eine CList ein guter Kandidat
(mit einer leichten Präferenz zu CList auf meiner Seite)
In .Net ... kann ich nicht sagen, das Gerümpel benutz ich nicht

> Eure Aussagen klangen bis jetzt ja nicht so vielversprechend, ich hoffe
> da ändert sich noch was :-)

Da ändert sich gar nichts mehr. Du kannst keine Variablen, also
etwas das einen Namen, hat zur Laufzeit erzeugen. Du kannst Objekte
erzeugen. Diese Objekte speichern deine Daten. Und natürlich kann
man solche Objekte in einem Container speichern.

Das einzige was sich noch ändert :-)
Hier kommt er, mein üblicher Spruch: Du brauchst Literatur. Ohne
ein vernünftiges Buch kann man nicht lernen. Try and Error funktioniert
bei Programmiersprachen auf diesem Level nicht.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaub ich hab mich nur falsch ausgedrückt. Ich möchte in jedem 
Schleifendurchlauf ein Objekt erzeugen. Und diese Objekte sollen 
durchnummeriert werden. Und genau da möchte ich wissen wie ich das 
meinem Compiler beibringe...

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wird LISP überhaupt noch benutzt?
> Ich kenn das nur von den LISP Maschinen aus den 80ern. Aber kenn jetzt
niemand der das könnte.

hmmm ... emacs?

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie oben schon erwähnt würd ich da zu ner Liste tendieren. Auch nachdem 
du nun deine Problemstellung genauer erläutert hast^^
In dem Fall ,wie Karl Heinz ja schon gesagt hat, ne CList. Und eben für 
jeden Chip ein weiters Element einfügen.

http://msdn2.microsoft.com/de-de/library/bxde0zae.aspx

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel wrote:
> Ich glaub ich hab mich nur falsch ausgedrückt. Ich möchte in jedem
> Schleifendurchlauf ein Objekt erzeugen. Und diese Objekte sollen
> durchnummeriert werden. Und genau da möchte ich wissen wie ich das
> meinem Compiler beibringe...

Und nochmal. Du kannst sie nicht durchnummerieren und in
Variablen speichern, die erst zur Laufzeit erzeugt werden.

Du brauchst einen Container, der die Objekte speichert.
  for( .... ) {

    USBDevice NewObj;    // Objekt mal temporär erzeugen
    NewObj. ......       // mit Daten füllen

    // und hier wird das Objekt dann dem Container übergeben
    // wie das genau funktioniert, hängt davon ab welchen
    // Container du benutzt.
 
    // zb. in Standard C++ würde man das so machen
    // ( eigentlich wird eine Kopie des Objektes erzeugt und im
    // Container gespeichert. Container die ihre Objekte per
    // Pointer referenzieren und nur die Pointer speichern, tu
    // ich dir jetzt nicht an )

    AllDevices.push_back( NewObj );

    // wobei AllDevices ein std::vector<USBDevice> ist


    // mit MFC Mitteln würde man sich zb ein
    // CArray< USBDevice, &USBDevice> AllDevices
    // anlegen und das neue Objekt (eigentich eine Kopie davon)
    // so in den Container einfügen
    AllDevices.Add( NewObj );

    // ähnlich würde das aussehen, wenn man statt einem CArray
    // ein CList aus der MFC nehmen würde.
  }

und um auf die Objekte im Container zuzugreifen, muss man denn Container
mal befragen, wieviele Objekte er denn enthält. Solche Funktionen
heissen meist count oder size oder zumindest so ähnlich

Std-C++

   for( int i = 0; i < AllDevices.size(); ++i )
     // machwas mit AllDevices[i]

Bei einem MFC CArray funktioniert das dann ähnlich
  for( int i = 0; i < AllDevices.GetSize(); ++i )
    // machwas mit AllDevices[i]

Es tut mir leid, aber du wirst nich umhin kommen, dich mit
Containern im Allgemeinen mal zu beschäftigen.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist es so schlimm, statt name17 name[17] zu schreiben? Mehr ist für
einen Array-Zugriff nicht zu tun. Und wenn das Ganze dynamisch sein
soll, weil die Anzahl der Elemente erst zur Laufzeit bekannt wird,
gibt es ja die von Karl heinz beschriebenen Container-Klassen, die den
dynamischen Speicherveraltungs-Hickhack komplett verstecken.

> Wird LISP überhaupt noch benutzt?

LISP ist die Mutter aller Programmiersprachen, d.h. was in irgendeiner
anderen Programmiersprache geht, geht auch in LISP, u.a. eben auch
dynamisch generierte Symbolnamen. Dass die Sprache heute zu den Exoten
zählt, liegt nicht an objektiven Mängeln der Sprache, sondern daran,
dass die Welt der Programmiersprachen stark von Modeerscheinungen
geprägt ist und die meisten Leute an einer Parenthesophobie zu leiden
scheinen ;-)

Heute wird LISP hautpsächlich zur Programmierung von Erweiterungen
komplexer Anwendungen benutzt (bspw. Scheme, Emacs LISP und AutoLISP),
es gibt aber durchaus Firmen, die auch heute noch mit eigenständigen
LISP-Systemen und -Anwendungen Geld verdienen. Hier ist eine kleine
Übersicht:

  http://www.pchristensen.com/blog/lisp-companies/

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab jetzt mal versucht kbucheggs (DANKE!!!) vorschlag 
umzusetzen, stehe aber immer noch vor dem gleichen Problem... Hier meine 
Schleife:
vector<struct device> deviceList;
struct device 
{
  int deviceEnumNumber;
  char deviceNumber;
  short deviceNoEndpoints;
};

int d = 0; 
do
{
  USBDevice->Open(d);
  device device0;
  deviceList.push_back(device0);
  device0.deviceEnumNumber = d;
  device0.deviceNumber = USBDevice->DeviceName[11];
  device0.deviceNoEndpoints = USBDevice->EndPointCount();
  d++;             
}
while (d < USBDevice->DeviceCount());

Es sollen nacheinander alle Devices geöffnet werden. Für jedes Device 
wird eine Struktur mit Konfigurationsdaten erstellt, diese Strukturen 
werden im vector deviceList abgelegt.
Mein Problem ist nun, dass in jedem Schleifendurchlauf wieder eine 
Struktur namens device0 erstellt wird. Und dieser Name müsste nun 
automatisch in jedem Durchlauf geändert werden...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel wrote:
> Also ich hab jetzt mal versucht kbucheggs (DANKE!!!) vorschlag
> umzusetzen, stehe aber immer noch vor dem gleichen Problem... Hier meine
> Schleife:
>

OK. Wir bewegen uns also im Bereich von Standard C++. Gut

> do
> {
>   USBDevice->Open(d);
>   device device0;
>   deviceList.push_back(device0);

Wieso fügst du hier bereits das Objekt zum Container hinzu.
Ich hab extra noch dazugeschrieben, dass sich der Container
eine Kopie(!) des übergebenen Objektes speichert. Eine
Kopie von einem Objekt welches keine gültigen Werte hat,
hat selbst keine gültigen Werte

> Mein Problem ist nun, dass in jedem Schleifendurchlauf wieder eine
> Struktur namens device0 erstellt wird.

Ja. Macht ja nichts.

> Und dieser Name müsste nun
> automatisch in jedem Durchlauf geändert werden...

Wozu?
Sobald du push_back machst, wird von deinem device0 Objekt
eine Kopie erzeugt und diese im Container gespeichert.

(Ich hab ins Beispiel auch noch eine String Klasse mit eingebaut.
 Nicht das du dann auch noch mit char-Arrays rummachst, denn das
 würde dann zu Ärger führen)

#include <stdio.h>
#include <vector>
#include <string>
#include <sstream>

struct Device
{
  int         Id;
  long        Vendor;
  std::string Name;
};

std::vector< Device > Devices;

int main()
{
  int i;

  //
  // container füllen
  //
  for( i = 0; i < 10; ++i ) {
    Device dev;

    dev.Id = i;
    dev.Vendor = i + 100;

    std::stringstream tmp;
    tmp << "USB-" << i;
    dev.Name = tmp.str();

    Devices.push_back( dev );
  }

  //
  // und abfragen
  //
  for( i = 0; i < Devices.size(); ++i ) {
    printf( "Device %s: %d - Vendor %d\n", Devices[i].Name.c_str(),
                                           Devices[i].Id,
                                           Devices[i].Vendor );
  }

  return 0;
}

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Karl Hein Vorschlag ist eigentlich der einfachst.
Das einzige was nun halt anderst ist also bei deiner durchnummernierung 
ist das du nun nicht mit device6 sondern mit device[6] zugreifst.
Aber das dürfte ja kein Problem darstellen

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jaaa, jetzt läufts. Bist ein Schatz, Karl Heinz ;-)

Danke auch an euch andere...

Gruß
Daniel

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> for( int i = 0; i < AllDevices.size(); ++i )

Damit das portabel ist, sollte i besser den Typ std::size_t bekommen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chris wrote:
>> for( int i = 0; i < AllDevices.size(); ++i )
>
> Damit das portabel ist, sollte i besser den Typ std::size_t bekommen.

Yep.
Damit es noch portabler ist, würde ich in realem Code auf
Iteratoren ausweichen, so wie sich die Macher der STL das vorgestellt
haben.
Allerdings: Ich wollte ihn nicht gleich am Anfang seiner Karriere
überfordern, auch wenn der Tip mit size_t ein guter ist.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.