Forum: PC-Programmierung c code Unterschied uint8 buffer [8] und char buffer[8]


von c schüler (Gast)


Lesenswert?

Móin,

kann mir jemand sagen was die Unterschiede sind und wann man welche 
szenarien verwendet:

1
//a: warum ist der Stern am Datentyp und wann macht man das so
2
void machwas (uint8* buffer) {
3
}
4
5
//b: 
6
void machwas (uint8 *buffer) {
7
}
8
9
//c:
10
void machwas (char* buffer) {
11
}
12
13
//d:
14
void machwas (char *buffer) {
15
}
16
17
// und warum gibt es so eine Schreibweise?
18
// ein array (container) für bytes? oder strings?
19
//e:
20
void machwas (uint8 buffer[] ) {
21
}
22
23
//ein array (container) für reinen String?
24
//oder ist das eine Stringliste,
25
// mich irretiert einmal schreibt man einen reinen String ohne
26
// array und einmal mit, wie ist es denn richtig?
27
//f:
28
void machwas (char buffer[] ) {
29
}

Ist es nicht so, dass unsigned char und uint8 das gleiche sind
was sind dann reine char datentypen, reichen die von 0 bis 255
oder nur 0 bis 127 oder hat das gar nichts damit zu tun.

Ich stolpere meistens wenn es um Bytes und Strings geht,
mein Base ist:

eine Zahl ist ein Integer
mehrer Zahlen sind eine Integer Folge
entweder in Reihe 'string' oder parallel 'array'

ein Buchstabe ist ein char
mehrere Buchstaben ein char Folge
entweder in Reihe 'string' oder parallel 'array'

Ein Buchstabe ist ein idx von einem string
Ein Byte kann alles sein, ein Buchstabe, eine Zahl, ein IDX.

Wo liegt mein Denkfehler, wie kann ich das wieder gerade biegen, sodass 
ich weiss, wann ich char und wann int / uint.. nehmen muss.

Danke!

: Verschoben durch Admin
von Dennis S. (eltio)


Lesenswert?

> Ist es nicht so, dass unsigned char und uint8 das gleiche sind
> was sind dann reine char datentypen, reichen die von 0 bis 255
> oder nur 0 bis 127 oder hat das gar nichts damit zu tun.
Es ist nicht definiert ob char mit oder ohne Vorzeichen ist. Somit kann 
es von 0 ... 255 ODER von -128 ... 127 gehen. Wie kommst du auf 0 ... 
127? Ein char ist immer 8Bit groß.

> eine Zahl ist ein Integer
Nein, es gibt auch Fließkommazahlen (float, double)

> mehrer Zahlen sind eine Integer Folge
Missverständlich... mehrere Zahlen können auch eine lange Zahl oder die 
Repräsentation eines "Strings" (was es so in C nicht gibt) als 
Ascii-Code sein.

> Wo liegt mein Denkfehler, wie kann ich das wieder gerade biegen, sodass
> ich weiss, wann ich char und wann int / uint.. nehmen muss.
Im Zweifel musst du entscheiden welche Werte deine Variable annehmen 
kann. Generell ist ein char auch nur eine Zahl (nähmlich der 
Ascii-Code). int-Typen sind in der Regel größer als char.

Welche Lernmaterialien nutzt du?

Gruß
Dennis

von Ingo L. (corrtexx)


Lesenswert?

Dennis S. schrieb:
> Es ist nicht definiert ob char mit oder ohne Vorzeichen ist.
Beim Atmel Studio kann man einstellen, ob char signed oder unsigned sein 
soll...

von TriHexagon (Gast)


Lesenswert?

Ingo Less schrieb:
> Dennis S. schrieb:
>> Es ist nicht definiert ob char mit oder ohne Vorzeichen ist.
> Beim Atmel Studio kann man einstellen, ob char signed oder unsigned sein
> soll...

Das kann man bei jedem vernünftigen Compiler einstellen (z.B. gcc mit 
-funsigned-char). Trotzdem ist es schlechter Stil char anstatt unsigned 
char oder besser uint8_t zu benutzen.

von Sebastian V. (sebi_s)


Lesenswert?

Varianten a, b und e sind exakt gleichwertig. Genauso c, d und f. Bei 
dem Stern ist es Geschmackssache ob man es an den Typ oder den 
Variablennamen schreibt. Und bei der Schreibweise mit [] könnte man auch 
erst meinen es wäre was anderes als als Funktionsparameter ist das 
identisch mit der Pointer Versionen. Bleibt also noch der Unterschied 
zwischen char und uint8_t. Dabei ist char der Typ den man für Strings 
benutzt weil char für Zeichen gedacht ist. uint8_t ist ein 
vorzeichenlose Zahl im Bereich 0 bis 255. Kann man nehmen wenn man mit 
keinen Zahlen arbeitet. Wird teilweise auch für binäre Daten benutzt 
(wieder Geschmackssache).

von Ingo L. (corrtexx)


Lesenswert?

Da gebe ich dir recht. Ich verwende auch immer uint8_t und co. weil ich 
auf 8 und 32 Bittern arbeite und man sich gern bei unsigned/signed int n 
Fehler ins Haus holt.

von Heinz L. (ducttape)


Lesenswert?

Ömm... in C ist ein string de facto ein character array. Da gibt's nix 
mit Reihe oder "parallel".

Wenn Du da hast
1
char meinname[] = "ducttape";

ist das nichts anderes als ein Array vom Typ char (also eine vorgegebene 
Anzahl an hintereinander liegenden (weil Array) ein Byte großen (weil 
char) Elementen. Dass die zufällig einen String ergeben den Du lesen 
kannst interessiert C dabei eher wenig. Für C ist das auch nix anderes 
als 8 Zahlen hintereinander. Die halt zufällig, wenn man durch sie den 
ASCII-Table interpretiert, einen String ergeben.

Anders gesagt, Du kannst auch folgendes machen:
1
char meinname[9]; //Wenn man nicht initialisiert, muss man C sagen wie groß.
2
meinname[0] = 100;
3
meinname[1] = 117;
4
meinname[2] = 99;
5
meinname[3] = 116;
6
meinname[4] = 116;
7
meinname[5] = 97;
8
meinname[6] = 112;
9
meinname[7] = 101;
10
meinname[8] = 0;
11
printf ("%s", &meinname);

Deswegen muss man C auch sagen welchen Typ eine Variable hat. Für C ist 
alles eigentlich nur 'ne Zahl. Auch wenn wir darin sonderbare Zeichen 
lesen wollen.

Übrigens: Das Array muss 9 Zeichen groß sein auch wenn nur 8 rein 
sollen, weil ein "string" in C ein extra Zeichen braucht für die 
berühmte terminierende 0. Die so nebenbei öfter als einem lieb ist für 
lustige Speicherüberläufe und sonstige Laufzeigfehler sorgt, 
insbesondere wenn sie nicht da ist.

Zum Thema Stern: Ob Du schreibst
1
uint* variable;
oder
1
uint *variable;
ist egal. Beides gleich gültig und am ehesten davon abhängig an welche 
Coding convention Du Dich zu halten hast weil Dein Chef das so will. :)

von Sebastian V. (sebi_s)


Lesenswert?

TriHexagon schrieb:
> Trotzdem ist es schlechter Stil char anstatt unsigned
> char oder besser uint8_t zu benutzen.

Von welchem Fall redest du jetzt? Für Funktionen die mit Strings/Zeichen 
arbeiten ist char genau richtig.

von c schüler (Gast)


Lesenswert?

Dennis S. schrieb:

>> Ist es nicht so, dass unsigned char und uint8 das gleiche sind
>> was sind dann reine char datentypen, reichen die von 0 bis 255
>> oder nur 0 bis 127 oder hat das gar nichts damit zu tun.
> Es ist nicht definiert ob char mit oder ohne Vorzeichen ist. Somit kann
> es von 0 ... 255 ODER von -128 ... 127 gehen. Wie kommst du auf 0 ...
> 127? Ein char ist immer 8Bit groß.

Ok, ich hab mir das ausgedacht, da es unsigned char und char gibt,
dachte ich mir dass unsigned dann 0..255 sein können und char eben der
reine Tastaursatz 0..127 oder so .


>
>> eine Zahl ist ein Integer
> Nein, es gibt auch Fließkommazahlen (float, double)

ok..

>
>> mehrer Zahlen sind eine Integer Folge
> Missverständlich... mehrere Zahlen können auch eine lange Zahl oder die
> Repräsentation eines "Strings" (was es so in C nicht gibt) als
> Ascii-Code sein.

ok . sorry für meine unverständliche Formulierung, int, double, long .. 
etc
ok kurze und lange Zahlen, mit denen man rechnet.

Was ist eigentliche eine Datei, ein Datenbuffer?
Ein Array von Bytes?
Ein Array von Chars's?
EIn Array von Integer?

Wobei ja die Fragen nicht richtig sind, ein Byte ist ein Integer 0..255
bzw  das Zeichen.


Wenn der Buffer/Datei 256 Bytes lang ist, können das ja nur ein array of 
bytes sein ?



>
>> Wo liegt mein Denkfehler, wie kann ich das wieder gerade biegen, sodass
>> ich weiss, wann ich char und wann int / uint.. nehmen muss.
> Im Zweifel musst du entscheiden welche Werte deine Variable annehmen
> kann. Generell ist ein char auch nur eine Zahl (nähmlich der
> Ascii-Code). int-Typen sind in der Regel größer als char.
>


Ich hatte irgenwo mal gelesen, dass bei char der compiler \0 als 
Schnittmakierung verwendet, und man eine Stelle mehr einpanen muss, 
daher hab ich charimmer der 'String' Verarbeitung zugeordnet:

