Forum: Mikrocontroller und Digitale Elektronik Programmiergrundlagen: array=array?


von Dulfried W. (dulfried)


Lesenswert?

Hallo Leute,
1
char array1[16];
2
char array2[16];
3
4
array1[0] = array2[0];
5
array1[1] = array2[1];
6
array1[2] = array2[2];
7
array1[3] = array2[3];
8
array1[4] = array2[4];
9
array1[5] = array2[5];
10
array1[6] = array2[6];
11
array1[7] = array2[7];
12
array1[8] = array2[8];
13
array1[9] = array2[9];
14
array1[10] = array2[10];
15
array1[11] = array2[11];
16
array1[12] = array2[12];
17
array1[13] = array2[13];
18
array1[14] = array2[14];
19
array1[15] = array2[15];

Wie mache ich das ganze in einem Befehl?

Und wie kann ich alle Werte von array1 auf 0 setzen?

von Cler (Gast)


Lesenswert?

memcpy

von Michael (Gast)


Lesenswert?

Kopieren: memcpy (siehe Vorredner)
Nullen: memset

von Dulfried W. (dulfried)


Lesenswert?

Diese Funktionen habe ich gesucht - Danke

von bla (Gast)


Lesenswert?

Oder die klassiche for-Schleife. Poor man's memcpy.

von Axel S. (a-za-z0-9)


Lesenswert?

bla schrieb:
> Oder die klassiche for-Schleife. Poor man's memcpy.

Compiler können das mittlerweile auch ganz gut optimieren.

von Cyblord -. (cyblord)


Lesenswert?

bla schrieb:
> Oder die klassiche for-Schleife. Poor man's memcpy.

Wobei memcpy auf den meisten RISC Architekturen auch einfach als Scheife 
umgesetzt ist. Wie auch sonst?

von Pandur S. (jetztnicht)


Lesenswert?

> Wobei memcpy auf den meisten RISC Architekturen auch einfach als Scheife
umgesetzt ist. Wie auch sonst?

Naja. Eine CPU kann das von selbst, ohne Schleife.

von Adam P. (adamap)


Lesenswert?

Da jetzt der Vergleich zwischen for() und memcpy() angesprochen wurde:

Axel S. schrieb:
> Compiler können das mittlerweile auch ganz gut optimieren.

Betrifft evtl. nur memcpy? (siehe weiter unten)

Cyblord -. schrieb:
> Wobei memcpy auf den meisten RISC Architekturen auch einfach als Scheife
> umgesetzt ist. Wie auch sonst?

Bei ARM Cortex-M4 mit gcc scheint es jedoch bei der strchr() ein 
Unterschied zu geben.

Gestern habe ich einige Funktionen bei mir optimiert und mal einen Test 
durchgeführt:

"Suche ein Zeichen im String und breche dann die weitere Suche ab"

1 Version: for-Schleife
2 Version: strchr()

Kompiliert wurde im Release Modus mit (-O1), (-O3) sowie (-Os).

Ergebnis: for-Variante war immer um den Faktor 1,5 bis 3 langsamer.

Da neige ich dann doch eher dazu, Funktionen zu nutzen, falls es sie 
bereits gibt und es nicht selbst neu zu programmieren.

von Walter K. (Gast)


Lesenswert?

string.h ?

von Dussel (Gast)


Lesenswert?

Adam P. schrieb:
> Da neige ich dann doch eher dazu, Funktionen zu nutzen, falls es sie
> bereits gibt und es nicht selbst neu zu programmieren.
Ich neige eher dazu, sowas selber zu programmieren, weil ich so alles 
kontrollieren kann oder zumindest das Gefühl habe.
Allerdings muss man realistisch doch sagen, dass die, die 
Standardfunktionen schreiben sich wahrscheinlich besser mit der 
Architektur und dem Compiler auskennen und sich mehr Gedanken gemacht 
haben als jemand, der während der Programmierung mal auf so ein Problem 
stößt.

von Adam P. (adamap)


