Hallo
Ich habe eine Konstante zB
#define TRUNCATEARRAYFROMVALUE= 150 und ein Int Array mit 200 Elementen.
Jetzt möchte ich einfach die letzten 50 rubbish Werte wegschneiden.
Gibt es eigentlich eine Funktion, die das automatisch macht oder muss
ich das selbst mit einer for-Schleife in C erledigen?
Markus schrieb:> Jetzt möchte ich einfach die letzten 50 rubbish Werte wegschneiden.
Warum nicht einfach die Iteration auf 150 Arraywerte beschränken?
for(int i=0; i<TRUNCATEARRAYFROMVALUE; i++)
Und den Rest ignorieren.
Willst du dein Array verkleinern oder beim umkopieren nur die ersten 150
Werte beachten?
Du sagtest dein Datentyp wäre Int...also 32bit?
Falls du kopieren willst:
Ert schrieb:> Kann man das nicht mit nem Pointer lösen?
Klar geht auch, aber ich weiß jetzt nicht was er genau machen möchte.
Für Kopieren würde ich keine for-Schleife nehmen, ist langsamer als
memcpy...will er jedoch mit jedem Wert etwas machen und nur bis zum
150ten, dann kann er for-Schleife nehmen und mit Zeigern arbeiten:
Adam P. schrieb:> Willst du dein Array verkleinern oder beim umkopieren nur die> ersten 150> Werte beachten?>> Du sagtest dein Datentyp wäre Int...also 32bit?>> Falls du kopieren willst:> #include <string.h>>> #define TRUNCATEARRAYFROMVALUE 150>> /* Quelle */> int32_t src_array[200];> /* Ziel */> int32_t dst_array[TRUNCATEARRAYFROMVALUE];>> /* kopieren */> memcpy(dst_array, src_array, TRUNCATEARRAYFROMVALUE * sizeof(int32_t));
Danke, das habe ich gesucht
Adam P. schrieb:> Willst du dein Array verkleinern oder beim umkopieren nur die> ersten 150> Werte beachten?>> Du sagtest dein Datentyp wäre Int...also 32bit?>> Falls du kopieren willst:> #include <string.h>>> #define TRUNCATEARRAYFROMVALUE 150>> /* Quelle */> int32_t src_array[200];> /* Ziel */> int32_t dst_array[TRUNCATEARRAYFROMVALUE];>> /* kopieren */> memcpy(dst_array, src_array, TRUNCATEARRAYFROMVALUE * sizeof(int32_t));
Danke, das habe ich gesucht.
Würde das so auch funktionieren?
ICH würde das so nicht machen...
Das ist aber kein C sondern C++, stimmts?
Man sollte NIE aus einer Funktion einen Zeiger auf eine Variable
zurückgeben die nur lokal in der Funktion existiert!
Markus schrieb:> uint16_t dst_array[index];> pArray = dst_array;
Das ist dohc ein Zeiger auf eine lokale Variable, der nach dem Verlassen
der Funktion zerstört wird.
Also vorher Speicher dynamisch (auf dem Heap) allokieren.
Markus schrieb:> uint16_t my_array[index];> pArray = my_array;>> for(uint8_t i = 0; i < index; i++)> {> my_array[i] = array[i];> }>> return pArray;
Auch hier das Gleiche wie oben: Zeiger auf eine lokale Variable.
zitter_ned_aso schrieb:> Markus schrieb:>> uint16_t dst_array[index];>> pArray = dst_array;>> Das ist dohc ein Zeiger auf eine lokale Variable, der nach dem Verlassen> der Funktion zerstört wird.>> Also vorher Speicher dynamisch (auf dem Heap) allokieren.
Ja macht Sinn.
Das habe ich mir schon irgendwie gedacht, dass das so nicht
funktioniert, weil C die Variable in der Funktion im Stack ablegt und
nach der Funktion die Variable nicht mehr existiert. Ich bin eben im
Moment dabei, das Ganze zu lernen.
Adam P. schrieb:> ICH würde das so nicht machen...>> Das ist aber kein C sondern C++, stimmts?>> Man sollte NIE aus einer Funktion einen Zeiger auf eine Variable> zurückgeben die nur lokal in der Funktion existiert!
Mein Grundgedanke war eben den Ursprungsarray nicht zu überschreiben,
sondern eine Kopie davon in der Funktion zu nutzen.
Um die bearbeitete Kopie aber weiter zu verwenden, muss ich sie
zurückgeben können. Man kann ja nicht einfach ein Array zurückgeben.
zitter_ned_aso schrieb:> Adam P. schrieb:>> Ich versuch dir da mal kurz was...>
War nicht an dich gerichtet.
Hier so wie du dir wohl vorgestellt hast mal als ganzes, aber wie gesagt
es gibt viele wege ob nun mit 2 pointern als parameter, oder dann doch
mit new bzw. malloc, kommt immer auf den anwendungsfall drauf an.
Danke euch beiden
Mir gefällt das memcpy schon sehr gut, vor allem wenn es schnell geht.
Die 2. Variante mit dem Pointer hat mich interessiert.
Dazu habe ich aber eine Frage:
Wenn ich den Array im Heap ablege (dynamischer Speicher)
Den Array aber für eine Auswertung durch das Ganze programm benötige.
Wann gebe ich dann den Speicher wieder frei?
Da Arrays eine feste Größe haben, kann man sie nicht verkleinern - nur
umkopieren. Aber was gewinnst du damit, außer zeitweise doppelten
Speicherbedarf?
Wenn dein Array je nach Situation unterschiedlich viele Elemente
enthalten kann, brauchst du zusätzlich eine Variable für die
Längenangabe oder eine spezielle Ende-Markierung mit einem reservierten
Wert, der sonst niemals vorkommt, wie das bei Zeichenketten üblich ist.
Mit Ende-Markierung:
1
intarray[1000]={0};
2
3
voidappend_to_array(intvalue)
4
{
5
for(inti=0;i<999;i++)
6
{
7
if(array1[i]==0)// end marker found?
8
{
9
array[i]=value;
10
array[i+1]=0;
11
return;
12
}
13
}
14
printf("Fehler: Array ist schon voll");
15
}
16
17
voidread_maximum_100_values()
18
{
19
for(inti=0;i<100&&array[i]!=0;i++)
20
{
21
intvalue=array[i];
22
printf("wert=%i\n",value);
23
}
24
}
Mit Längenangabe:
1
intarray[1000];
2
intarray_length=0;
3
4
voidappend_to_array(intvalue)
5
{
6
if(array_length<1000)
7
{
8
array[array_length]=value;
9
array_length++;
10
}
11
else
12
{
13
printf("Fehler: Array ist schon voll");
14
}
15
}
16
17
voidread_maximum_100_values()
18
{
19
for(inti=0;i<100&&i<array_length;i++)
20
{
21
intvalue=array[i];
22
printf("wert=%i\n",value);
23
}
24
}
Die Verwerndung von sizeof(), strlen() und strcat() könnte hier nützlich
sein.
Markus schrieb:> Mein Grundgedanke war eben den Ursprungsarray nicht zu überschreiben,> sondern eine Kopie davon in der Funktion zu nutzen.
Dann übergib der Funktion schon eine Kopie vom Array.
Dirk B. schrieb:> Markus schrieb:>> Mein Grundgedanke war eben den Ursprungsarray nicht zu überschreiben,>> sondern eine Kopie davon in der Funktion zu nutzen.>> Dann übergib der Funktion schon eine Kopie vom Array.
Ich hätte noch einige Fragen zu den Kommentaren der anderen, aber vorweg
einmal:
Ein übergebener Array an eine Funktion zerfällt ja bekanntlich in einen
Zeiger. Wie meinst du das "übergib der Funktion die Kopie vom Array"
Geht das irgendwie direkt auch oder gibt es nur die Variante, den
src-array schon vorhor in eine andere arrayvariable zu speichern?
Markus schrieb:> Wie meinst du das "übergib der Funktion die Kopie vom Array"
Array halt vorher kopieren. Zeiger auf Kopie übergeben. Anders gehts
nicht.
Aber das ist meist der falsche Weg. Will man mit Teilen eines Arrays
arbeiten gibt man den Funktionen nicht nur das Array sondern einfach
Offset und Länge mit. Und die arbeiten dann nur auf diesem Teil.
Siehe z.B. solche Implementierungen von QuickSort.
Cyblord -. schrieb:> Markus schrieb:>> Wie meinst du das "übergib der Funktion die Kopie vom Array">> Array halt vorher kopieren. Zeiger auf Kopie übergeben. Anders gehts> nicht.>> Aber das ist meist der falsche Weg. Will man mit Teilen eines Arrays> arbeiten gibt man den Funktionen nicht nur das Array sondern einfach> Offset und Länge mit. Und die arbeiten dann nur auf diesem Teil.>> Siehe z.B. solche Implementierungen von QuickSort.
Danke Cyblord für den Tipp zugleich
Meine nächste Frage ist: was hat es mit new uint16_t[length] auf sich.
Was passiert da in der Zeile. Ich kenne das nur von Java, wenn man ein
neues Objekt erzeugt. Was passiert hier und warum macht man das?
Adam P. schrieb:> zitter_ned_aso schrieb:>> Adam P. schrieb:> {> uint16_t *dst = new uint16_t[length];>
Markus schrieb:> Meine nächste Frage ist: was hat es mit new uint16_t[length] auf sich.
Das ist C++ Syntax.
> Was passiert da in der Zeile. Ich kenne das nur von Java, wenn man ein> neues Objekt erzeugt. Was passiert hier und warum macht man das?
Was schon? Es wird ein neues Array erzeugt. In reinem C nimmt man dafür
malloc.
Cyblord -. schrieb:> Markus schrieb:>> Meine nächste Frage ist: was hat es mit new uint16_t[length] auf sich.>> Das ist C++ Syntax.
Also könnte ich das in reinem C gar nicht anwenden.
Ich frage mich dann wieso, das trotzdem als Lösung vorgeschlagen wurde,
denn ich hatte doch weiter oben C erwähnt. Oder ist das irgendwie
Kompatibel und Adam hat es bewusst so vorgeschlagen.
Die anderen Beiträge muss ich mir erst mal heute Abend noch durchlesen.
Bis dann
Markus schrieb:> Cyblord -. schrieb:>> Markus schrieb:>>> Meine nächste Frage ist: was hat es mit new uint16_t[length] auf sich.>>>> Das ist C++ Syntax.>>> Also könnte ich das in reinem C gar nicht anwenden.
Nein, aber es spielt doch keine Rolle WIE du nun einen neuen
Speicherbereich für ein neues Array allokierst.
DAS solltest du in deiner Sprache mindestens mal beherrschen. Ansonsten
würde ich vorschlagen du schaust dir die Grundlagen diesbezüglich erst
nochmal an.
Markus schrieb:> Ich frage mich dann wieso, das trotzdem als Lösung vorgeschlagen wurde,> denn ich hatte doch weiter oben C erwähnt.
Wer liest sich schon alle Beiträge und auch noch gründlich durch.
Da kommen dann Buzzwort-Antworten. (C++ ist besser, new statt malloc
(obwohl man das auch nicht mehr nimmt))
Cyblord -. schrieb:> Markus schrieb:>> Cyblord -. schrieb:>>> Markus schrieb:>>>> Meine nächste Frage ist: was hat es mit new uint16_t[length] auf sich.>>>>>> Das ist C++ Syntax.>>>>>> Also könnte ich das in reinem C gar nicht anwenden.>> Nein, aber es spielt doch keine Rolle WIE du nun einen neuen> Speicherbereich für ein neues Array allokierst.> DAS solltest du in deiner Sprache mindestens mal beherrschen. Ansonsten> würde ich vorschlagen du schaust dir die Grundlagen diesbezüglich erst> nochmal an.
Du hast Recht, ich versuche sowas gleich einmal umzusetzen.
Meinst du eigentlich konkret wie man dynamischen Speicher auf dem Heap
anfordert und wieder freigibt? Ich habe es eigentlich schon mal
durchgelesen, aber ich muss es dann einfach nochmals selber versuchen in
Form von einer eigenen, praktischen Umsetzung.
Erst dann sitzen die Dinge bei mir so richtig, leider... :( Beim Lesen
scheinen die Dinge immer erst so klar und beim Ausführen haperts dann
oftmals.
Ich danke euch aber trotzdem für die bisherige Hilfe.
Dirk B. schrieb:> Brauchst du denn noch die Originalwerte im Array oder kann das> überschrieben werden?
Nein, Dirk.
Wenn ich es mir so richtig überlege, bräuchte ich das alte Array dann
eigentlich nicht, weil ich ja die letzten Wert nie benötige. Das ist
unnötiger Speicherverbrauch, wenn es slso fast 2 identische Arrays
gibt..
Dann müsste ich einfach den Array der Funktion übergeben.
Die Elemente bis zu einem Index kopieren und den bestehenden Array mit
dem dst_array überschreiben. Richtig?
Noch ein Beispiel.
Wir haben ein Array mit etwas Text.
1
chartext[]="Stefan ist panne";
Wir wollen nur den Namen ausgeben, nicht den ganzen Text. In diesem Fall
kann ich damit Leben, wenn der Rest des Arrays verloren geht, also
terminiere ich den String einfach an der gewünschnten Stelle:
1
intposi=strchr(text,' ');
2
text[posi]=0;
Und den können wir jetzt an printf übergeben:
1
printf("Dein Name ist %s",name);
Umkopieren des Arrays war wieder nicht nötig.
Wenn ich den String (das Array) für spätere Verwendung nicht abschneiden
bzw modifizieren will, muss ich der Ausgabefunktion eine Längenangabe
mit geben:
1
intlen=strchr(text,' ');
2
printf("Dein Name ist ");
3
fwrite(text,len,1,stdout);
Dieses mal musste ich auf fwrite() ausweichen, weil ich bei printf()
keine Länge angeben kann.
Dirk B. schrieb:> Doch, geht:printf("Dein Name ist %.*s", len, name);
Oh cool, das kannte ich noch nicht.
Kleine Korrektur:
printf("Dein Name ist %s",name);
printf("Dein Name ist %.*s", len, name);
Da gehört die Variable "text" hin, nicht "name".