letztendlich will ich byte's verarbeiten 0..255 ob das eine Zahl ist, 
oder ein Hexwert oder Bin Wert ist mir erstmal egal, aber jedesmal wenn 
ich anfange, stolpere ich über die Wahl, wenn ich einen MessageText 
daraus ziehen will..:

was wäre richtiger?
1
 
2
3
char buffer[8] = "abcdefg\0";
4
..
5
uint8_t buffer[8] = "abcdefgh";

Und das Sternchen gibt mir dann den Rest,einmal rechts dran beim 
Datentyp und einmal links dran an der Variablen, und manchmal steht es 
einfach nur so da:
1
void machwas('typedef structure:datensatz' *);


> Welche Lernmaterialien nutzt du?

'Karl Heinz'
'Karl Heinz'
'Karl Heinz'

mikrocontroller.net ´

J. Wolf, beide C und C++ Bücher, kleines Handbuch und dickes.

>
> Gruß
> Dennis

Danke!

von TriHexagon (Gast)


Lesenswert?

Sebastian V. O. schrieb:
> TriHexagon schrieb:
>> Trotzdem ist es schlechter Stil char anstatt unsigned
>> char oder besser uint8_t zu benutzen.
>
> Von welchem Fall redest du jetzt? Für Funktionen die mit Strings/Zeichen
> arbeiten ist char genau richtig.

Bei Strings und Zeichen char, ansonsten uint8_t. Da hast du allerdings 
recht das hätte ich unterscheiden müssen.

von Guest (Gast)


Lesenswert?

Heinz L. schrieb:
> Zum Thema Stern: Ob Du schreibst uint* variable;
> oder uint *variable;
> ist egal. Beides gleich gültig und am ehesten davon abhängig an welche
> Coding convention Du Dich zu halten hast weil Dein Chef das so will. :)

Ich habe damals gelernt, dass man typischerweise uint *variable; 
schreiben sollte. Warum?

Übersichtlicher, wenn man diesen Fall betrachtet:

uint8_t* var1, var2; (var1 pointer, var2 nicht aber schlecht zu lesen)

bzw.

uint8_t *var1, var2; (var1 pointer, var2 nicht, eindeutiger)

von Karl H. (kbuchegg)


Lesenswert?

c schüler schrieb:

> Ok, ich hab mir das ausgedacht, da es unsigned char und char gibt,

Es gibt auch signed char :-)

am besten gehst du so vor

char          für alles was mit Texten zu tun hat. Also 
Stringverarbeitung
signed char   kleiner Integer, mit Vorzeichen
unsigned char kleiner Integer, aber ohne Vorzeichen


insbesondere letzteres (unsigned char) ist der Datentyp der Wahl, wenn 
man es mit Bytes zu tun hat.

> Was ist eigentliche eine Datei

Den Datentyp 'Datei' gibt es in C nicht.

> ein Datenbuffer?
> Ein Array von Bytes?
> Ein Array von Chars's?
> EIn Array von Integer?
>

Das kommt drauf an, als was du es ansehen willst.

Grundsätzlich ist der einfachste Datentyp immer das Byte.
Aber es kann natürlich sein, dass eine Abfolge von Bytes eine spezielle 
Bedeutung hat. Wie zum Beispiel dann, wenn die Bytes als Inhalt ASCII 
Codes haben und nach dem letzten Nutzbyte ein Byte mit dem Wert 0 kommt. 
Dann wird aus der allgemeinen Bytefolge ein String.

: Bearbeitet durch User
von Sebastian V. (sebi_s)


Lesenswert?

c schüler schrieb:
> Ok, ich hab mir das ausgedacht, da es unsigned char und char gibt,
> dachte ich mir dass unsigned dann 0..255 sein können und char eben der
> reine Tastaursatz 0..127 oder so .

Für alle anderen Ganzzahligen Typen hättest du recht gehabt. Also wenn 
du nur short, int, long oder sowas schreibst ist es immer signed also 
mit Vorzeichen. Wenn man unsigned will muss man das dazu schreiben. Bei 
char wird es aber nicht festgelegt obt es signed oder unsigned ist. Wenn 
man explizit Zahlen zwischen -128 bis 127 speichern will nimmt man 
signed char oder besser int8_t. Für unsigned eben unsigned char oder 
auch wieder besser uint8_t. Den Typ char nimmt man ausschließlich für 
Zeichen oder Strings (Array von Zeichen).

von Karl H. (kbuchegg)


Lesenswert?

Guest schrieb:

> Ich habe damals gelernt, dass man typischerweise uint *variable;
> schreiben sollte. Warum?


Das ist auf eine Idee der Designer von C zurückzuführen, die die 
Definition einer Variablen wie ihre Verwendung gestalten wollten

in
1
  int * a, b;

ist a eine Pointer Variable, b jedoch nicht.
D.h. an dieser Stelle bindet sich der * an den Variablennamen und nicht 
an den Namen des Datentyps.

Wenn b auch ein Pointer sein soll, dann schreibt sich das als
1
  int * a, * b;

(Und ob du da jetzt Leerzeichen machst oder nicht, ist dem C Compiler 
wurscht)

mit
1
  int* a, b;
ist das jetzt leicht fehlzulesen, weil uns die Nähe des * zum Dtaentyp 
suggeriert, dass er dort dazugehört. Tut er aber nicht.

von c schüler (Gast)


Lesenswert?

TriHexagon schrieb:
> Sebastian V. O. schrieb:
>> TriHexagon schrieb:
>>> Trotzdem ist es schlechter Stil char anstatt unsigned
>>> char oder besser uint8_t zu benutzen.
>>
>> Von welchem Fall redest du jetzt? Für Funktionen die mit Strings/Zeichen
>> arbeiten ist char genau richtig.
>
> Bei Strings und Zeichen char, ansonsten uint8_t. Da hast du allerdings
> recht das hätte ich unterscheiden müssen.

Dann geht es nicht nur mir so.
Es gibt also doch 'Missverständnise' untereinander.

@all
Danke für die vielen Antworten, ich war zu schnell bei Denis zu 
antworten; viele Sachen sind schon beantwortet, danke danke! Jetzt kann 
ich wieder weiter kauen.

Es ist sehr schwer wenn man von einer anderen Programiersprache kommt, 
wo es zu viele Datentypen gibt, die aber genau genommen auch nur ein 
Byte sind; mir persönlich sind uint8_t am liebsten, egal ob 
Stringverarbeitung oder Rechnen. Bei char zucke ich zusammen und mein 
Gehirn fängt an zu rattern, was ich jetzt falsch machen könnte.


Sternchen ist jetzt klarer.
Danke nochmals an alle hier, dass ihr euch so eine Mühe gemacht habt,
und dazu noch bei dem Wetter.

von c schüler (Gast)


Lesenswert?

Karl Heinz schrieb:
> Guest schrieb:
>
>> Ich habe damals gelernt, dass man typischerweise uint *variable;
>> schreiben sollte. Warum?
>
>
> Das ist auf eine Idee der Designer von C zurückzuführen, die die
> Definition einer Variablen wie ihre Verwendung gestalten wollten
>
> in
>
1
> 
2
>   int * a, b;
3
>
>
> ist a eine Pointer Variable, b jedoch nicht.
> D.h. an dieser Stelle bindet sich der * an den Variablennamen und nicht
> an den Namen des Datentyps.
>
> Wenn b auch ein Pointer sein soll, dann schreibt sich das als
>
1
>   int * a, * b;
2
>
>
> (Und ob du da jetzt Leerzeichen machst oder nicht, ist dem C Compiler
> wurscht)
>
> mit
>
1
>   int* a, b;
2
>
> ist das jetzt leicht fehlzulesen, weil uns die Nähe des * zum Dtaentyp
> suggeriert, dass er dort dazugehört. Tut er aber nicht.

Da ist es wieder ;-)
Das Sternchen einmal da udn einmal hier ;-)
ALso reiner Schreibstil Karl Heinz?

Wenn ich also schreibe
1
int* a,b,c,d,e,f;
2
3
// ist das gleiche wie
4
5
int *a,*b,*c,*d,*e,*f;
6
7
8
// ?

Danke!

von Sebastian V. (sebi_s)


Lesenswert?

c schüler schrieb:
> mir persönlich sind uint8_t am liebsten, egal ob
> Stringverarbeitung oder Rechnen

Wenn du für alles uint8_t nimmst funktioniert sowas aber nicht:
1
  uint8_t x[] = "test";
2
  printf(x);
Zumindest nicht ohne extra Cast.

c schüler schrieb:
> Wenn ich also schreibe
>
> int* a,b,c,d,e,f;
>
> // ist das gleiche wie
>
> int *a,*b,*c,*d,*e,*f;

Nein das ist nicht das gleiche! Dem Compiler ist es egal wo man die 
Leerzeichen setzt. Aber für den Leser der sich nicht so genau mit den 
Regeln auskennt könnte meinen bei int* a,b,c,d,e,f; wären alles Pointer. 
Tatsächlich ist hier nur a ein Pointer.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

c schüler schrieb:

> Ich hatte irgenwo mal gelesen, dass bei char der compiler \0 als
> Schnittmakierung verwendet, und man eine Stelle mehr einpanen muss,
> daher hab ich charimmer der 'String' Verarbeitung zugeordnet:

Das ist auch ok so.

> letztendlich will ich byte's verarbeiten 0..255 ob das eine Zahl ist,
> oder ein Hexwert oder Bin Wert ist mir erstmal egal


Pst. In einem Computer ist alles ausnahmslos eine Zahl.

Du als Programmierer entscheidest, was da daraus machst.