Lesenswert?

Walter K. schrieb:
> string.h ?

ja

von Dr. Sommer (Gast)


Lesenswert?

Zitronen F. schrieb:
>> Wobei memcpy auf den meisten RISC Architekturen auch einfach als
> Scheife
> umgesetzt ist. Wie auch sonst?
>
> Naja. Eine CPU kann das von selbst, ohne Schleife.

So ist es (Cortex-M, braucht 4-Byte-Alignment):
1
void copy16 (char* dest, const char* src) {
2
  unsigned int dummy [4];
3
  asm volatile ("ldm %[src], {%[r0], %[r1], %[r2], %[r3]}\n"
4
     "stm %[dest], {%[r0], %[r1], %[r2], %[r3]}\n" : [r0] "=&r" (dummy [0]), [r1] "=&r" (dummy [1]), [r2] "=&r" (dummy [2]), [r3] "=&r" (dummy [3]) : [src] "r" (src), [dest] "r" (dest) : "memory");
5
}
Oder wie wäre es damit:
1
std::array<char, 16> array2, array1;
2
array1 = array2;
Oder:
1
std::vector<char> array2 (16), array1;
2
array1 = array2;

von Dulfried W. (dulfried)


Lesenswert?

Wäre gut, wenn ihr mir nochmal helfen könntet.

Wie überprüfe ich, ob in einem String eine Newline (\n) vorhanden ist?
1
strchr(array, '\n');

So geht das nicht, da \n kein char ist

von Dr. Sommer (Gast)


Lesenswert?

Dulfried W. schrieb:
> So geht das nicht, da \n kein char ist

Es geht trotzdem genau so. In C ist '\n' zwar ein int, passt aber in den 
Wertebereich von char. In C++ ist es ein char. strchr() nimmt einen 
"int", sodass hier auch keine Compiler-Warnung kommt.

von Harry L. (mysth)


Lesenswert?

Dr. Sommer schrieb:
> In C ist '\n' zwar ein int

Blödsinn!

von Dr. Sommer (Gast)


Lesenswert?

Harry L. schrieb:
> Blödsinn!

Danke für diesen qualifizierten und wohlbegründeten Beitrag.

http://en.cppreference.com/w/c/language/character_constant
1
1) single-byte integer character constant, e.g. 'a' or '\n' or '\13'. Such constant has type int and a value equal to the representation of c-char in the execution character set as a value of type char mapped to int.

von Harry L. (mysth)


Lesenswert?

Es geht aber nicht um um CPP und in C ist auch eine Escape-Sequence ein 
char.

von Dr. Sommer (Gast)


Lesenswert?

Harry L. schrieb:
> Es geht aber nicht um um CPP und in C ist auch ein
> Escape-Character ein
> char.

Leseverständnis nicht vorhanden? Mein Beitrag bezieht sich auf C. Der 
Link verweist auf die C-Dokumentation. Der C-Präprozessor "CPP" kennt 
kein "char" oder "int". In C++ sind Literale der Form 'x' char, in C 
sind alle Literale der Form 'x' oder '\n' int, egal ob escaped oder 
nicht.

von Harry L. (mysth)


Lesenswert?

