#include <string.h>
void *memset(void *s, int c, size_t n)
Das memset() Funktion füllt die erste nByte des Speicherbereichs, auf den gezeigt wird s mit dem konstanten Byte c.
Es ist offensichtlich das memset kann nicht zum Initialisieren verwendet werden int Array wie unten gezeigt:
int a[10];
memset(a, 1, sizeof(a));
es ist weil int wird durch 4 Bytes (sagen wir) dargestellt und man kann nicht den gewünschten Wert für die Ganzzahlen im Array erhalten a.
Aber ich sehe oft die Programmierer verwenden memset die einzustellen int Array-Elemente entweder 0 oder -1.
int a[10];
int b[10];
memset(a, 0, sizeof(a));
memset(b, -1, sizeof(b));
Nach meinem Verständnis Initialisierung mit Integer 0 ist in Ordnung, weil 0 kann in 1 Byte dargestellt werden (möglicherweise irre ich mich in diesem Zusammenhang). Aber wie ist es möglich, zu initialisieren b mit -1 (ein 4-Byte-Wert)?
Sie liegen etwas falsch mit dem Grund für die Initialisierung mit 0 ist in Ordnung. Es ist in Ordnung, weil 0 passt in ein unsigned char (Daher wird es nicht abgeschnitten, wenn es als zweites Argument für verwendet wird memset) und weil das Bitmuster im Speicher für a sizeof(int)-Byte Null ist identisch mit dem Bitmuster im Speicher für sizeof(int) sequentielle Ein-Byte-Nullen. Beides muss zutreffen, damit dies funktioniert. Tatsächlich gelten diese Dinge für genau zwei Zahlen in der Zweierkomplement-Arithmetik: 0 und -1.
– zol
22. Juli 2015 um 0:36 Uhr
@zwol: Hm? Der erste Satz spricht von Nullen und gilt daher nicht wörtlich für −1. Vermutlich beabsichtigen Sie also, den ersten Satz implizit zu parametrisieren: Es funktioniert für x wenn die Bits für ein int mit Wert x sind die gleichen wie die Bits für sizeof(int)unsigned char jeweils mit Wert x. Darüber hinaus müssen wir die berücksichtigen unsigned char mit Wert x als Ergebnis der Umwandlung von x zu unsigned char, da −1 nicht darstellbar ist. Wenn ja, dann ist es nicht wahr, dass 0 und −1 die einzigen solchen Werte sind. 16.843.009 • x funktioniert für jede ganze Zahl 0 ≤ x < 256. (16.843.009 ist Hex 1010101).
– Eric Postpischil
27. Oktober 2020 um 17:45 Uhr
@zwol: Abgesehen von der Tatsache, dass C die Bitpositionen in Ganzzahlen unterschiedlicher Breite nicht benötigt, um dieselben Werte darzustellen.
– Eric Postpischil
27. Oktober 2020 um 17:48 Uhr
@EricPostpischil Ich verstehe dein Beispiel nicht. Kein Vielfaches von 16.843.009 ist durch einen der darstellbar char Typen (nun, es sei denn, Sie befinden sich auf einer Maschine, auf der CHAR_BIT >= 25.)
– zol
27. Oktober 2020 um 18:12 Uhr
@zwoll: 0x34343434 ist ein Vielfaches von 16.843.009; es ist 0x34 * 0x01010101. int a; memset(&a, 0x34343434, sizeof a); setzt jedes Byte von a zu 0x34. Dann der Wert von a wird sein 0x34343434.
– Eric Postpischil
27. Oktober 2020 um 18:47 Uhr
Sergej Kalinitschenko
Seltsamerweise der Grund, warum dies funktioniert -1 ist genau derselbe wie der Grund, warum dies mit Nullen funktioniert: in Zweierkomplement binäre Darstellung, -1 hat 1s in all seinen Bits, unabhängig von der Größe der Ganzzahl, also Füllen einer Region mit Bytes, die mit all gefüllt sind 1s erzeugt eine Region von -1 unterzeichnet ints, longs, und shorts auf Zweierkomplement-Hardware.
Auf Hardware, die vom Zweierkomplement abweicht, wird das Ergebnis anders sein. Das -1 Integer-Konstante würde in eine konvertiert werden unsigned char ausgerechnet, weil die Norm konkret vorschreibt, wie die Konvertierung durchzuführen ist. Allerdings eine Region von Bytes, bei denen alle ihre Bits auf gesetzt sind 1 würden gemäß den Regeln der Plattform als integrale Werte interpretiert. Beispielsweise würden auf Vorzeichen-und-Größen-Hardware alle Elemente Ihres Arrays den kleinsten negativen Wert des entsprechenden Typs enthalten.
Würde nicht verwenden ~0 effektiv gleich (und klarer) sein?
– Fiddle Bits
13. Juni 2014 um 14:46 Uhr
@FiddlingBits Ja, mit ~0 würde die Verwirrung hier auf jeden Fall vermeiden.
– Sergej Kalinitschenko
13. Juni 2014 um 14:50 Uhr
@hackks Wenn Sie einen Speicherbereich, der a entspricht, mit Nur-Einsen-Bitmustern füllen sizeof von einem ganzzahligen Typ (int, longoder short) und dann diese Region als den entsprechenden ganzzahligen Typ neu interpretieren, würden Sie sehen -1 auf Computern mit Zweierkomplementdarstellung. Beachten Sie, dass Sie in seltenen Fällen, wenn Sie eine Hardware mit Vorzeichengröße haben, die kleinste negative Ganzzahl sehen, die auf dieser Hardware darstellbar ist (ich habe solche Hardware noch nie gesehen, oder sogar eine Person, die erwähnt hat, dass sie solche Hardware gesehen hat, aber ich habe gehört, dass sie existiert) .
– Sergej Kalinitschenko
13. Juni 2014 um 15:08 Uhr
@hackks Du hast recht, mit -1 als “Abkürzung” für ein “Byte gefüllt mit allen Einsen” ist plattformspezifisch. Ich habe einige Klarstellungen hinzugefügt, zusammen mit dem langen Kommentar oben. Vielen Dank!
– Sergej Kalinitschenko
13. Juni 2014 um 15:23 Uhr
@chux Der Standard sagt das, um einen negativen ganzzahligen Wert umzuwandeln unsigned Der Compiler muss die Größe des negativen Werts von 2^N subtrahieren, wobei N die Anzahl der Bits im ganzzahligen Typ ohne Vorzeichen ist. Hier ist N 8, also ist das Ergebnis 256-1=255, ein vorzeichenloser Wert. Auf diese Weise vermieden sie, dass die Prozessimplementierung definiert wurde, ohne dass eine Zweierkomplementdarstellung erforderlich war. Deshalb ist mein Verständnis so -1 unabhängig davon, wie die Negative auf der Zielplattform dargestellt werden, in ein Nur-Einsen-Bitmuster umgewandelt.
– Sergej Kalinitschenko
13. Juni 2014 um 18:44 Uhr
Minhas Kamal
Wenn alle Bits einer Zahl sind 0sein Wert ist auch 0. Allerdings, wenn alle Bits sind 1 der Wert ist -1.
Wenn wir schreiben int a[2], 4×2 Bytes Speicher werden zugewiesen, die Zufalls-/Müllbits enthalten.
Dann schreiben wir memset(a, 0, sizeof(a)). Jetzt, memset() arbeitet Byte für Byte und eine Byte-Darstellung (unsigned char) von 0 ist 00000000. Also wird es-
void *memset( void *dest, int ch, size_t count ); => Kopiert den Wert ch (Nach Umstellung auf unsigned char) in jedes der ersten Zählzeichen des Objekts, auf das gezeigt wird dest.
– Minhas Kamal
27. Oktober 2020 um 18:23 Uhr
14148000cookie-checkWie initialisiert memset ein Array von Ganzzahlen mit -1?yes
Sie liegen etwas falsch mit dem Grund für die Initialisierung mit
0
ist in Ordnung. Es ist in Ordnung, weil0
passt in einunsigned char
(Daher wird es nicht abgeschnitten, wenn es als zweites Argument für verwendet wirdmemset
) und weil das Bitmuster im Speicher für asizeof(int)
-Byte Null ist identisch mit dem Bitmuster im Speicher fürsizeof(int)
sequentielle Ein-Byte-Nullen. Beides muss zutreffen, damit dies funktioniert. Tatsächlich gelten diese Dinge für genau zwei Zahlen in der Zweierkomplement-Arithmetik:0
und-1
.– zol
22. Juli 2015 um 0:36 Uhr
@zwol: Hm? Der erste Satz spricht von Nullen und gilt daher nicht wörtlich für −1. Vermutlich beabsichtigen Sie also, den ersten Satz implizit zu parametrisieren: Es funktioniert für x wenn die Bits für ein
int
mit Wert x sind die gleichen wie die Bits fürsizeof(int)
unsigned char
jeweils mit Wert x. Darüber hinaus müssen wir die berücksichtigenunsigned char
mit Wert x als Ergebnis der Umwandlung von x zuunsigned char
, da −1 nicht darstellbar ist. Wenn ja, dann ist es nicht wahr, dass 0 und −1 die einzigen solchen Werte sind. 16.843.009 • x funktioniert für jede ganze Zahl 0 ≤ x < 256. (16.843.009 ist Hex 1010101).– Eric Postpischil
27. Oktober 2020 um 17:45 Uhr
@zwol: Abgesehen von der Tatsache, dass C die Bitpositionen in Ganzzahlen unterschiedlicher Breite nicht benötigt, um dieselben Werte darzustellen.
– Eric Postpischil
27. Oktober 2020 um 17:48 Uhr
@EricPostpischil Ich verstehe dein Beispiel nicht. Kein Vielfaches von 16.843.009 ist durch einen der darstellbar
char
Typen (nun, es sei denn, Sie befinden sich auf einer Maschine, auf derCHAR_BIT >= 25
.)– zol
27. Oktober 2020 um 18:12 Uhr
@zwoll:
0x34343434
ist ein Vielfaches von 16.843.009; es ist0x34 * 0x01010101
.int a; memset(&a, 0x34343434, sizeof a);
setzt jedes Byte vona
zu0x34
. Dann der Wert vona
wird sein0x34343434
.– Eric Postpischil
27. Oktober 2020 um 18:47 Uhr