>, aber jedesmal wenn
> ich anfange, stolpere ich über die Wahl, wenn ich einen MessageText
> daraus ziehen will..:

Text ... dann ist die Sache klar. Text ist char

> was wäre richtiger?
>
1
> 
2
> char buffer[8] = "abcdefg\0";
3
>

Grunsätzlich fast richtig. Aber wozu das \0 Zeichen da am Ende?
Wenn du ein Stringliteral schreibst, also etwas in " Anführungszeichen, 
dann hängt der Compiler IMMER das abschliessende \0 Zeichen automatisch 
mit drann! D.h der String "abcdefg\0" hat die Länge 9(!) und nicht 8. Es 
ist schön (und nicht verboten), wenn du selbst da ein \0 in den String 
reinschreibst. Das hindert den Compiler aber nicht daran, selbst dann 
auch noch eines hinten anzuhängen, so wie es die Regel fordert, dass er 
das bei einem Stringliteral tun muss.


> uint8_t buffer[8] = "abcdefgh";

UNd auch dieses Array ist zu klein.
Zähl die Zeichen. VOn a bis zum h sind es 8 sichtbare Zeichen. Dann noch 
das obligatorische \0 vom Compiler hinten drann und du hast 9 Zeichen.

OK. Der Fairness halber sei gesagt, dass es hier noch eine 
Ausnahmeregelung gibt. Nämlich dann, wenn dein Stringliteral ohne das 
abschliessende \0 Zeichen exakt in das angegebene Array passt, dann wird 
das abschliessende \0 auch ausgelassen. Aber das ist eine Ausnahme. 
Ansonsten ist das obligatorische \0 vom Compiler immer mit dabei.

Aber:
Wozu die Zeichen zählen? Überlass das doch dem Compiler!
1
char buffer[] = "abcdefgh";
Der Compiler sieht sich die Initialisierung an, bestimmt daraus wie 
gross das Array sein muss und dann macht er es genau so gross.

Wenn die Idee an dieser Stelle war, ein Array zu machen, das als 
Übersetzungstabelle fungiert, dann könnte man das auch genau so als 
Übersetzungstabelle schreiben.
1
  char buffer[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };

jetzt ist alles klar: Es ist klar, dass dieses Array nicht als String 
aufgefasst werden soll, denn sonst hättest du es ja mit einem 
Stringliteral initialisiert. Das hier, und das ist für einen 
Programmierer ablesbar, ist eindeutig einfach nur als Array von 
Charactern gedacht. Mit irgendeinem Index geht man in das Array rein und 
aus dem Array kriegt man 1 Character raus. Mehr wollte der 
Originalprogrammierer nicht und mehr steckt auch nicht in diesem Code.


Man kann viele Dinge auf viele verschiedene Art und Weisen schreiben. 
Manchmal bewirkt es sogar bis runter zur Bitebene genau das gleiche. Der 
Unterschied besteht nur darin, was die unterschiedlichen Schreibweisen 
einem menschlichem Programmierer vermitteln - was sie ihm erzählen was 
wohl die Absicht des Schreibers war.

: Bearbeitet durch User
von c schüler (Gast)


Lesenswert?

Sebastian V. O. schrieb:
> c schüler schrieb:
>> mir persönlich sind uint8_t am liebsten, egal ob
>> Stringverarbeitung oder Rechnen
>
> Wenn du für alles uint8_t nimmst funktioniert sowas aber nicht:
>
1
  uint8_t x[] = "test";
2
>   printf(x);
> Zumindest nicht ohne extra Cast.

EXACT!
Sebastian du bringst es auf den Punkt,
genau an dieser Stelle habe ich dann meine Hänger,
und fange den angefangenen schönen code zu verwurschteln an.

Ich bin dann mehr Zeit damit beschäftigt, zu verstehen, warum mir der 
compiler den fehlenden TYpe Cast meldet, dann häng ich einen aus 
verschiedenen casten kopierten Code ein, einmal mit einem Stern am 
Datentyp oder andersmal mit einem am Variablennamen damit es weitergeht.

Das bringt mich dann in rage und fange an die Bücher auf und ab zu 
wälzen um das zu verstehen, was ich falsch mache.
>
> c schüler schrieb:
>> Wenn ich also schreibe
>>
>> int* a,b,c,d,e,f;
>>
>> // ist das gleiche wie
>>
>> int *a,*b,*c,*d,*e,*f;
>
> Nein das ist nicht das gleiche!

okay, jetzt ist das Sternchen in dem Fall klar, danke!

von Jay (Gast)


Lesenswert?

c schüler schrieb:
> Móin,
>
> kann mir jemand sagen was die Unterschiede sind und wann man welche
> szenarien verwendet:
>
> //a: warum ist der Stern am Datentyp und wann macht man das so
> void machwas (uint8* buffer) {
> }

Der Standard-Datentyp heißt uint8_t, nicht uint8.

Zur Platzierung des *: Persönliche Vorliebe des Programmierers, macht an 
dieser Stelle aber keinen Unterschied. Die Schreibweise wird von manchen 
Lehrbüchern als "schöner" bezeichnet, hat aber in anderem Zusammenhang 
den Nachteil etwas Verwirrung zu stiften:
1
uint8_t* p, q;
Sind mitnichten zwei Pointer p und q, sondern ein Pointer p, und eine 
uint8_t variable q. Bei sauberer Schreibweise ist das etwas 
offensichtlicher:
1
uint8_t *p, q;

> // und warum gibt es so eine Schreibweise?
> // ein array (container) für bytes? oder strings?
> //e:
> void machwas (uint8 buffer[] ) {
> }

Syntaktischer Zucker. Ob eine Funktion als
1
void machwas(uint8_t buffer[]) { }
oder
1
void machwas(uint8_t *buffer) { }
definiert wird macht absolut keinen Unterschied.

Bei beiden Versionen erwartet die Funktion einen Pointer!

Es ist so, dass in C an ein paar Stellen der Namen eines Arrays 
automatisch in einen Pointer auf das Array umgewandelt wird. Der Aufruf 
einer Funktion ist so eine Stelle. Man kann eine Funktion nicht mit 
einem Array aufrufen, auch wenn es so aussieht. Es ist in Wahrheit immer 
ein Pointer der in der Funktion ankommt.

Die Variante
1
void machwas(uint8_t buffer[]) { }
verbirgt das nur, ändert aber nichts daran, dass buffer nicht als Array, 
sondern eben als Pointer auf ein Array übergeben wird. Vielleicht hätten 
die Erfinder von C diese alternative Schreibweise weglassen sollen.

>
> //ein array (container) für reinen String?
> //oder ist das eine Stringliste,
> // mich irretiert einmal schreibt man einen reinen String ohne
> // array und einmal mit, wie ist es denn richtig?

Ein char-Array ist Speicherplatz (typischerweise für einen String, 
besonders in älteren Programmen auch oft Speicherplatz für Daten, als es 
noch kein uint8_t gab). Ein Pointer ist ein Verweis auf einen 
Speicherplatz.

Das ist so etwa der Unterschied zwischen "ein Schüler sein" und der 
Nachbar zeigt auf dich und sagt "da hihten, dass ist ein Schüler".

In C ist die Bezeichnung String eine Bezeichnung für zwei Dinge:

1) Für ein char-Array das die nummerischen Codes der einzelnen 
Buchstaben eines Strings enthält, abgeschlossen durch ein zusätzliche 
0-Byte (ASCII-Code NUL) im Array.

2) Ein String-Literal, also
1
"dies ist ein String"
 Eigentlich ist die Bezeichnung eines String-Literals, als String nicht 
ganz richtig, aber üblich.


Im Folgenden geht es ziemlich heftig durcheinander:

> Ich stolpere meistens wenn es um Bytes und Strings geht,
> mein Base ist:
>
> eine Zahl ist ein Integer

Es gibt auch andere Zahlen.

> mehrer Zahlen sind eine Integer Folge

Mehrere Zahlen sind erst einmal nur mehrere Zahlen. Mehrere Zahlen in 
ein Array geschrieben, sind Inhalt des Arrays.

> entweder in Reihe 'string' oder parallel 'array'

Nein, siehe oben. In C ist ein String ein mit Buchstabencodes 
initialisiertes Array (oder ein String-Literal).

> ein Buchstabe ist ein char

Die in C übliche Art und Weise den nummerischen Code eines Buchstabens 
zu speichern ist der char-Datentyp. Vereinfacht nennt man ein char 
manchmal einen Buchstaben oder einen Buchstaben ein char.

> mehrere Buchstaben ein char Folge

Mehrere Buchstaben sind erst einmal mehrere Buchstaben. Speichert man 
die numerischen Codes der jeweiligen Buchstaben in ein char-Array, und 
speichert man hinter den Buchstabencodes im Array noch den ASCII-Code 
NUL, hat man einen String (in einem char-Array).

> entweder in Reihe 'string' oder parallel 'array'

Quatsch.

> Ein Buchstabe ist ein idx von einem string

Nein ein Index ist ein Verweis auf eine Stelle in einem Array. An der 
Position des Index im Array befinden sich Daten. Bei einem char-Array 
befindet sich an der durch den Index bezeichneten Position zum Beispiel 
der numerische Code eines Buchstabens.

> Ein Byte kann alles sein, ein Buchstabe, eine Zahl, ein IDX.

Ein Byte ist eine Informationseinheit, typischerweise auf modernen 
Systemen aus 8 Bit zusammengesetzt (ja, es gab auch Maschinen mit andere 
Byte-Längen). Ein Byte kann in C in jedem Datentyp gespeichert werden, 
der mindestens die Anzahl Bits eines Bytes speichern kann. Früher war 
das klassischerweise der Datentyp char. Heute verwendet man für die 
üblichen 8 Bit Bytes lieber uint8_t.