Zitat 1. Absatz der von dir verlinkten Seite:
1
c-char is either
2
a character from the basic source character set minus single-quote ('), backslash (\), or the newline character.
3
escape sequence: one of special character escapes \' \" \? \\ \a \b \f \n \r \t \v, hex escapes \x... or octal escapes \... as defined in escape sequences.

von Dr. Sommer (Gast)


Lesenswert?

Na und? Der Typ ist trotzdem int.
https://stackoverflow.com/questions/433895
https://www.geeksforgeeks.org/g-fact-54/
Wenn du das aber niemandem glauben willst, probier's einfach aus:
1
printf("%z\n", sizeof('x'));
 gibt typischerweise 2 oder 4 aus, weil 'x' ein int ist.

von Dr. Sommer (Gast)


Lesenswert?

PS: Ich meinte natürlich %zu, also
1
printf("%zu\n", sizeof('x'));
Siehe z.B.
https://ideone.com/2WnWd6

von Adam P. (adamap)


Lesenswert?

Dulfried W. schrieb:
> strchr(array, '\n');
>
> So geht das nicht, da \n kein char ist

Warum soll das nicht gehen:

Einfacher Test:
1
#include <stdio.h>
2
#include <string.h>
3
4
int main(void) {
5
  char buf[10] = "Hallo\n";
6
  
7
  char *ptr_base;
8
  char *ptr_find;
9
  
10
  ptr_base = buf;
11
  ptr_find = strchr(ptr_base, '\n');
12
  
13
  printf("ptr_base = 0x%08X\n", ptr_base);
14
  printf("ptr_find = 0x%08X\n", ptr_find);
15
  
16
  // your code goes here
17
  return 0;
18
}

Ergibt folgende Ausgabe:
1
ptr_base = 0x2A8A7D60
2
ptr_find = 0x2A8A7D65

Somit stimmt die Differenz der Adresse.

siehe auch: https://ideone.com/NBT5JY

von Dr. Sommer (Gast)


Lesenswert?

Adam P. schrieb:
> printf("ptr_base = 0x%08X\n", ptr_base);
>   printf("ptr_find = 0x%08X\n", ptr_find);

Pointer gibt man mit %p aus. Auf 64bit-Plattformen fehlen sonst 8 
Ziffern...

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Statische Arrays mit denselben Datentypen und gleicher Länge.

in Pascal würde array2:=array1; reichen

Geht das in C(++/#) nicht?

von Dr. Sommer (Gast)


Lesenswert?

Mike B. schrieb:
> Geht das in C(++/#) nicht?
C kann sehr vieles nicht, dennoch bestehen mysteriöserweise viele Leute 
partout immer noch darauf. In C++ geht's:

Dr. Sommer schrieb:

Dr. Sommer schrieb:
> std::array<char, 16> array2, array1;
> array1 = array2;
> Oder:
> std::vector<char> array2 (16), array1;
> array1 = array2;

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:

> Dr. Sommer schrieb:
>> std::array<char, 16> array2, array1;
>> array1 = array2;
>> Oder:
>> std::vector<char> array2 (16), array1;
>> array1 = array2;

überlesen, sorry.

von Adam P. (adamap)


Lesenswert?

Dr. Sommer schrieb:
> Pointer gibt man mit %p aus. Auf 64bit-Plattformen fehlen sonst 8
> Ziffern...

Danke für die Info,
jedoch bin ich davon ausgegangen dass es sich z.B. um ein maximal 32-bit 
Mikrocontroller handelt.

OK, um den Source portabel zu halten, ist %p natürlich optimal -
ich habe es immer Anwendungsfall bezogen mit 0x%02X, 0x%04X oder 0x%08X 
gelöst (natürlich nicht auf die Adressen bezogen, das ginge ja so auch 
nicht), aber da ich wusste, ok, ich hab ein 32bit system, also brauch 
ich 0x%08X - ja, umständlich, nu wurde ich eines besseren belehrt ;)

Aber man lernt ja nie aus...zum glück :)

edit:
Gibt es überhaupt 64-bit µC?

von Hunsbuckel (Gast)


Lesenswert?

Adam P. schrieb:

> OK, um den Source portabel zu halten, ist %p natürlich optimal

%p ist nicht nur optimal - sondern eher zwingend

Denn manchmal ist sogar:

sizeof(int*) != sizeof(char*)

von Adam P. (adamap)


Lesenswert?

Hunsbuckel schrieb:
> Denn manchmal ist sogar:
>
> sizeof(int*) != sizeof(char*)

Das leuchtet mir jetzt aber irgendwie nicht ein...

Wenn ich ein 32-bit Adressraum habe,
in diesem kann ich char sowie int ablegen -

Wenn sizeof(char*) nun 2 wäre...dann wären ja alle adressen oberhalb 
dieser grenze gar nicht möglich.

Wo gibt es denn diesen Fall?

Oder ich versteh nicht ganz was du meinst...

"sizeof(int*) != sizeof(char*)"

Soll dies nu bedeuten, dass ein Zeiger auf "int" ungleich einem Zeiger 
auf "char" sein kann, sprich in der Größe des Zeigers?

Ein Zeiger beinhaltet doch die Adresse auf die er zeigt...

von Hunsbuckel (Gast)


Lesenswert?

„...Soll dies nu bedeuten, dass ein Zeiger auf "int" ungleich einem 
Zeiger auf "char" sein kann, sprich in der Größe des Zeigers?..“

Selbstverständlich können die unterschiedlich groß sein!

Auch in der PC Welt gab es schon mal schräge Memory-Modelle mit Offsets 
usw.

von Rolf M. (rmagnus)


Lesenswert?

Adam P. schrieb:
> Soll dies nu bedeuten, dass ein Zeiger auf "int" ungleich einem Zeiger
> auf "char" sein kann, sprich in der Größe des Zeigers?

Genau. Für Beispiele, siehe die FAQ von comp.lang.c: 
http://c-faq.com/null/machexamp.html

von Wilhelm M. (wimalopaan)


Lesenswert?

Leider sieht die Sprache C(99) oft nur einfach aus: manche Annahmen, die 
man aus ihrer Einfachheit ableiten mag, sind einfach falsch. Leider.

In diesem Thread sind zwei "schöne" Beispiele genannt worden (Typ von 
character-constants und sizeof(<pointer>)). Man könnte weiter machen mit 
_Bool ...

Daher rate ich jedem C-Programmierer, sich mal die C-FAQ anzusehen:

http://c-faq.com/charstring/sizeofchar.html

http://c-faq.com/ptrs/generic.html

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> In diesem Thread sind zwei "schöne" Beispiele genannt worden (Typ von
> character-constants und sizeof(<pointer>)). Man könnte weiter machen mit
> _Bool ...

Diese Sachen finde ich verständlich, wenn man sie sich mal angesehen 
hat. Wirklich bizarr ist es bei Funktionen wie z.B. toupper. Das bekommt 
auch einen int für das zu konvertierende Zeichen übergeben. Aber man 
darf nicht einfach sein Zeichen übergeben, denn der erlaubte 
Wertebereich ist der von unsigned char und EOF. Jeder andere Wert ergibt 
undefiniertes Verhalten. Wenn man also eine Plattform hat, auf der char 
signed ist, muss sichgergestellt sein, dass das erstmal nach unsigned 
char gecastet wird.

Also falsch:
1
int c = getchar();
2
int C = toupper(c);

Richtig:
1
int c = getchar();
2
int C;
3
if (c != EOF)
4
    C = toupper((unsigned char)c);
5
else 
6
    C = EOF;

Obwohl c ein int ist und toupper auch einen int erwartet, muss erst noch 
nach unsigned char gecastet werden. Und dann muss EOF auch separat 
behandelt werden, obwohl toupper es auch behandelt. Es geht aber durch 
den Cast nach unsigned char verloren.

von Walter K. (Gast)


Lesenswert?

Rolf M. schrieb:
> Wenn man also eine Plattform hat, auf der char
> signed ist

In C ist char immer signed
(solange Du nicht explizit sagst, dass die Char-Variable vorzeichenlos 
sei soll)
- das hat nix mit der Plattform zu tun

von Walter K. (Gast)


Lesenswert?

Rolf M. schrieb:
>....
> Es geht aber durch
> den Cast nach unsigned char verloren.

Das ist alles Unfug!

von Rolf M. (rmagnus)


Lesenswert?

Walter K. schrieb:
> Rolf M. schrieb:
>> Wenn man also eine Plattform hat, auf der char
>> signed ist
>
> In C ist char immer signed

Nein, ist es nicht.

> - das hat nix mit der Plattform zu tun

Die signedness von char ist in C implementation-defined.

Walter K. schrieb:
> Rolf M. schrieb:
>>....
>> Es geht aber durch
>> den Cast nach unsigned char verloren.
>
> Das ist alles Unfug!

Lies doch bitte in ISO C nach, bevor du hier losplärrst. Dein Halbwissen 
reicht nicht, um da mitdiskutieren zu können.

Beitrag #5367834 wurde von einem Moderator gelöscht.
von mh (Gast)


Lesenswert?

Walter K. schrieb im Beitrag #5367834:
> Habe ich was von ISO C geschrieben?

Auf welche Programmiersprache, die wie C aussieht, aber nicht ISO C ist, 
beziehen sich denn deine Posts? Falls du es nicht mitbekommen hast, alle 
anderen Teilnehmer hier im Thread gehen von ISO C aus.

von Walter K. (Gast)


Lesenswert?


von Rolf M. (rmagnus)


Lesenswert?

Walter K. schrieb im Beitrag #5367834:
> Habe ich was von ISO C geschrieben?

ISO C ist für mich C (es mag nicht die einzige Form von C sein, aber 
gehört auf jeden Fall zur Obermenge "C"), und damit ist diese Aussage:

Walter K. schrieb:
> In C ist char immer signed

schlicht und ergreifend falsch. Was du stattdessen mit "C" meinst, 
solltest du dann schon erwähnen.

Walter K. schrieb:
> 
https://www.google.de/imgres?imgurl=http://t3.gstatic.com/images?q%3Dtbn:ANd9GcQMn9tdlkggvV7yp5v97Bq3LLclq1fE_2LJE_LNAwSA5ZpAg_wd&imgrefurl=https://books.google.com/books/about/C_Programming_Language.html?id%3DYi5FI5QcdmYC%26source%3Dkp_cover&h=792&w=600&tbnid=N7ch4N5cTW2EZM:&tbnh=160&tbnw=120&usg=__e3o2AGs4JF2grEEWtxm718mK7kY%3D&vet=10ahUKEwj7v-O3vY7aAhXCDpoKHT6RAMQQ_B0IqwEwCg..i&docid=0UqNku-PooUQ0M&itg=1&client=safari&sa=X&ved=0ahUKEwj7v-O3vY7aAhXCDpoKHT6RAMQQ_B0IqwEwCg

Und, hast du das auch gelesen, oder nur das Cover angeschaut? Meine 
Aussagen sind nämlich auch für das (schon lange veraltete) ANSI C 
gültig.

von Walter K. (Gast)


Lesenswert?

Rolf M. schrieb:
> schlicht und ergreifend falsch. Was du stattdessen mit "C" meinst,
> solltest du dann schon erwähnen.

ja o.k. ...

(war nicht so gemeint, das mit Kaffee etc. ..sorry )

von Walter K. (Gast)


Lesenswert?

Rolf M. schrieb:
> Und, hast du das auch gelesen, oder nur das Cover angeschaut? Meine
> Aussagen sind nämlich auch für das (schon lange veraltete) ANSI C
> gültig.

das stimmt jetzt nicht, denn char ist signed! ..auch wenn Dir das nicht 
gefällt

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Wilhelm M. schrieb:
>> In diesem Thread sind zwei "schöne" Beispiele genannt worden (Typ von
>> character-constants und sizeof(<pointer>)). Man könnte weiter machen mit
>> _Bool ...
>
> Diese Sachen finde ich verständlich, wenn man sie sich mal angesehen
> hat.

Ja, wenn man sie sich angesehen hat ...

Beitrag #5367859 wurde von einem Moderator gelöscht.
von Wilhelm M. (wimalopaan)


Lesenswert?

Walter K. schrieb:
> Rolf M. schrieb:
>> Und, hast du das auch gelesen, oder nur das Cover angeschaut? Meine
>> Aussagen sind nämlich auch für das (schon lange veraltete) ANSI C
>> gültig.
>
> das stimmt jetzt nicht, denn char ist signed! ..auch wenn Dir das nicht
> gefällt

Schau doch mal tatsächlich nach, bevor du so etwas Falsches behauptest:

C11: 6.2.5/15

"The three types char, signed char, and unsigned char are collectively 
called
the character types. The implementation shall define char to have the 
same range,
representation, and behavior as either signed char or unsigned char."

von mh (Gast)


Lesenswert?

Walter K. schrieb:
> https://www.google.de/imgres?imgurl=http://t3.gsta...

Also meinst du ANSI-C Ok.

Nimm das Buch, dessen Cover du verlinkt hast, und schlage nach in 
Kapitel 2.2 "Data Types and Sizes" (in meiner Version Seite 36):
1
Whether plain chars are signed or unsigned is machine-dependent, but printable characters are always positive.

von Walter K. (Gast)


Lesenswert?

mh schrieb:
> Walter K. schrieb:
>> https://www.google.de/imgres?imgurl=http://t3.gsta...
>
> Also meinst du ANSI-C Ok.
>
> Nimm das Buch, dessen Cover du verlinkt hast, und schlage nach in
> Kapitel 2.2 "Data Types and Sizes" (in meiner Version Seite 36):
>
>
1
Whether plain chars are signed or unsigned is machine-dependent, 
2
> but printable characters are always positive.

Und wo steht da nun, dass char nicht signed ist?

'.. but printable characters are always positive.'

vom typ char kann ja mehr als 'printable chracters' sein

von Walter K. (Gast)


Lesenswert?

mh schrieb:
> Walter K. schrieb:
>> https://www.google.de/imgres?imgurl=http://t3.gsta...
>
> Also meinst du ANSI-C Ok.
>
> Nimm das Buch, dessen Cover du verlinkt hast, und schlage nach in
> Kapitel 2.2 "Data Types and Sizes" (in meiner Version Seite 36):
>
>
1
Whether plain chars are signed or unsigned is machine-dependent, 
2
> but printable characters are always positive.

Und wo steht da nun, dass char unsigned ist?

von Walter (Gast)


Lesenswert?

Walter K. schrieb:
> Und wo steht da nun, dass char nicht signed ist?

Walter K. schrieb:
> Whether plain chars are signed or unsigned is machine-dependent,

von A. S. (Gast)


Lesenswert?

Walter K. schrieb:
> Und wo steht da nun, dass char nicht signed ist?

nirgends. Das wäre genauso falsch wie:

Walter K. schrieb:
> In C ist char immer signed

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Walter K. schrieb
> Und wo steht da nun, dass char unsigned ist?

https://m.youtube.com/watch?v=ubKinQvpc6w

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf M. schrieb:
> Also falsch:
> int c = getchar();
> int C = toupper(c);
>
> Richtig:int c = getchar();
> int C;
> if (c != EOF)
>     C = toupper((unsigned char)c);
> else
>     C = EOF;

Auch das erste Beispiel ist korrekt und liefert exakt dassselbe Ergebnis
wie das zweite Beispiel, da getchar() alle Zeichen (einschließlich EOF)
in der Darstellung liefert, wie toupper() sie erwartet.

Die Casterei ist nur dann notwendig, wenn das Zeichen als (signed-)
char-Variable vorliegt.

von Rolf M. (rmagnus)


Lesenswert?

Yalu X. schrieb:
> Auch das erste Beispiel ist korrekt und liefert exakt dassselbe Ergebnis
> wie das zweite Beispiel, da getchar() alle Zeichen (einschließlich EOF)
> in der Darstellung liefert, wie toupper() sie erwartet.

Da hast du recht. Ich hatte getchar() nur verwendet, um irgendwoher das 
Zeichen zu bekommen und gar nicht darauf geachtet, dass das auch schon 
diese Repräsentation nutzt.

> Die Casterei ist nur dann notwendig, wenn das Zeichen als (signed-)
> char-Variable vorliegt.

Also wäre es so falsch:
1
    char c = getchar();
2
    char C = toupper(c);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.