Guten Morgen,
ich habe eine kleine Frage, habe hier über die Suchfunktion noch keine
direkte Antwort finden können aber vielleicht könnt ihr mir was dazu
sagen, wäre echt super.
Ich habe einen Zähler implementiert, der mir einfach eine unsigned char
Variable bei jedem Aufruf hochzählt, nichts aufregendes. Jedoch erreicht
diese auch ihren Maximalwert 255. Muss ich die aktiv zurücksetzen oder
kann ich einen Overflow zulassen? Sauberer wäre sicher das Zurücksetzen
oder was sagt ihr?
Gruß Manuel
...Ich Danke Euch!
Manuel schrieb:> Muss ich die aktiv zurücksetzen oder> kann ich einen Overflow zulassen?> Sauberer wäre sicher das Zurücksetzen oder was sagt ihr?
Sauberer wäre vermutlich die Verwendung einer für den zu erwartenden
Wertebereich ausreichend dimensionierten Variablen.
Lässt sich so pauschal nicht sagen. Was machst du denn mit dieser
Zählervariable? Darf sie.bei 0xff stehen bleiben, wird siesporadisch
rückgeaetzt um timeouts zu implememtieren oder...? Dem Compiler, der MCU
ist der mögliche Overflow jedenfalls egal.
Char ist denkbar ungeeignet, da eine char Variable ein Zeichen enthält.
Das kann unter Umständen auch mal 16 Bit breit sein.
Ich würde, bei Dingen, wo es darauf ankommt, dass du eine definierte
Breite hast immer diese Standarddinger nehmen:
Sven H. schrieb:> Char ist denkbar ungeeignet, da eine char Variable ein Zeichen enthält.>
achso, wer sagt das? Der Typ char sagt nur aus, dass damit eine Variable
mit 1 Byte Länge definiert wird! Ob diese Varaible dann (logisch
gesehen) ein Zeichen, eine Zahl zwischen 0...255, eine Bit-Belegung
eines 8-Bit-Ports oder ein Keks beinhaltet ist vollkommen egal und dem
Programmierer überlassen!
Sven H. schrieb:> uint8_t>
und was meinst du, was sich hinter diesem Typ verbirgt? Schaue mal in
der entsprechenden Header-Datei nach...:
'uint8_t' ist nur eine andere Bezeichnung für 'unsigned char'!
Mahlzeit
Manuel schrieb:> Ich habe einen Zähler implementiert, der mir einfach eine unsigned char> Variable bei jedem Aufruf hochzählt, nichts aufregendes. Jedoch erreicht> diese auch ihren Maximalwert 255. Muss ich die aktiv zurücksetzen oder> kann ich einen Overflow zulassen? Sauberer wäre sicher das Zurücksetzen> oder was sagt ihr?
Bei Datentypen ohne Vorzeichen ist das Überlaufverhalten sauber
definiert. Bei Überschreitung des Wertebereichs geht es wieder bei 0
los.
Bei Datentypen mit Vorzeichen ist das Überlaufverhalten nicht
definiert.
A. K. schrieb:> Manuel schrieb:>>> Ich habe einen Zähler implementiert, der mir einfach eine unsigned char>> Variable bei jedem Aufruf hochzählt, nichts aufregendes. Jedoch erreicht>> diese auch ihren Maximalwert 255. Muss ich die aktiv zurücksetzen oder>> kann ich einen Overflow zulassen? Sauberer wäre sicher das Zurücksetzen>> oder was sagt ihr?>> Bei Datentypen ohne Vorzeichen ist das Überlaufverhalten sauber> definiert. Bei Überschreitung des Wertebereichs geht es wieder bei 0> los.>> Bei Datentypen mit Vorzeichen ist das Überlaufverhalten nicht> definiert.
Ok, dann weiß ich bescheid!
Danke für die Antworten! Ist ein sehr nützliches Forum, konnte schon
viel lernen.
Gruß
besserwisser schrieb:> achso, wer sagt das? Der Typ char sagt nur aus, dass damit eine Variable> mit 1 Byte Länge definiert wird!
Mööp, leider falsch.
Zitat aus Wiki ( http://de.wikipedia.org/wiki/Char_(Datentyp) )
Die meisten Programmiersprachen stellen ein Zeichen in einem Byte (8Bit)
dar, wobei als Zeichensatz ASCII und dessen Ableitungen wie ISO 8859-1
sowie EBCDIC die verbreitetsten Kodierungen sind. *Neuere
Programmiersprachen wie C# oder Java verwenden zwei Byte pro Zeichen
(UNICODE) und kodieren Zeichen in UTF-16.* Die etablierten Sprachen wie
C und C++ wurden um den mehrbytigen Datentyp wchar_t erweitert.[1]
Und, ja, ich weiß sehr wohl, was sich in c hinter dem uint8_t verbirgt
tut nur hier nichts zur Sache, da der TO leider keine Programmiersprache
angegeben hat.
besserwisser schrieb:> 'uint8_t' ist nur eine andere Bezeichnung für 'unsigned char'!
Auch falsch. Siehe die erste Antwort in folgendem Link:
http://www.progforum.com/showthread.php?8632-Unterschiede-zwischen-uint8_t-und-char
Zitat:
die Speichergrößen von char, int, long, etc. sind nicht wirklich fest
definiert. Laut C-Standard ist char <= int <= long. Zwar ist im
Allgemeinen ein char immer 8 Bit, es besteht aber (auch wenn sehr
Unwahrscheinlich) das auf einer anderen Plattform ein char > 8 bit ist.
Zudem kann je nach Plattform ein char signed (mit Vorzeichen) oder
unsigned (ohne Vorzeichen) sein.
Im Allgemeinen ist es aber so das ein char[] einen String definiert,
und der ist in C immer mit einem \0 abgeschlossen.
Ein uint8_t gibt hingegen direkt die Speichergröße und Typ an (unsigned
8 bit type). Wenn man Arrays zum Ablegen von Daten macht, ist das
uint8_t in diesem Fall zu bevorzugen, da es die Größe und Typ fest
definiert.
Wie gesagt, im Fall des char macht das noch nicht wirklich Sinn,
Interresant wird es aber bei anderen Typen, z.B. int. So ist auf PIC's
ein int z.B. 16 Bit, während er auf x86 meistens mit 32 Bit definiert
ist.
Sven H. schrieb:> Mööp, leider falsch.>
MööpMööp..., wenn du schon zitierst, dann bitte den richtigen Abschnitt
des Artikels. Über die fachliche Richtigkeit des verlinkten
Wikipedia-Artikels lässt sich streiten. Vorallem, wenn ich ich da lese:
"Der Datentyp eignet sich grundsätzlich nur zur Zeichendarstellung,
nicht zu Berechnungen und nicht für die Indizierung/Adressierung.
Hierfür werden numerische Datentypen verwendet, je nach
Programmiersprache z. B. short, long, integer etc."
Das halte ich für vollkommenden Blödsinn! Wer hintert mich (in C) daran,
in einer char-Variablen etwas anderes abzulegen, als wie unbedingt ein
Zeichen? Niemand!
Und nochmal: der Datentyp char legt nur fest, das die, mit diesem Typ
definierte Variable ("i.d.R."; Zitat Wikipedia-Artikel) 8-Bit lang sind.
Der Begriff "Zeichkodierung" hat erstmal nichts mit dem Datentyp "char"
zu tun! Wenn du Zeichensätze mit mehr als 8-Bit hast, wirst du (i.d.R.)
nicht mit dem Datentyp "char" auskommen, sondern wirst dich auf andere
Datentypen (z.B. word, uint16_t, ...) ausweichen bzw. dir selbst etwas
deklarieren müssen, wenn du auf das Wortfragment "*char*" in der
Bezeichnung bestehst!
Sven H. schrieb:> Ein uint8_t gibt hingegen direkt die Speichergröße und Typ an (unsigned> 8 bit type). Wenn man Arrays zum Ablegen von Daten macht, ist das> uint8_t in diesem Fall zu bevorzugen, da es die Größe und Typ fest> definiert.>
aber nicht, wenn in meiner stdint.h steht:
1
typedef unsigned char uint8_t
...und, nach deiner Annahme ein "char" auch 16-Bit sein könnte! Oder
habe ich da etwas übersehen?
Mahlzeit!
PS.: nicht alles was man im Internet findet, sollte man, ohne mal
darüber eingehender nachgedacht zu haben, bedenkenlos zitieren. Ich
halte mich da lieber an die originale Doku des jeweilig verwendeten
Compiler!
besserwisser schrieb:> Oder> habe ich da etwas übersehen?
Ein char ist mindestens 8 Bit groß, kann aber auch größer sein (und ist
es auch bei manchen Architekturen). Wenn es größer ist, dann existiert
auf einem solchen System ein uint8_t schlicht nicht. Wenn die genaue
Größe für das Funktionieren des Programms wichtig ist (z.B. weil es sich
darauf verlässt, dass die Variable entsprechend überläuft), dann ist es
besser unit8_t zu nehmen, denn wenn dann versucht wird, das Programm auf
einem char>8Bit-System zu übersetzen gibt es sofort eine Fehlermeldung,
dass uint8_t nicht existiert.
besserwisser schrieb:> Wer hintert mich (in C) daran,> in einer char-Variablen etwas anderes abzulegen, als wie unbedingt ein> Zeichen? Niemand!
wer hindert dich daran mit einer Maurerkelle den Kuchen zu servieren?
klar ist es möglich, aber es gehört nicht zum guten Stil.
dito mit char und Daten, die keine Zeichen sind.
char, long etc. sind wirklich nicht definiert. Das hängt von der
Busbreite ab. Das ist so. Ein int ist auf einem 32 Bit System nicht
gleich gross wie auf einem 64 Bit System.
Ein char ist in der Regel 8 Byte (aber nicht zwingend). Das hängt vom
Compiler und Architektur ab.
Worauf Sven lediglich aufmerksam machen wollte, ist, das in c die Typen
uint8_t etc. kompatibler sind zwischen verschiedenen Architekturen.
Grüsse,
René
Sven H. schrieb:> Char ist denkbar ungeeignet, da eine char Variable ein Zeichen enthält.>
Mir ist dieser Satz in Svens Posting aufgestossen, der so vollkommen
absolu formuliert ist und so nicht stimmt! Die weiteren Zitate, die er
dann angebracht hatte, zeigen davon, dass er es auch wirklich so absolut
meint...
Mahlzeit!
> Mahlzeit!
Na ja.
Du hast dich auch nicht gerade mit Ruhm bekleckert.
>> aber nicht, wenn in meiner stdint.h steht:>> typedef unsigned char uint8_t>>> ...und, nach deiner Annahme ein "char" auch 16-Bit sein könnte!> Oder habe ich da etwas übersehen?
Du hast übersehen, dass in diesem Fall dann ein uint8_t anders definiert
wäre oder gar nicht. Was dich allerdings nichts angeht, weil dir dein
Compilerhersteller die stdint.h aufs Auge drückt und einen uint8_t dann
eben so definiert, dass er wieder 8 Bit hat. Wie auch immer diese
Definition aussieht. Und falls es überhaupt möglich ist, natürlich.
Nur weil bei dir, auf deinem jetzigen Compiler ein uint8_t als typedef
auf einen unsigned char definiert ist, heißt das nicht, dass das immer
und überall so ist.
So, von der Solaris Page über die Portierung von 32Bit nach 64Bit:
The 64-bit environment uses a different data type model than the 32-bit
environment. The C data-type model used for 32-bit applications is the
ILP32 model, so named because ints, longs, and pointers are 32-bit. The
LP64 data model is the C data-type model for 64-bit applications. This
model was agreed upon by a consortium of companies across the industry.
It is so named because longs and pointers grow to 64-bit quantities. The
remaining C types int, short, and charare the same as in the ILP32
model. The standard relationship between C integral types still holds
true.
So, wie ich das verstehe ist die Grösse eine Vereinbarung, was demnach
nicht heisst, dass das immer so ist. Zumindest verstehe ich das so.
Der Linke zur Seite:
http://developers.sun.com/solaris/articles/solarisupgrade/64bit/Convert.html
PS: In dem Fall ist es aber so, das int sowohl auf 32Bit als auch 64Bit
4 Byte ist.
Grüsse,
René
>So, von der Solaris Page über die Portierung von 32Bit nach 64Bit:
um es noch "interessanter" zu machen: es gibt ja (wenn man mal nur Intel
betrachtet ) 2 Verschiedene 64-bit Architekturen
die von Intel (Itanium/IA-64) und die von AMD (x64)
für die von AMD (welche in aktuellen CPUs verwendet wird)
werden int weiterhin als 32bit definiert (bei Itanium und auch Sparc??
eher 64bit?)
andererseits gibt es auch
http://www.heise.de/open/artikel/Kernel-Log-x32-ABI-umgeht-Nachteile-des-64-Bit-Betriebs-1341264.html
also 32bit Pointer trotz 64Bit Linux Betriebssystem.
Manuel schrieb:> Ich habe einen Zähler implementiert, der mir einfach eine unsigned char> Variable bei jedem Aufruf hochzählt, nichts aufregendes. Jedoch erreicht> diese auch ihren Maximalwert 255. Muss ich die aktiv zurücksetzen oder> kann ich einen Overflow zulassen? Sauberer wäre sicher das Zurücksetzen> oder was sagt ihr?
unsigned char counter=0;
while(true) //endlos
counter++
Das Ding läuft bis zum Maximalwert und wird dann wieder bei 0 gestartet.
Absolut kein Problem, du musst dich nicht um Zurücksetzen oder ähnliches
kümmern.
Beachte aber wie bereits oben erwähnt, dass sizeof(char) nicht zwingend
1 ist. Die Kardinalität von char ist 2^(sizeof(char)*8).
Wobei ich sagen muss, dass ich es bis jetzt noch nicht erlebt habe, dass
in C/C++ char jemals ungleich 1 byte war. Aber das heißt grundsätzlich
mal garnichts ;-)
Und noch ein Wort zur Verwendung von char: Niemand schreibt vor, wie ich
char in C/C++ verwende. Wenn ich zum Beispiel eine Schleife über 3 Werte
mache (z.B. über die 3 Farbkanäle eines Bildes), so verwende ich hierfür
unsigned char, ganz einfach deswegen, weil es vom Wertebereich absolut
genug ist. Niemand schreibt vor, dass man in char ein Zeichen speichern
muss.
Grade wenns Richtung low level Sachen geht, auf schwachen Rechnern,
verwende ich bei solchen Dingen durchaus char!
Anderes Beispiel: digitale Bilder. Jeder Kanal ist mit 1 byte codiert.
Klar missbraucht man auch hier unsigned char zum Speichern einer Zahl,
anstatt zum Speichern eines Zeichens. Stellt euch mal vor, was es heißt,
stattdessen short int zu verwenden. Der Speicherverbrauch verdoppelt
sich unnötigerweise.
Mal abgesehen davon, dass ich mich vielleicht wirklich etwas absolut
ausgedrückt habe, finde ich es interessant, in welche Richtung sich der
Thread entwickelt hat!
Robert L. schrieb:> für die von AMD (welche in aktuellen CPUs verwendet wird)> werden int weiterhin als 32bit definiert (bei Itanium und auch Sparc??> eher 64bit?)
Bis vor kurzem haben wir hier noch auf Solaris SPARC gearbeitet.
Zwischen 32/64 Bit hatten sich lediglich die Pointers unterschieden.
Integer war auf beiden 4 Byte lang.
besserwisser schrieb:> Sven H. schrieb:>> Char ist denkbar ungeeignet, da eine char Variable ein Zeichen enthält.>>> Mir ist dieser Satz in Svens Posting aufgestossen, der so vollkommen> absolu formuliert ist und so nicht stimmt!
Naja, man sollte char nur für Zeichen verwenden, allerdings ist im
Ursprungsposting nicht von char, sondern von unsigned char die Rede.
> Die weiteren Zitate, die er dann angebracht hatte, zeigen
zeugen (Sorry, aber wenn du dich schon "besserwisser" nennst...)
> davon, dass er es auch wirklich so absolut meint...Karl Heinz Buchegger schrieb:> Du hast übersehen, dass in diesem Fall dann ein uint8_t anders definiert> wäre oder gar nicht. Was dich allerdings nichts angeht, weil dir dein> Compilerhersteller die stdint.h aufs Auge drückt und einen uint8_t dann> eben so definiert, dass er wieder 8 Bit hat. Wie auch immer diese> Definition aussieht. Und falls es überhaupt möglich ist, natürlich.
Speziell uint8_t kann nur existieren, wenn char 8 Bit breit ist. Das
ergibt sich einfach daraus, daß sizeof(char)==1 und damit char der
kleinste Datentyp ist. Wenn der größer als 8 Bit ist, kann es also
keinen 8-Bit-Typ geben.
Sven H. schrieb:> besserwisser schrieb:>> achso, wer sagt das? Der Typ char sagt nur aus, dass damit eine Variable>> mit 1 Byte Länge definiert wird!>> Mööp, leider falsch.
Nein, das ist absolut richtig.
> Die meisten Programmiersprachen stellen ein Zeichen in einem Byte (8Bit)> dar,
In C (und auch allgemein) muß ein Byte nicht zwingend genau 8 Bit groß
sein. Statt "Byte (8Bit)" wäre in dem Text die in der Netzwerktechnik
übliche Bezeichung "Oktett" besser geeignet.
ösi schrieb:> Beachte aber wie bereits oben erwähnt, dass sizeof(char) nicht zwingend> 1 ist.
Doch, sizeof(char) ist per Definition immer 1.
> Die Kardinalität von char ist 2^(sizeof(char)*8).
Wieso 8? Das ist nirgends so festgelegt. Die Zahl an Bits in einem char
stellt dir der Compiler über das Makro CHAR_BIT zur Verfügung.
> Und noch ein Wort zur Verwendung von char: Niemand schreibt vor, wie ich> char in C/C++ verwende. Wenn ich zum Beispiel eine Schleife über 3 Werte> mache (z.B. über die 3 Farbkanäle eines Bildes), so verwende ich hierfür> unsigned char, ganz einfach deswegen, weil es vom Wertebereich absolut> genug ist. Niemand schreibt vor, dass man in char ein Zeichen speichern> muss.
char und unsigned char sind zwei verschiedene Typen. Am besten nutzt man
ersteren nur für Zeichen und den zweiten, wenn man Platz sparen muß und
einen kleinen vorzeichenlosen Integerwert speichern muß.
Rolf Magnus schrieb:> Sven H. schrieb:>> besserwisser schrieb:>>> achso, wer sagt das? Der Typ char sagt nur aus, dass damit eine Variable>>> mit 1 Byte Länge definiert wird!>>>> Mööp, leider falsch.>> Nein, das ist absolut richtig.
Ich könnte jetzt zwar behaupten, das es doch falsch ist, führt aber zu
nichts, daher die bitte doch nochmal diese Quelle zu prüfen:
http://msdn.microsoft.com/de-de/library/x9h8tsay(v=vs.90).aspxRolf Magnus schrieb:> Speziell uint8_t kann nur existieren, wenn char 8 Bit breit ist. Das> ergibt sich einfach daraus, daß sizeof(char)==1 und damit char der> kleinste Datentyp ist. Wenn der größer als 8 Bit ist, kann es also> keinen 8-Bit-Typ geben.
Auch nicht richtig:
http://msdn.microsoft.com/de-de/library/5bdb6693(v=vs.90).aspx
Es gibt einen 8 Bit breiten Datentyp, obwohl char 16 bit breit ist.
Bei diesen Diskussionen muss halt beachtet werden, dass nirgendwo die
Rede von C war. Es könnte auch jede andere Programmiersprache gemeint
sein.
ösi schrieb:> Beachte aber wie bereits oben erwähnt, dass sizeof(char) nicht zwingend> 1 ist.
In C schon. C99 zum sizeof() Operator: "When applied to an operand that
has type char, unsigned char, or signed char, (or a qualified version
thereof) the result is 1."
Sven H. schrieb:> Rolf Magnus schrieb:>> Speziell uint8_t kann nur existieren, wenn char 8 Bit breit ist. Das>> ergibt sich einfach daraus, daß sizeof(char)==1 und damit char der>> kleinste Datentyp ist. Wenn der größer als 8 Bit ist, kann es also>> keinen 8-Bit-Typ geben.>> Auch nicht richtig:>> http://msdn.microsoft.com/de-de/library/5bdb6693(v...>> Es gibt einen 8 Bit breiten Datentyp, obwohl char 16 bit breit ist.
Gibt es in C# denn überhaupt einen Typ namens uint8_t? Schließlich wurde
ja darüber diskutiert.
> Bei diesen Diskussionen muss halt beachtet werden, dass nirgendwo die> Rede von C war. Es könnte auch jede andere Programmiersprache gemeint> sein.
Naja, jede andere vielleicht nicht, aber es stimmt natürlich, daß die
Sprache hätte angegeben werden müssen.
Sven H. schrieb:> A. K. schrieb:>> In C schon.>> Es geht aber ausschließlich nicht um C.
Woraus hast du das gelesen? Du scheinst C# anzunehmen. Gibt es da
überhaupt den im Ursprungsposting erwähnten Typ "unsigned char"?
Rolf Magnus schrieb:> Gibt es in C# denn überhaupt einen Typ namens uint8_t? Schließlich wurde> ja darüber diskutiert.
Genau wir in C steht es dir frei, einen Datentypen zu definieren.
uint8_t ist ja auch ein selbst definierter Typ. (typedef unsigned char)
das Problem ist wohl, dass Sven H. und auch der TO
beide die Sprache nicht "definiert" haben (weder bei der Frage, noch bei
der/den Antwort(en))
dass dann nur "nonsense" raus kommt, ist doch klar..
so kann sich jeder immer alles so hin-biegen, um bloß nicht zugeben zu
müssen, irgendwas falsches geschrieben zu haben..
wobei:
zitat:
> Standarddinger nehmen:>uint8_t
stellt sich schon die frage: gibt es STANDARDmäßig ausser in C das
irgendwo ?
Sven H. schrieb:> uint8_t ist ja auch ein selbst definierter Typ
Nein. Er wird durch die "Implementierung" (also Compiler oder
Standardbibliothek) vorgegeben, über <stdint.h> oder <inttypes.h>.
Dadurch wird seine Semantik (für die Sprache C) eindeutig
beschrieben und ist nicht irgendwie beliebig interpretierbar.
Ob die Implementierung nun über ein typedef erfolgt [was naheliegend
ist] oder über ein Pragma oder was auch immer, ist dabei völlig
unerheblich und für den Nutzer unwichtig. Ein Compiler könnte sich
beispielsweise auch entscheiden, diese Namen als builtins zu
implementieren, die dann durch einen Konstrukt wie
1
#pragma __STDINT_H_included
(der in <stdint.h> drin steht) "freigeschaltet" werden.
Ob Manuel ggf. was anderes als die Sprache C meinte, hat er uns
nicht verraten. Man kann allerdings davon ausgehen, dass er eine
obskure Sprache (wie C#) sicher gesondert erwähnt hätte.
Jörg Wunsch schrieb:> Ja, und? Muss man den kennen?
Ich denke, dass viele die professionell in der SW-Entwicklung arbeiten
davon schon mal gehört haben
> Meine Arbeit ist nicht indiziert. :)
ich wäre mir nicht so sicher, ob da nicht doch auch treffer von mir mit
einberchnet sind.
wenn man bei google nach "c rogramming" "jörg wünsch" eingibt gibts
immerhin >800 Treffer, die ja im gesamtergebnis auch mit drinstecken.