Die Bedeutung eines Bytes hängt von seiner Interpretation ab. Ich kann 
ein Byte als Zahl, als nummerischen Code eines Buchstabens, oder was 
auch immer interpretieren. Heute handhabt man das so, dass wenn man ein 
Byte in einem char-Datentyp abspeichert man die Interpretation als 
Zahlencode eines Buchstabens möchte. Speichert man ein Byte in einem 
uint8_t Datentyp ab sagt man erst mal gar nichts darüber wie man das 
Byte interpretieren will, allerdings erlaubt ein uint8_t eine einfache 
Interpretation eines Bytes als Zahl zwischen 0 ... 255.

von Karl H. (kbuchegg)


Lesenswert?

c schüler schrieb:

>> Wenn du für alles uint8_t nimmst funktioniert sowas aber nicht:
>>
1
  uint8_t x[] = "test";
2
>>   printf(x);
>> Zumindest nicht ohne extra Cast.
>
> EXACT!
> Sebastian du bringst es auf den Punkt,
> genau an dieser Stelle habe ich dann meine Hänger,

wo hast du da einen Hänger?

Dieses x hier ist eindeutig dazu gedacht einen Text aufzunehmen. Die 
Intialisierung zeigt das mehr als deutlich an, indem dort ein 
Stringliteral steht.
Also ist der dafür zuständige Datentyp ein plain vanilla char.

von Heinz L. (ducttape)


Lesenswert?

Stoooooop!

Momenterle bitte! Bitte nicht einfach Sterne irgendwo dranpappen und 
weglassen damit irgendwie halt der Code compiliert! Da kommt sonst sehr 
schnell GANZ was anderes raus als man will!

Wenn zwei Typen nicht implizit gecastet werden können kann man auch 
explizit casten. Aber einfach Sternchen hinmalen oder weglassen geht 
SICHER schief!

von c schüler (Gast)


Lesenswert?

Karl Heinz schrieb:
> c schüler schrieb:
>
>> was wäre richtiger?
>>
1
>>
2
>> char buffer[8] = "abcdefg\0";
3
>>
>
> Grunsätzlich fast richtig. Aber wozu das \0 Zeichen da am Ende?

okay, verstanden, hatte das mal gelesen, dass man bei String ein \0
ranhängen sollte, damit, wenn der buffer[8] mit "ab" belegt wird,
nicht weitere zeichen aus speicheradressen wiedergibt.

> Wenn du ein Stringliteral schreibst, also etwas in " Anführungszeichen,
> dann hängt der Compiler IMMER das abschliessende \0 Zeichen automatisch
> mit drann!

das hab ich so noch nicht gewusst, danke Karl Heinz.
ok.

> reinschreibst. Das hindert den Compiler aber nicht daran, selbst dann
> auch noch eines hinten anzuhängen, so wie es die Regel fordert, dass er
> das bei einem Stringliteral tun muss.

Karl Heinz, kannst du mir bitte dieses Regelwerk posten, es wäre schön, 
wenn man so ein Regelwerk am Tisch hat, den \0 Schnittmarke hatte ich 
auch nur bedingt in Erfahrung gebracht, als ich einen String ausgewertet 
habe, und mich wunderte, warum 0x00 oder \0 nicht vorkam, obwohl ich es 
explizit versand hatte ( UART ) .
>
>
>> uint8_t buffer[8] = "abcdefgh";
>
> UNd auch dieses Array ist zu klein.

jetzt rattert es wieder ;-)
man sollte das \0 also generell einplanen mit einem mehrzeichen?

> Zähl die Zeichen. VOn a bis zum h sind es 8 sichtbare Zeichen. Dann noch
> das obligatorische \0 vom Compiler hinten drann und du hast 9 Zeichen.

bekomme ich das zu sehen, wenn ich neun bytes lese?

>
> OK. Der Fairness halber sei gesagt, dass es hier noch eine
> Ausnahmeregelung gibt.

solche Sachen werden in den Standards beschrieben, richtig?
wie kann man sich da auf dem Laufenden halten?

> Aber:
> Wozu die Zeichen zählen? Überlass das doch dem Compiler!
>
1
> char buffer[] = "abcdefgh";
2
>
> Der Compiler sieht sich die Initialisierung an, bestimmt daraus wie
> gross das Array sein muss und dann macht er es genau so gross.

was macht das Programm dann wenn es mal ein grösserer String wird,
kümmert es sich selber um den Speicherbedarf onThefly?


>
> Wenn die Idee an dieser Stelle war, ein Array zu machen, das als
> Übersetzungstabelle fungiert, dann könnte man das auch genau so als
> Übersetzungstabelle schreiben.
>
1
>   char buffer[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
2
>

EXACT!
genau diese Stellen haben ich dann, und springe dann
1
chararray[0] = string[0];
2
chararray[1] = string[1];
3
chararray[2] = string[2];
4
..

weil ich versucht habe, ein array einfach einem anderen array zuzuweisen
1
chararray = stringarray;

es aber nicht geht.


>
> jetzt ist alles klar: Es ist klar, dass dieses Array nicht als String
> aufgefasst werden soll, denn sonst hättest du es ja mit einem
> Stringliteral initialisiert. Das hier, und das ist für einen
> Programmierer ablesbar, ist eindeutig einfach nur als Array von
> Charactern gedacht. Mit irgendeinem Index geht man in das Array rein und
> aus dem Array kriegt man 1 Character raus. Mehr wollte der
> Originalprogrammierer nicht und mehr steckt auch nicht in diesem Code.

exact, genau so mach ich das bisher.
und Ecke dann wenn ich einen Text daraus ziehen will.
Ich bekomme das schon irgendwie dann hin, aber ich muss
nachschlagen, nachlesen, es will einfach nicht als 'logik'
in meinen Kopf ;-)

danke!!

von c schüler (Gast)


Lesenswert?

Heinz L. schrieb:
> Stoooooop!
>
> Momenterle bitte! Bitte nicht einfach Sterne irgendwo dranpappen und
> weglassen damit irgendwie halt der Code compiliert! Da kommt sonst sehr
> schnell GANZ was anderes raus als man will!
>
> Wenn zwei Typen nicht implizit gecastet werden können kann man auch
> explizit casten. Aber einfach Sternchen hinmalen oder weglassen geht
> SICHER schief!

Nach 3-4 Stunden lesen und recherchieren, was die Compiler Meldung 
mitteilen will, probiere ich es just in Time aus ;-);
am nächsten Tag ist das dann klar wie Sternenhimmel;
am übernächsten Tag gleiche Art, andere Namen, und es geht von vorne 
los.

Ich will das verstehen, warum weshalb wieso, c ist super , wenn ich c 
von Anfang an verwendet hätte, wäre einiges einfacher; vieles läuft 
jetzt dank der Hilfen immer hier, und lesen in Büchern, aber manche 
Sachen bringen mir Kopfzerbrechen warum das jetzt so ist wie es ist und 
sein muss.
Hernach ist es dann wieder klar.

..

von c schüler (Gast)


Lesenswert?

Danke euch für Eure Mühen, '1000 thanks button drück'
danke Jay und Karl Heinz, viel Stoff - werde mich einlesen!
Viele Sachen wieder dabei, die mich weiterbringen!

von Sebastian V. (sebi_s)


Lesenswert?

c schüler schrieb:
> solche Sachen werden in den Standards beschrieben, richtig?
> wie kann man sich da auf dem Laufenden halten?

Ja es gibt einen C-Standard, den man auch im Internet findet. Zum lernen 
ist das allerdings nichts. Das ist eher was als Nachschlagwert für 
Experten und Compilerentwickler. Sinnvoller wäre eher ein gutes Buch. 
Dort werden solche Grundlagen wie der richtige Umgang mit Strings 
erklärt.

c schüler schrieb:
>> char buffer[] = "abcdefgh";
>> > Der Compiler sieht sich die Initialisierung an, bestimmt daraus wie
>> gross das Array sein muss und dann macht er es genau so gross.
>
> was macht das Programm dann wenn es mal ein grösserer String wird,
> kümmert es sich selber um den Speicherbedarf onThefly?

Der String kann nicht vergrößert werden. Der Compiler reserviert einfach 
soviel Platz wie es für die Zeichen in den Anführungszeichen benötigt + 
ein extra Zeichen für die abschließende \0. Wenn man nachträglich noch 
etwas anhängen möchte braucht man ein neues Array mit mehr Platz.

c schüler schrieb:
> man sollte das \0 also generell einplanen mit einem mehrzeichen?

Wenn es um Text geht ja. Die vielen Funktionen welche mit Strings 
arbeiten gehen davon aus, dass der String bei einem \0 Zeichen zuende 
ist. Dies hat den Vorteil, dass man sich nicht speichern muss wie lang 
der Text ist sondern man gibt einfach so lange Zeichen aus bis ein \0 
kommt. Natürlich könnte es noch weiter gehen aber das kann die Funktion 
ja nicht wissen. Dafür gibt es auch Funktionen aber denen muss man dann 
die Größe mitgeben.

von Heinz L. (ducttape)


Lesenswert?

Zum Thema der \0: Grundsätzlich hast Du recht. Wenn Du Strings "zu Fuß" 
zuweist, also jeden Buchstaben einzeln (siehe auch mein Beispiel weiter 
oben), dann musst Du das machen. Wenn Du einem Character Array einen 
String "direkt" zuweist, also mit sowas wie
1
char mystring[]="whatever";

Macht das der Compiler für Dich, weil ihm klar ist dass Du da mit einem 
String hantierst. Das Array muss allerdings in jedem Fall groß genug 
sein dass die 0 reinpasst. Sprich, wenn Du 8 Zeichen im String hast, 
muss das Array Platz für 9, also Deine 8 und die 0 von C, haben.

