Warum tut memset
nimm ein int
als zweites Argument anstelle von a char
wohingegen wmemset
nimmt ein wchar_t
statt so etwas wie long
oder long long
?
Warum nimmt memset ein int anstelle eines char?
Benutzer541686
Jerry Sarg
memset
ist (um einiges) älter als das Hinzufügen von Funktionsprototypen zu C. Ohne einen Prototyp, Sie kippen passieren a char
zu einer Funktion — wenn/wenn Sie es versuchen, wird es befördert int
wenn Sie es übergeben, und was die Funktion empfängt, ist ein int
.
Es ist auch erwähnenswert, dass in C (aber nicht in C++) ein Zeichenliteral wie 'a'
tut nicht Typ haben char
— es hat Typ int
also wird das, was Sie passieren normalerweise beginne als ein int
ohnehin. Im Grunde ist die einzige Möglichkeit, als Char zu starten und befördert zu werden, wenn du eine bestehst char
Variable.
In der Theorie, memset
könnte wahrscheinlich geändert werden, so dass es eine erhält char
statt ein int
, aber es ist unwahrscheinlich, dass es irgendeinen Vorteil gibt, und eine ziemlich anständige Möglichkeit, den einen oder anderen alten Code zu brechen. Mit unbekannten, aber möglicherweise ziemlich hohen Kosten und fast keiner Chance auf einen wirklichen Nutzen, würde ich sagen, dass die Chancen, dass es geändert wird, einen erhalten char
liegen genau auf der Linie zwischen “schlank” und “keine”.
Bearbeiten (Reaktion auf die Kommentare): The CHAR_BIT
niederwertigsten Bits der int
werden als Wert zum Schreiben in das Ziel verwendet.
-
Warte, es gab eine Version von C ohne Funktionsprototypen?! =O
– Benutzer541686
7. Mai 2011 um 7:56 Uhr
-
Ja – Prototypen wurden während der C89-Standardisierung hinzugefügt. Davor gab es nur Funktionsdeklarationen, die den Rückgabetyp spezifizierten, aber nicht die Anzahl oder Art(en) von Parameter(n).
– Jerry Sarg
7. Mai 2011 um 7:58 Uhr
-
Ein Beispiel für das Brechen von altem Code, if
memset
nahm plötzlich einchar
Code dann nach dem üblichen Idiom des Passierens(unsigned char)some_int
würde nicht streng konform werden, da es bei einer (sehr seltenen) Implementierung nicht funktionieren würde, wochar
vorzeichenbehaftet ist und Werte größer als hatCHAR_MAX
nicht konvertierenchar
wie Sie hoffen würden.– Steve Jessop
3. April 2013 um 21:52 Uhr
-
Ebenfalls,
memset
nicht per Definition benutze dieCHAR_BIT
niedrigstwertige Bits des Werts. Es ist definiert, um den Wert zu konvertierenunsigned char
was bei einer 2er-Komplementdarstellung auf dasselbe hinausläuft, aber bei anderen (sehr seltenen) Implementierungen nicht so sehr.– Steve Jessop
3. April 2013 um 21:54 Uhr
-
Ich benutze C++ schon so lange, dass ich das vergessen hatte
'a'
in C ist einint
und nicht einchar
.– Adrian McCarthy
22. Mai 2014 um 17:32 Uhr
Frédéric Hamidi
Wahrscheinlich der gleiche Grund, warum die Funktionen in <ctypes.h>
nehmen ints
und nicht chars
.
Auf den meisten Plattformen a char
ist zu klein, um alleine auf den Stack geschoben zu werden, also schiebt man normalerweise den Typ, der der Wortgröße der Maschine am nächsten kommt, dh int
.
Wie der Link im Kommentar von @ Gui13 zeigt, erhöht dies auch die Leistung.
-
Hier gibt es eine interessante Antwort: programrsheaven.com/mb/embedCpp/359784/359784/memset-function was bestätigt, was du sagst 🙂 Was interessant zu bestätigen ist, ist das Verhalten von
memset(ptr, 0xFEBADE23, 1);
? Welcher Teil von int wird geschrieben?– GUI13
7. Mai 2011 um 7:52 Uhr
-
@Frederic: Tolle Erklärung, aber warum gilt nicht dasselbe für
wmemset
? Ist nicht einwchar_t
auch zu klein, um auf vielen Plattformen auf den Stack geschoben zu werden (oft 16 Bytes)?– Benutzer541686
7. Mai 2011 um 7:59 Uhr
-
Die Funktionen im
<ctype.h>
nehmenint
s aus dem gleichen Grund, dassgetc
,fgetc
etc., Rückkehrint
– unterzubringenEOF
die sich von jedem Wert von unterscheiden musschar
(odersigned char
oderunsigned char
).– Jerry Sarg
7. Mai 2011 um 8:02 Uhr
-
@Mehrdad, das kommt darauf an.
wchar_t
ist 32 Bit breit auf Linux-Systemen 🙂– Frédéric Hamidi
7. Mai 2011 um 8:05 Uhr
-
@Frederic: Aber es sind 16 Bit auf Windows-Systemen … : P (Ich glaube, Sie meinten
bits
nichtbytes
)– Benutzer541686
7. Mai 2011 um 8:06 Uhr
Siehe Freds Antwort, es ist aus Leistungsgründen.
Auf meiner Seite habe ich diesen Code ausprobiert:
#include <stdio.h>
#include <string.h>
int main (int argc, const char * argv[])
{
char c = 0x00;
printf("Before: c = 0x%02x\n", c);
memset( &c, 0xABCDEF54, 1);
printf("After: c = 0x%02x\n", c);
return 0;
}
Und es gibt mir das auf einem 64-Bit-Mac:
Before: c = 0x00
After: c = 0x54
Wie Sie sehen, wird also nur das letzte Byte geschrieben. Ich denke, das hängt von der Architektur (Endianness) ab.
-
Der geschriebene Wert ist unabhängig von der Endianness der Architektur. Der geschriebene Wert ist der übergebene Wert, der in ein umgewandelt wird
unsigned char
was Modulo bedeutet2^CHAR_BIT
Arithmetik. Dies bedeutet die am wenigsten signifikanteCHAR_BIT
Bits unabhängig von der Endianness der Maschine.– CB Bailey
7. Mai 2011 um 8:02 Uhr
@Default: Haha, eigentlich weiß ich, dass es nicht funktioniert, aber ich denke, es erleichtert das visuelle Lesen, nicht wahr?
– Benutzer541686
7. Mai 2011 um 7:39 Uhr
Nein, nicht zu mir. Und um wählerisch zu sein, könnte memset es auch sein
code
🙂– Ursprünglich
7. Mai 2011 um 7:40 Uhr
Wenn
wmemset
symmetrisch war, würde es eine dauernwint_t
das ist der Typ, der als definiert istint
zuwchar_t
‘schar
. (Hinweis: mehrere Funktionen in der Standardbibliothek übernehmenint
Argumente, die in Zeichen umgewandelt werden. Der (C)-Standard besagt, dass Zeichenliterale vom Typ sindint
nichtchar
.)– Chris Lutz
7. Mai 2011 um 7:42 Uhr
@Default: Haha ok, ich dachte, es wäre besser lesbar. 🙂 @Chris: Warte, was?? Ich dachte, Chars sind Charaktere?!
– Benutzer541686
7. Mai 2011 um 7:43 Uhr
'\n'
ist vom Typint
in C (nicht in C++). Es sei denn, ich täusche mich gewaltig. Ich tippe dies von meinem iPhone aus oder ich würde eine umfassendere Antwort geben.– Chris Lutz
7. Mai 2011 um 7:45 Uhr