Gibt es nun eine schnelle Methode wie ich diese Struct-Arrays (a,b,c)
mit einer einfachen Zuweisung mit den Werten der globalen Arrays
(aa,bb,cc) befüllen kann? Bisher kenne ich nur den "Umweg" über eine
Schleife, in der Form:
1
for(inti=0;i<20;i++)
2
{
3
ram.a[i]=aa[i];
4
ram.b[i]=bb[i];
5
ram.c[i]=cc[i];
6
}
Das funktioniert zwar... aber geht es auch ohne diese Schleife? Habe es
auch mit memcpy probiert, aber das funktioniert bei der
struct-Initialisierung leider nicht. Wer hat eine Idee?
Sebastian Seppel schrieb:> Das funktioniert zwar... aber geht es auch ohne diese Schleife?
Nein, selbst memcpy ist ja als Schleife realisiert, irgendwann musst du
die Speicherstellen halt ansprechen.
Würde mir aber jetzt nicht wirklich Gedanken machen drüber, wie oft
initialiserst du die Arrays schon?
:-)
Entschuldigt bitte den Schreibfehler in der Überschrift, kanns leider
nicht mehr ändern: "sruct" = "struct"
strncpy(ram.a,aa,20) geht leider auch nicht. Das Problem ist dabei, dass
ich ein c-File mit Parametern angelegt habe, welche ich global verwenden
möchte. In diesem c-File gibt es bisher nur Variablen, zum
initialisieren mit "strncpy" oder "memcpy" müsste ich eine Funktion
drumrum bauen.. eine Init-Routine wenn man so will. Das möchte ich aber
nicht.
Sebastian Seppel schrieb:> Das funktioniert zwar... aber geht es auch ohne diese Schleife? Habe es> auch mit memcpy probiert, aber das funktioniert bei der> struct-Initialisierung leider nicht. Wer hat eine Idee?
Hi, weiss zwar nicht genau was du uns mit diesem Satz sagen willst, aber
mit memcpy geht das sicherlich :
ram_var* ram;
memcpy(ram->a, aa, sizeof(aa));
@ Floh
stimmt schon, man initialisiert nur einmal :) Aber hab halt eine große
struct von etwa 250 Bytes mit 10 verschieden großen Arrays drin... drum
frug ich mich grad obs einfacher geht ;)
Du kannst ja die aa,bb,cc Arrays nur einmal halten und die structs mit
Zeigern darauf initialisieren. Die Zugriffsfunktionen musst Du natürlich
entsprechend ändern.
>Aber gehts auch ohne eine solche Init-Funktion?
Der Punkt ist doch, dass Du willst das ein bestimmer Speicherbereich (in
der Struktur) Daten enthält, die Du in einem anderen Speicherbereich
vorhälst.
Es gibt keinen anderen Weg, als die Daten entweder dorthin zu kopieren
oder die Struktur nochmal unter ausdrücklicher Nennung der Elemente zu
initialisieren.
Das Problem könnte sicherlich durch entsprechende Sprachmittel anders
gelöst werden aber C hat solche Sprachmittel nicht und würde, wenn doch,
nicht darum herumkommen die Daten, ohne das Du das ausdrücklich
schreibst, doch zu kopieren.
Ich verstehe vielleicht das Grundproblem nicht, aber warum das hier
>müsste ich eine Funktion drumrum bauen.. eine Init-Routine wenn man so >will. Das
möchte ich aber nicht.
und das hier
>Aber gehts auch ohne eine solche Init-Funktion?
nun zwingend notwendig ist, hast Du bisher leider nicht geschrieben.
@Huch
Nun muss ich doch weiter ausholen.. Zeiger kann ich leider nicht nehmen.
Meine (aa,bb,cc) sind (nicht wie oben im einfachen Beispiel) Konstanten.
Im Beispiel heißt das:
memcpy(ram.a,(unsignedchar)aa,sizeof(aa)),//NICHT ok
16
...
17
}
Die "@" sind dafür da, damit die Konstanten in die dahinter angegebenen
Speicherbereiche geschrieben werden. Sie sollen im Flashspeicher stehen,
daher müssen es Konstanten sein. Wenn ich das selbe mit Variablen mache,
kommen Fehler, da diese nicht im FLASH Bereich alloziert werden können.
Sebastian Seppel schrieb:> Wenn ich das selbe mit Variablen mache,> kommen Fehler, da diese nicht im FLASH Bereich alloziert werden können.
klar, da meckert der Compiler zu Recht. memcpy wird ja zur Laufzeit
ausgeführt, nur kann er dann nicht mehr in den Flash schreiben.
Bei "test" funktioniert das, da der Wert bereits zur Compilezeit
vorliegt und deshalb beim Programmieren durch den Zahlenwert ersetzt
werden kann.
:-)
Aha. Das hättest Du von Anfang an schreiben sollen.
Du kannst durchaus in Strukturen auch Zeiger auf Vektoren im FLASH
speichern. Dabei ist es egal, ob die Struktur selbst im RAM oder im
FLASH liegt.
Nur musst Du eben, wie oben schon bemerkt, die Zugriffsfunktionen
entsprechend schreiben.
memcpy(ram.a,(unsignedchar)aa,sizeof(aa)),//NICHT ok
6
...
7
}
Erlaube mir, Dich höflich darauf hinzuweisen, das Du ein C Buch lesen
solltest. Du wirst sehen, das in solchen Initialisierungen
Funktionsaufrufe nicht erlaubt sind. Es sind nur solche Ausdrücke
möglich, die zur Kompilierzeit zu einer Konstanten auswertbar sind.
Du solltest vielleicht auch mal schreiben, auf welcher Hardware das
Programm laufen soll und welchen Compiler Du benutzt. Du bist hier im
Unterforum PC-Programmierung. Das ist im Zusammenhang mit Flash-Speicher
sehr wahrscheinlich ein Widerspruch.
Sebastian Seppel schrieb:> Die "@" sind dafür da, damit die Konstanten in die dahinter angegebenen> Speicherbereiche geschrieben werden.
Warum müssen deine Konstanten denn an einer ganz bestimmten Adresse
stehen, und warum kannst du deine ram_var nicht direkt mit den
gewünschten Werten initialisieren?
Also:
Ich programmiere einen CAN-Bootloader für einen Freescale HCS08
Controller. Dazu nutze ich die IDE von Freescale (Codewarrior) mit
integrierten Compiler.
Ich habe diesen Thread in das PC-Programmierungsforum geschrieben, da
mein Problem ein reines "C" Problem ist. Mir kam halt die Frage auf, ob
es möglich ist ein Array in einer struct mit einem zweiten Array direkt
in dieser Initialisierungsliste zu initialisieren, ohne eine Funktion
oder Schleife aufrufen zu müssen. In dieser Art u Weise:
1
structram_varram@0x300=
2
{
3
0x60,//ok, mit hex Werten
4
200,//ok, mit dec Werten
5
test,//ok, mit Variablen
6
memcpy(&ram.a,(unsignedchar)aa,sizeof(aa)),//NICHT ok, da Array
7
...
8
}
Aber das klappt leider nicht. Habe jetzt die einzelnen Arraywerte
übergeben, nach dem Schema:
1
structram_varram@0x300=
2
{
3
...
4
a[0]=aa[0],
5
a[1]=aa[1],
6
...
7
}
Nicht gerade schön, aber selten :)
Mit memcpy, memset, strncpy, if/for-Schleifen funktionierts wirklich nur
innerhalb einer Funktion.
Bsp.:
Und eben diese Funktion möchte ich nicht einbringen, da es sich um eine
reine Parameter-File handeln soll.
Danke euch dennoch für eure Hilfe, man lernt ja nie aus.
> Ich habe diesen Thread in das PC-Programmierungsforum geschrieben, da> mein Problem ein reines "C" Problem ist.
Und? Was haben "reine C-Probleme" mit PC-Programmierung zu tun?
@ Klaus Wachtler
Genau diese Einzelinitialisierung habe ich jetzt auch genommen. Ist halt
mühselig bei vielen, großen Arrays. Hatte die Hoffnung dass es noch eine
weitere Methode (außer die oben genannten) gibt, die ich noch nicht
kenne. Aber gut, es gibt ja 3-4 verschiedene Möglichkeiten. C kann ja
nix dafür, dass ich so sturköpfig bin und keine Funktion einbinden
möchte :) Danke euch allen.
Sebastian Seppel schrieb:> @ Klaus Wachtler> Genau diese Einzelinitialisierung habe ich jetzt auch genommen. Ist halt> mühselig bei vielen, großen Arrays. Hatte die Hoffnung dass es noch eine> weitere Methode (außer die oben genannten) gibt, die ich noch nicht> kenne. Aber gut, es gibt ja 3-4 verschiedene Möglichkeiten. C kann ja> nix dafür, dass ich so sturköpfig bin und keine Funktion einbinden> möchte :) Danke euch allen.
Es gibt noch eine Möglichkeit. Gar nicht mal so trickreich, wenn man
erst mal den Brechreiz überwunden hat :-)
file: dataA.inc
**************
1
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
file: irgendwas.h oder .c
*************************
Oder alternativ statt je eines Include ein #define mit der Liste?
Dann wird nicht das zweite Feld mit dem ersten initialisiert,
sondern beide aus dem Makro.
Ich fürchte allerdings, daß der Compiler nicht merkt, daß die beiden
gleich sind und sie doppelt im Image hält (was für die include-Lösung
auch gilt).
Achja: Weshalb ich diesen Thread in PC-Programmierung eröffnete:
Zitat Forenliste:
"PC-Programmierung - Programmierung auf PCs, allgemeineProgrammierfragen, ohne direkten Mikrocontrollerbezug."
Da es sich um eine allgemeine Programmierfrage zu C handelt, dachte ich
passt es am besten darein. Sorry falls das falsch war.
Keine Zeiger -> Weil es ein Zeiger auf den FLASH Bereich werden würde,
allerdings darf ich zur Laufzeit nicht in den FLASH schreiben. Somit
muss ich sie erst einmal in den RAM schreiben und anschließend spezielle
Routinen aufrufen die diesen RAM-Wert in den FLASH schreiben. Ich muss
also immer den Umweg nehmen: Kopiere RAM in FLASH.