Zum Thema "welche Zahlen ergeben einen String", schau Dir mal einen 
ASCII-Table an. Tante Google hat da einige zur Auswahl. Wenn Du Dir den 
anschaust wirst Du feststellen, dass im ASCII-Table jede Zahl zwischen 0 
und 127 etwas bedeutet. Die ersten 32 sind Steuerzeichen mit 
hauptsächlich historischer Bedeutung. Das sollte das Mysterium warum aus 
einem character array ein String wird etwas erhellen.

Zum Einlesen: Du bekommst grundsätzlich immer das Zeichen das Du 
einliest. Wenn Du im obenstehenden String "whatever" das 9. Zeichen 
einliest (also Zeichen mit Index 8, remember, C zählt von 0 weg!) dann 
bekommst Du als Antwort 0. Weil das 9. Zeichen ist die Trenn-0 von C.

Zur Größe von Arrays: Nein, Arrays wachsen nicht automatisch. Wenn Du 
versuchst einem Char Array der Größe 8 den String "vielzugross" 
zuzuweisen gibt's einen Laufzeitfehler mit "index out of bounds". 
Vorläufig solltest Du hier bei der Erstellung bereits einplanen dass Du 
da später mehr reinschreiben willst. Später gibt's über dynamische 
Speicherallokierung Mittel und Wege das on the fly zu lösen, aber lassen 
wir das mal für später. Jedenfalls, automatisch ist da nix. 
Grundsätzlich: In C ist wenig bis gar nix automatisch.

Zuweisen von Arrays: DER klassische Anfängerfehler. Fühl Dich in guter 
Gesellschaft, hat jeder gemacht. :)

Das zu erklären bedarf eines an Ausholen, weil dafür sollten wir zuerst 
mal erklären wie denn das so ist mit Pointern, Referenzen und 
Dereferenzierung. Würd's Dich sehr stören wenn wir das etwas 
verschieben? Sonst ist die Verwirrung unter Garantie komplett.

von c schüler (Gast)


Lesenswert?

Heinz, das verschieben wir ;-)
Ok - bin satt :)

Ihr habt mir sehr geholfen, was raus kommt, wird in jedem Fall hier als 
erstes stehen!

Jetzt gönnt euch eine saubere Radler -

;-)

von Marc S. (marc_s86)


Lesenswert?

Jay schrieb:
> Es ist so, dass in C an ein paar Stellen der Namen eines Arrays
> automatisch in einen Pointer auf das Array umgewandelt wird. Der Aufruf
> einer Funktion ist so eine Stelle. Man kann eine Funktion nicht mit
> einem Array aufrufen, auch wenn es so aussieht. Es ist in Wahrheit immer
> ein Pointer der in der Funktion ankommt.

hier sei noch gesagt dass in c arrays und pointer absolut das selbe 
sind.
1
a[5]

ist das selbe wie
1
*(a+5*{LÄNGE DES TYPS DER ELEMENTE VON A})


btw: das ist auch das selbe wie:
1
5[a]

von Peter II (Gast)


Lesenswert?

Marc S. schrieb:
> hier sei noch gesagt dass in c arrays und pointer absolut das selbe
> sind.

so pauschal stimmt das aber nicht.

sizeof() liefert bei pointer etwas anders als bei einem Array.

von Marc S. (marc_s86)


Lesenswert?

Peter II schrieb:
> Marc S. schrieb:
>> hier sei noch gesagt dass in c arrays und pointer absolut das selbe
>> sind.
>
> so pauschal stimmt das aber nicht.
>
> sizeof() liefert bei pointer etwas anders als bei einem Array.

sizeof ist aber ein compile time operator, zur laufzeit ist es das 
selbe. der compiler zählt halt und etzt für sizeof diese zahl ein. und 
das gilt natürlich auch nur für statische arrays.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Marc S. schrieb:

> hier sei noch gesagt dass in c arrays und pointer absolut das selbe
> sind.

gefährliche Aussage. Die hat in dieser Form schon zu so manchem Fehler 
geführt.

Sagen wir so:
Der Indexoperator ist in C in Einheiten von Pointer Arithmetik 
definiert.
Bei alleiniger Nennung des Namens eines Arrays, 'zerfällt' das Array in 
die Startadresse seines ersten Elements (Ausnahme: sizeof)

Diese Aussagen passen auch auf dein Beispiel und vermeiden die nicht 
korrekte Aussage, dass ein Array und ein Pointer dasselbe wären. Denn 
das sind sie nicht.

File1.c
1
char tst[10];

File.c
1
extern char* tst;

Frage: Warum funktioniert das nicht, wo doch Array und Pointer angeblich 
dasselbe sind?

: Bearbeitet durch User
von TriHexagon (Gast)


Lesenswert?

Auch ein kleiner aber feiner Unterschied:
1
void* test; //gültig
2
void test[]; //ungültig

von c-hater (Gast)


Lesenswert?

TriHexagon schrieb:

> Das kann man bei jedem vernünftigen Compiler einstellen (z.B. gcc mit
> -funsigned-char). Trotzdem ist es schlechter Stil char anstatt unsigned
> char oder besser uint8_t zu benutzen.

Richtig.

Das führt aber ganz unmittelbar zu der Frage: wozu zum Teufel ist dann 
der Datentyp char eigentlich überhaupt gut, wenn man ihn bei sauberer 
Programmierung ohnehin zu fast garnichts einsetzen kann?

Und die einzig korrekte Antwort ist: Es handelt sich de facto um eine 
Inkarnation der C-Portibilitätslüge. Und zwar nur um eine einzige von 
Unmassen ähnlicher (und auch völlig andersgearteter) Versuche, eine in 
der bösen Realitität ziemlich fiktive Portabilität wenigstens auf dem 
Papier herbeizuzaubern...

Übrigens: Andere Programmiersprachen sind da schon vor Jahrzehnten sehr 
viel weiter beim Betrug gewesen. Man denke z.B. nur an das Konzept der 
"Variants". Genauso grenzdebile Scheiße, die auch einfach nur Sachen 
verspricht, die sie nie und nimmer halten kann.

Und jedem, der von der Sache was versteht, war von Anfang an klar, dass 
es so ist. Man braucht also nur die Apologeten raussuchen, die Unfähigen 
und Unwissenden (AKA: Fanboys) abziehen, und in dem, was überbleibt, hat 
man eine zuverlässige und aussagekräftige Liste notorischer Lügner...

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

c-hater schrieb:
> TriHexagon schrieb:
>
>> Das kann man bei jedem vernünftigen Compiler einstellen (z.B. gcc mit
>> -funsigned-char). Trotzdem ist es schlechter Stil char anstatt unsigned
>> char oder besser uint8_t zu benutzen.
>
> Richtig.

Nein, falsch.

> Das führt aber ganz unmittelbar zu der Frage: wozu zum Teufel ist dann
> der Datentyp char eigentlich überhaupt gut, wenn man ihn bei sauberer
> Programmierung ohnehin zu fast garnichts einsetzen kann?

Ausgehend von einer falschen Aussage kann man fast alles behaupten...

von Sebastian V. (sebi_s)


Lesenswert?

c-hater schrieb:
> Das führt aber ganz unmittelbar zu der Frage: wozu zum Teufel ist dann
> der Datentyp char eigentlich überhaupt gut, wenn man ihn bei sauberer
> Programmierung ohnehin zu fast garnichts einsetzen kann?

Wurde hier schon 5mal gesagt aber nochmal: Für Zeichen und Arrays von 
Zeichen aka Strings. Da interessiert dich dann überhaupt nicht ob es 
signed oder unsigned ist aber du kannst auf jeden Fall Zeichen 
speichern.

Karl Heinz schrieb:
> Bei alleiniger Nennung des Namens eines Arrays, 'zerfällt' das Array in
> die Startadresse seines ersten Elements (Ausnahme: sizeof)

Eine weitere Ausnahme ist der Address-of-Operator. Wenn das nicht so 
wäre müsste man ja die Adresse der Startadresse aufs erste Element 
kriegen. Aber das gibts nur bein Pointern.

: Bearbeitet durch User
von TriHexagon (Gast)


Lesenswert?

c-hater schrieb:
> TriHexagon schrieb:
>
>> Das kann man bei jedem vernünftigen Compiler einstellen (z.B. gcc mit
>> -funsigned-char). Trotzdem ist es schlechter Stil char anstatt unsigned
>> char oder besser uint8_t zu benutzen.

Bitte auch das zitieren:

TriHexagon schrieb:
> Bei Strings und Zeichen char, ansonsten uint8_t. Da hast du allerdings
> recht das hätte ich unterscheiden müssen.

Damit wird klarer was ich meinte, nämlich nicht dass grundsätzlich bei 
Zeichen unsigned char anstatt char verwendet werden sollte.

Michael Reinelt schrieb:
> c-hater schrieb:
>> TriHexagon schrieb:
>>
>>> Das kann man bei jedem vernünftigen Compiler einstellen (z.B. gcc mit
>>> -funsigned-char). Trotzdem ist es schlechter Stil char anstatt unsigned
>>> char oder besser uint8_t zu benutzen.
>>
>> Richtig.
>
> Nein, falsch.

Immer noch falsch?

von W.S. (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Ausgehend von einer falschen Aussage kann man fast alles behaupten...

Nanana.

Hier muß ich durchaus in c-hater's Horn blasen.

Also:
1. ein char ist ein char und weil - wie der Namen sagt - selbiger 
eigentlich zum Ausdrücken von Text aller Art gedacht war und ist, soll 
man ihn genau DAFÜR auch so benutzen wie er heißt.

2. Die Anlässe, vorzeichenbehaftet mit 8 Bit Entitäten zu rechnen und 
sich deshalb int zu verkneifen, sind extrem exotisch.

Vorzeichenlos mit 8 Bit Entitäten zu rechnen, ist hingegen Alltagsbrot 
und deshalb sollte man dafür auch den Begriff "byte" verwenden und sich 
notfalls als "unsigned char" selber definieren. Das Wort "byte" kennt 
jeder - im Gegensatz zu uint8_t.

Damit wären wir wieder mal bei typedef angekommen:
typedef alte Bezeichnung neue Bezeichnung
so ist das definiert. Es ist eine reiner Umbenennungsakt. Man hätte es 
anstelle von "typedef" besser "rename" genannt. Aber um Klarheit war man 
in C-Kreisen ja noch nie bemüht.

Von dem krampfigen uintxyz_t halte ich garnichts, denn erstens ist es 
unleserlich und zweitens ist das alles nicht im Sprachumfang enthalten, 
sondern lediglich eine schnöde Umbenennung per Headefile. Kein 
C-Compiler in dieser Welt kennt von sich aus uint8_t. So etwas schafft 
also weder neue Datentypen noch ist es ein Beitrag zur vielgepriesenen 
Portabilität, die es in der Realität mehr oder weniger schlecht auch 
ohne den ganzen uintxyz_t Zirkus schon immer gegeben hat.

Und wer stolz behauptet, daß er dank Beschäftigung mit 8 und 32 Bittern 
zu so etwas greift und damit die gepriesene Portabilität für sich 
hergestellt hat, ist ein Scharlatan. Die wahren Probleme sind nämlich 
ganz woanders, z.B. bei der "Endianess" - ich hab selber sowohl mit Big- 
als auch mit Little-Endian Systemen zu tun und da muß man auf ganz 
andere Dinge achten als auf dieses alberne uintblabla_t. Obendraufkommen 
noch Dinge wie Alignment bei einigen Systemen.


W.S.

von Sebastian V. (sebi_s)


Lesenswert?

W.S. schrieb:
> Vorzeichenlos mit 8 Bit Entitäten zu rechnen, ist hingegen Alltagsbrot
> und deshalb sollte man dafür auch den Begriff "byte" verwenden und sich
> notfalls als "unsigned char" selber definieren. Das Wort "byte" kennt
> jeder - im Gegensatz zu uint8_t.

Und wer garantiert einem, dass unsigned char wirklich ein Byte ist? Der 
Standard garantiert zwar sizeof(char) = 1 aber das muss trotzdem kein 
Byte sein. Es soll scheinbar auch wirre Architekturen geben mit mehr als 
8 Bits pro Byte wobei mir sowas noch nie untergekommen ist.

W.S. schrieb:
> Von dem krampfigen uintxyz_t halte ich garnichts, denn erstens ist es
> unleserlich und zweitens ist das alles nicht im Sprachumfang enthalten,
> sondern lediglich eine schnöde Umbenennung per Headefile. Kein
> C-Compiler in dieser Welt kennt von sich aus uint8_t.

Wie definierst du den Sprachumfang? Gut es gehört nicht zur Sprache an 
sich aber der Header stdint.h ist im Standard definiert. Möchtest du 
vielleicht printf auch nicht benutzen weil es nicht fest in die Sprache 
eingebaut ist sondern einen Header braucht?

Ich finde die Verwendung der uintxx_t Typen durchaus sinnvoll wenn man 
einen Typ mit einer festgelegten Größe braucht. Zum Beispiel beim 
Datenaustausch über Dateien oder Netzwerk. Wenn ich 32Bit brauche dann 
schreibe ich uint32_t und nicht etwa long weil ich gerade auf dem AVR 
bin. Natürlich muss man es nicht überall nutzen und für einfache 
Schleifenzähler nehm ich auch int. Endianess ist natürlich auch wichtig 
aber bisher ist mir noch keine Big-Endian CPU begegnet.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Vorzeichenlos mit 8 Bit Entitäten zu rechnen, ist hingegen Alltagsbrot
> und deshalb sollte man dafür auch den Begriff "byte" verwenden und sich
> notfalls als "unsigned char" selber definieren. Das Wort "byte" kennt
> jeder - im Gegensatz zu uint8_t.

"Byte" kennt zwar jeder als Begriff, allerdings gibt es keine
einheitliche, von jedem akzeptierte Definition dafür:

  http://de.wikipedia.org/wiki/Byte

Einig sind sich diese Definitionen nur in dem einen Punkt, dass ein Byte
eine Ansammlung mehrerer Bits ist.

Beim Datentyp uint8_t steckt bereits im Namen viel Information über die
Eigenschaften des Typs:

- Die "8" sagt aus, dass der Typ aus 8 Bits besteht. Nicht 5 Bits, nicht
  7 Bits, auch nicht "mindestens 8 Bits", sondern exakt 8 Bits.

- Das "int" sagt aus, dass diese 8 Bits ein Integer, d.h. eine ganze
  Zahl repräsentieren. Damit ist klar, dass für diesen Datentyp
  arithmetische Operationen wie Addition und Multiplikation definiert
  sind.

- Das "u" sagt aus, dass diese Zahl vorzeichenlos ist

- Aus den vorangegangenen drei Punkten lässt sich der Wertebereich des
  Typs ableiten: Er umfasst alle ganzen Zahlen im Bereich von 0 bis 255.

All diese Eigenschaften werden durch den Begriff "Byte" nicht
impliziert.

Um zweifelsfrei zu klären, ob der Typ "byte" auch auf exotischen
Prozessorarchitekturen genau 8 Bits enthält, ob diese Bits einfach nur
ein Bitmuster oder tatsächlich eine Zahl darstellen und ob ggf. diese
Zahl vorzeichenlos ist, muss die Dokumentation herangezogen werden.

Die Programmierpsprachen, die "byte" als Datentyp enthalten, verwenden
für Integertypen mit größerem Wertebereich gerne Namen wie "word",
"longword", "doubleword", "quad" u.ä., bei denen die Wertebereiche noch
viel unklarer und oft auch architekturabhängig sind.

Um alle Wünsche und Anforderungen abzudecken, bietet C mehrere Gruppen
von Integer-Datentypen:

Die architekturabhängigen Typen:
  - char
  - short
  - int
  - long
  - long long
  jeweils optional mit den Attributen "signed" oder "unsigned"

Die Typen mit definierter Bitgröße als Typsynonyme:
  - int8_t
  - int16_t
  - int32_t
  - int64_t
  jeweils optional mit dem Präfix "u" (für unsigned)

Darüberhinaus gibt noch weitere Gruppen von Typsynonymen, wie bspw.
[u]int_leat<N>_t und [u]int_fast<N>_t.

von chris (Gast)


Lesenswert?

> Und wer garantiert einem, dass unsigned char wirklich ein Byte ist? Der
> Standard garantiert zwar sizeof(char) = 1 aber das muss trotzdem kein
> Byte sein. Es soll scheinbar auch wirre Architekturen geben mit mehr als
> 8 Bits pro Byte wobei mir sowas noch nie untergekommen ist.

Z.B. Motorola/Freescale DSP560xx/DSP563xx. Für diese DSPs gibt einen 
"nicht mehr ganz frischen" GCC (v1.52 oder so), bei dem gilt:
char = 24 Bit
short int = 24 Bit
int = 24 Bit
long int = 48 Bit
und damit sizeof(char) = sizeof(short int) = sizeof(int) = 1
und sizeof(long int) = 2.

Spätestens bei solchen exotischen Prozessoren fällt man auf die Schnauze 
wenn man davon ausgeht, dass ein char immer 8 Bit hat.
Allerdings programmiert man (also zumindest ich) die genannten 
Prozessoren in der Regel in Assembler.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Man kann auch sagen, es gibt einen Unterschied zu dem was der Volksmund 
8 Bit nennt (ein Byte) und was der Spezialist 8 Bit nennt, wenn er es 
unbedingt braucht: Ein Oktett.

Nun ist die Bezeichnung Oktett schon sehr exotisch und in 99,9...% aller 
Fälle kann man ein Byte als 8 Bit annehmen. Eine Ausnahme ist 
ausgerechnet C. Da funktioniert 8 Bit == char == Byte eben nicht in 100% 
aller Fälle.

Wenn man, wie in diesen Thread, C Grundlagen auseinanderklamüsert und 
versucht Missverständnisse zu vermeiden, dann lohnt es sich schon nicht 
neue falsche Aussagen einzuführen wie char == 8 Bit (oder pointer == 
array). Beides ist nun mal bei C falsch.

Zur Frage nach dem C-Standard, eine alte Version konnte man mal relativ 
preiswert in einer kommentierten Auflage kaufen. Das dumme an den 
Kommentaren war nur, dass sie erschreckend falsch waren 
http://www.lysator.liu.se/c/schildt.html Statt dessen würde ich, auch 
wenn es ebenfalls nicht mehr den neusten Standard beschreibt, das 
klassische Lehrbuch 
http://en.wikipedia.org/wiki/The_C_Programming_Language empfehlen.

von eProfi (Gast)


Lesenswert?

>   int * a, * b;
> (Und ob du da jetzt Leerzeichen machst oder nicht, ist dem
> C Compiler wurscht)

genau, man kann sogar
int*a,*b;
schreiben.

> Nun ist die Bezeichnung Oktett schon sehr exotisch.
Ja, die ganze Welt schreibt Byte, nur bei den Franzosen heißt es Oktett 
(und sie meinen damit ein Byte).

von Dirk B. (dirkb2)


Lesenswert?

Hannes Jaeger schrieb:
> 8 Bit == char == Byte

Die kleinste adressierbare Einheit ist in C ein Byte (per Definition, 
was von der Größe her ein char ist).
Damit man weiß wie groß das ist, gibt es das Makro CHAR_BIT  aus 
limits.h
Und dieses Byte muss mindestens 8-Bit haben, kann auch mehr sein

Hannes Jaeger schrieb:
> dann lohnt es sich schon nicht
> neue falsche Aussagen einzuführen wie char == 8 Bit (oder pointer ==
> array). Beides ist nun mal bei C falsch.
Das erste kann richtig sein, (das zweite ist auf alle Fälle falsch)

Hannes Jaeger schrieb:
> Zur Frage nach dem C-Standard, eine alte Version konnte man mal relativ
> preiswert in einer kommentierten Auflage kaufen.

Es gibt die Drafts zu den Standards. Die letzen davon stimmen jeweils 
mit dem eigentlichen Standard überein.
Die Links dazu stehen bei https://www.c-plusplus.net/forum/300567

Und es gibt noch "The Standard C Library"  von P.J. Plauger.
Das bezieht sich zwar auf C89, dafür aber mit Kommentaren und Quellcode 
zu den Standardfunktionen. Plauger hat C89 selber mit verabschiedet.

von TriHexagon (Gast)


Lesenswert?

W.S. schrieb:
> Von dem krampfigen uintxyz_t halte ich garnichts, denn erstens ist es
> unleserlich und zweitens ist das alles nicht im Sprachumfang enthalten,
> sondern lediglich eine schnöde Umbenennung per Headefile. Kein
> C-Compiler in dieser Welt kennt von sich aus uint8_t. So etwas schafft
> also weder neue Datentypen noch ist es ein Beitrag zur vielgepriesenen
> Portabilität, die es in der Realität mehr oder weniger schlecht auch
> ohne den ganzen uintxyz_t Zirkus schon immer gegeben hat.

Diesen Unsinn lese ich seit Jahren öfters und sehe da bis heute kein 
Problem.

1. Die Typen gehören zu C99 (stdint.h), also zum Sprachumfang.

2. Lassen sich die Typen auch nach belieben umbenennen (z.B. u32). Wobei 
die Namen der Typen einem System folgen und Sinn ergeben.

3. Der Standard garantiert, dass die Typen auch so breit sind. Da ändert 
der Umstand, dass diese Typen als typedefs umgesetzt werden, gar nichts.

4. Die Entscheidung die Typen nicht in den Sprachkern aufzunehmen ist 
legitim. Man will damit mögliche Kompatibilitätsprobleme mit altem Code 
aus dem Weg gehen und den Sprachkern kompakt halten. An vielen neuen 
Sprachen sieht man diesen Trend, Sprachelemente mit der 
Standardbibliothek umzusetzen (wenn es möglich ist). Das sieht man unter 
anderem gut an Rust.

Also alles nur Märchen?

von Dirk B. (dirkb2)


Lesenswert?

Gerade die [u]int<N>_t vermindern die Portabilität, weil es Probleme 
geben kann, wenn diese nicht existieren.

Man sollte sich schon Gedanken machen, wo man welchen Typ einsetzt.

von TriHexagon (Gast)


Lesenswert?

Dirk B. schrieb:
> Gerade die [u]int<N>_t vermindern die Portabilität, weil es Probleme
> geben kann, wenn diese nicht existieren.
>
> Man sollte sich schon Gedanken machen, wo man welchen Typ einsetzt.

Ok das lasse ich gelten, wobei sowas relativ selten vorkommen sollte 
(auf exotischen Architekturen). Eine Sprache die auf allen Architekturen 
gleich gut funktioniert wird es allerdings nie geben.

von Dirk B. (dirkb2)


Lesenswert?

TriHexagon schrieb:
> Eine Sprache die auf allen Architekturen
> gleich gut funktioniert wird es allerdings nie geben.

Kommt auch auf das Problem an. (wird Hardware angesprochen, kann es 
abstrakt berechnet werden, ....)

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
> Von dem krampfigen uintxyz_t halte ich garnichts, denn erstens ist es
> unleserlich und zweitens ist das alles nicht im Sprachumfang enthalten,
> sondern lediglich eine schnöde Umbenennung per Headefile.

Nach dieser Argumentation ist im Sprachumfang auch keinerlei Möglichkeit 
enthalten, Text auszugeben oder dynamischen Speicher anzufordern. Denn 
printf() und malloc() sind nicht Teil des Sprachkerns, sondern der 
Standardbibliothek, genauso wie uint*_t. Letzteres zugegebenermaßen erst 
seit 16 Jahren.

> Kein C-Compiler in dieser Welt kennt von sich aus uint8_t. So etwas
> schafft also weder neue Datentypen

Warum soll man auch neue Datentypen dafür brauchen?

eProfi schrieb:
>> Nun ist die Bezeichnung Oktett schon sehr exotisch.

Sie ist der Fachausdruck. Das ist im übrigen auch die offizielle 
Bezeichnung nach ISO. "Byte" ist nur der umgangssprachliche Begriff für 
"8 Bit".

> Ja, die ganze Welt schreibt Byte, nur bei den Franzosen heißt es Oktett
> (und sie meinen damit ein Byte).

Es ist genau umgekehrt. Wir schreiben Byte und meinen damit in der Regel 
Oktett. Als der Begriff "Byte" erfunden wurde, waren übrigens eher 
andere Größen als 8 Bit üblich.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Dirk B. schrieb:
> Gerade die [u]int<N>_t vermindern die Portabilität, weil es Probleme
> geben kann, wenn diese nicht existieren.

Wo soll da das Problem sein?

Für den seltenen Fall, dass man solchen Code mit einem Compiler 
übersetzen muss, der auf einem Stand von vor sechzehn Jahren ist:

Eine Light-Version von stdint.h schreibt man sich innerhalb von Minuten. 
Wenn es sein muss auf Basis einer stdint.h, die man aus dem Netz fischt.

Dass heißt, man kann diese fehlenden Typen bei vergammelten Compilern 
mit Bordmitteln nachrüsten, und kann den Gammelcompiler weiter benutzen. 
Was mehr willst du eigentlich?

Braucht jemand die Datentypen öfters hat er so eine Headerdatei für 
seinen Gammelcompiler sowieso bereits fertig in der Schublade.

von Bastler (Gast)


Lesenswert?

Laut GNU header portability guide sollte man besser <inttypes.h> verwend 
en, weil darin auf jeder (GNU bekannten) Plattform stdint.h inkludiert 
wird, falls diese dort existiert. inttypes.h existiert auf allen.
Neben [u]int<N>_t gibt es ja in <inttypes.h> auch die "least" und "fast" 
Varianten. Wenn man also z.B. einen Zähler von 1.30000 braucht, dann 
kann man den als uint_least16_t definieren, wenn man Speicherplatzangst 
hat, oder uint_fast16_t, wenn man die schnellste Variante auf der 
entsprechenden Hardware braucht.
int, long, short, .. auf feste Breiten zu definieren, (wie in Java,) 
wäre nicht sehr zukunftssicher. Dann hätte man zu PDP11-Zeiten int auf 
16 und long auf 32 Bit festgelegt. Und als C "erfunden" wurde auf der 
PDP7, gab es 18bit Worte (und eventuell 9-Bit char?).

von Dirk B. (dirkb2)


Lesenswert?

Hannes Jaeger schrieb:
> Für den seltenen Fall, dass man solchen Code mit einem Compiler
> übersetzen muss, der auf einem Stand von vor sechzehn Jahren ist:

Es geht nicht um vergammelte Compiler sondern "exotische" Architekturen.

Da, wo ein Byte mehr als 8 Bit hat.

Da kann es keinen uint8_t geben. Aber ein uint_least8_t schon.

von Sebastian V. (sebi_s)


Lesenswert?

Dirk B. schrieb:
> Gerade die [u]int<N>_t vermindern die Portabilität, weil es Probleme
> geben kann, wenn diese nicht existieren.

Da habe ich lieber einen Fehler beim Compilieren als das es nacher so 
aussieht es würde alles funktionieren aber für bestimmte Wertebereiche 
geht dann was schief.

von W.S. (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Nach dieser Argumentation ist im Sprachumfang auch keinerlei Möglichkeit
> enthalten, Text auszugeben oder dynamischen Speicher anzufordern. Denn
> printf() und malloc() sind nicht Teil des Sprachkerns, sondern der
> Standardbibliothek

Schreibe nicht so ein Zeugs, das macht mich so langsam zornig.
printf ist eine ganz schnöde Funktion, die sich jeder nach seinem Gusto 
selber schreiben könnte wenn er das denn wollte.

Der C-Compiler kennt printf oder malloc jedenfalls NICHT. Punkt. Er 
kennt von Hause aus ÜBERHAUPT KEINE Funktionen. Man muß selbige dem 
Compiler nämlich vor der ersten Verwendung erstmal klarmachen und dazu 
dient ein sogenanntes Headerfile, was man einbinden muß: #include ... 
Diese Syntax wirst du ja wohl kennen.

Kurzum, alle (ja ALLE!) Funktionen in C gehören nicht zum Sprachumfang, 
sind also dem C-Compiler nicht von selbst bekannt. Das ist bei Pascal 
durchaus anders, dort sind Funktionen wie chr, val, inc, dec, write, at 
usw. im Sprachumfang enthalten, weswegen der Pascal-Compiler sowas ohne 
jegliche uses Anweisung von sich aus kennt.

Also, Rolf, hast du das nun verstanden?

W.S.

von Sebastian V. (sebi_s)


Lesenswert?

W.S. schrieb:
> Der C-Compiler kennt printf oder malloc jedenfalls NICHT. Punkt.

Was anderes hat hier auch niemand behauptet. Natürlich braucht man ein 
include. Ändert aber nichts daran, dass die Header trotzdem zu C gehören 
und man davon ausgehen kann, dass diese vorhanden sind.

Siehe hier Kapitel 7: 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

von W.S. (Gast)


Lesenswert?

Sebastian V. O. schrieb:
> Und wer garantiert einem, dass unsigned char wirklich ein Byte ist?

Ein Blick in das Manual der betreffenden Hardware. Anders geht es 
prinzipiell nicht. Abgesehen davon IST ein Byte ein unsigned char und es 
sollte dir recht schwerfallen, davon eine Ausnahme in der realen Welt zu 
finden, die irgendwelche Relevanz hat.

Sebastian V. O. schrieb:
> Wie definierst du den Sprachumfang?
Ganz einfach: alles das, was der C-Compiler per se versteht. Guck in die 
Doku zu irgend einem Compiler, da steht es drin. Normalerweise ist die 
Doku zu etwaigen Standard-Bibliotheken ein davon völlig verschiedenes 
Dokument.

Sebastian V. O. schrieb:
> Endianess ist natürlich auch wichtig
> aber bisher ist mir noch keine Big-Endian CPU begegnet.
Siehste, ich habe seit vielen Jahren genau DAS als täglich Brot. Genau 
deshalb hab ich z.B. meine Fonts auch so geschrieben, daß sie mit beiden 
Endian-Arten funktionieren - und dazu braucht man uintxyz_t und 
Konsorten nicht wirklich.

Das kannst du dir merken: Portabilität ist eine Sache der 
Software-Strategie und der Struktur-Entwürfe und hat nichts mit irgend 
einer konkreten Programmiersprache zu tun - und schon garnicht mit 
irgend welchen verquaasten Umbenennungen von Basistypen in C.


Yalu X. schrieb:
> "Byte" kennt zwar jeder als Begriff, allerdings gibt es keine
> einheitliche, von jedem akzeptierte Definition dafür:
Yalu, bleib wenigstens DU hier auf dem Teppich. Du mußt auch nicht jeden 
Unsinn glauben, der in einem Wiki steht. Wenn wir mal ganz kurz 
historisch werden, dann fing das Ganze mit Baudot an und war 5 Bit breit 
- und NIEMAND hat dazu Byte gesagt. Und ASCII war schon immer nur 7 Bit 
breit, damit man das 8. Bit im Byte für die Parität benutzen konnte. Bei 
Lochbandlesern war das essenziell. Und wenn du mal in steinalte Dokus 
von Intel guckst, so aus den frühen 70er Jahren, dann sollte auch dir 
klar werden, daß es schon ganz lange das Byte zu exakt 8 Bit gibt. Mehr 
noch:
8 Bit = byte,
16 Bit = word,
32 Bit = dword,
64 Bit = qword,
80 Bit = tword.

Diese Klassifikation ist mittlerweile über 37 Jahre alt. Reicht das?

Hier geht es um was ganz Anderes, nämlich die Unfähigkeit zu klaren 
Verhältnissen zu kommen. ANSI hatte es einmal geschafft, die Machete in 
den C-Wust zu hauen, saubere Prototypen und ordentliche Argumente zu 
schaffen. Aber zu einem zweiten Aufräumen, das nach Sachlage 
allerdringendst erforderlich wäre, haben sie es nicht geschafft.

Es geht - wie man hier wieder mal deutlich sieht -  auch um die 
Beschränktheit der Leute. Wenn jemand argumentiert, daß es eine 
Headerdatei in die Dokumente von C99 geschafft hat und deshalb das, was 
da drin steht, somit zum Sprachumfang gehören würde, dann kann ich mir 
nur an den Kopf greifen. Welch ein Unverstand. Entweder gehört etwas zum 
Sprachumfang, dann ist es in die Compiler bereits eingebaut und bedarf 
keiner Headerdatei, oder es gehört eben NICHT dazu und muß erst per 
Headerdatei definiert werden. Leute, lernt Denken.

W.S.

von Sebastian V. (sebi_s)


Lesenswert?

W.S. schrieb:
> Sebastian V. O. schrieb:
>> Und wer garantiert einem, dass unsigned char wirklich ein Byte ist?
>
> Ein Blick in das Manual der betreffenden Hardware.

Aha. Ich dachte es ging um Portabilität. Wieso muss ich jetzt in 
hardwarespezifische Unterschlagen schauen?

W.S. schrieb:
> Normalerweise ist die
> Doku zu etwaigen Standard-Bibliotheken ein davon völlig verschiedenes
> Dokument.

Die Doku irgendeines Compilers interessiert mich nicht. Was zählt ist 
der Standard und da ist Language und Library beides in einem Dokument 
(oben verlinkt).

W.S. schrieb:
> Genau
> deshalb hab ich z.B. meine Fonts auch so geschrieben, daß sie mit beiden
> Endian-Arten funktionieren - und dazu braucht man uintxyz_t und
> Konsorten nicht wirklich.

Rein aus Interesse: Wie speicherst du deine Fonts? Wenn irgendwie 
textbasiert hast du das Problem natürlich umschifft aber wenn man binär 
speichern möchte dann muss man sich auf eine Bitbreite, Endianness, 
Alignment usw. festlegen. Wenn du binär arbeitest, wie realisierst du 
fest vorgegebene Bitbreiten von z.B. 32Bit?

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
> Es geht - wie man hier wieder mal deutlich sieht -  auch um die
> Beschränktheit der Leute. Wenn jemand argumentiert, daß es eine
> Headerdatei in die Dokumente von C99 geschafft hat und deshalb das, was
> da drin steht, somit zum Sprachumfang gehören würde, dann kann ich mir
> nur an den Kopf greifen. Welch ein Unverstand. Entweder gehört etwas zum
> Sprachumfang, dann ist es in die Compiler bereits eingebaut und bedarf
> keiner Headerdatei, oder es gehört eben NICHT dazu und muß erst per
> Headerdatei definiert werden. Leute, lernt Denken.

Das ist der größte Blödsinn, den ich seit langem gehört habe.

Abgesehen davon sind z.B. bei gcc die meisten Standardfunktionen 
tatsächlich im Compiler eingebaut.

von Bastler (Gast)


Lesenswert?

>8 Bit = byte,
>16 Bit = word,
>32 Bit = dword,
>64 Bit = qword,
>80 Bit = tword.
Das ist die Nomenklatur EINES Herstellers. Und auch sehr logisch 
aufgebaut. Warum sind 8Byte ein QuadWord, aber 10Byte keine FiveWord 
oder TenByte?

Ganz wichtig: gegen die Portabilität von C spricht ja, daß es auf 
praktischer keiner Plattform verwendet wird, oder :-))

von Rolf M. (rmagnus)


Lesenswert?

Bastler schrieb:
>>8 Bit = byte,
>>16 Bit = word,
>>32 Bit = dword,
>>64 Bit = qword,
>>80 Bit = tword.
> Das ist die Nomenklatur EINES Herstellers.

Richtig. Bei der weltweit am weitesten verbreiteten CPU-Architektur ist 
die Nomenklatur anders. Da ist ein word nämlich 32 Bit breit.
Man sieht hier recht klar, daß W.S. Schwierigkeiten hat, über seinen 
Tellerrand zu schauen und glaubt, daß alles, was er nicht kennt, auch 
nicht relevant ist.

von Heinz L. (ducttape)


Lesenswert?

Erh... Leute, der Threaderöffner hat glaub ich das Gebäude bereits 
verlassen. :)

von W.S. (Gast)


Lesenswert?

Sebastian V. O. schrieb:
> Aha. Ich dachte es ging um Portabilität. Wieso muss ich jetzt in
> hardwarespezifische Unterschlagen schauen?

Und was willst du portieren? Du erwartest nicht ernsthaft, ein 
Windows-Programm bloß per Neukompilieren auf ner Bare-Metal-MIPS 
lauffähig zu kriegen odern nen SDIO-Treiber vom ARM7TDMI auf nem MAC?

Wer an reinen Algorithmen interessiert ist, der nimmt dafür eine 
ausreichend hardwareferne Sprache, wie z.B. Fortran oder so. Aber wer in 
C und das auch noch so einigermaßen hardwarenah programmiert, der muß 
sich zwangsläufig auch mit der zu beglückenden Hardware vertraut machen. 
Portabilität ist sowieso ein Witz, wenn man sich weigert, in 
"hardwarespezifische Unterschlagen (zu) schauen".


Sebastian V. O. schrieb:
> Wenn du binär arbeitest, wie realisierst du
> fest vorgegebene Bitbreiten von z.B. 32Bit?

Byteweise und bitseriell. Daß heißt, Bytegrenzen sind für die Zeichen 
irrelevant. Ist eigentlich ganz einfach.


Heinz L. schrieb:
> Erh... Leute, der Threaderöffner hat glaub ich das Gebäude bereits
> verlassen. :)

Tja, mich wundert das nicht. Bei so einer grandiosen Beratung...

W.S.

von c schüler (Gast)


Lesenswert?

Heinz L. schrieb:
> Erh... Leute, der Threaderöffner hat glaub ich das Gebäude bereits
> verlassen. :)

Ist die Luft jetzt wieder rein? Kann ich aus meinem Versteck?
Da bin ich ja mal froh, dass ihr fast alle gleicher Meinung seid,

danke für die vielen Infos zwischen den Zeilen. Ich habe eine Menge 
dazugelernt und bin bereit für das nächste Kapitel "pointer" in allen 
Variationen, dazu erstelle ich demnächst eine neue Frage.

Danke!

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.