Hat jemand eine Möglichkeit, ein Array von zu initialisieren ints (jeder Multi-Byte-Typ ist wirklich in Ordnung), einfach auf einen Wert ungleich Null und ungleich -1? Gibt es eine Möglichkeit, dies in einem Einzeiler zu tun, ohne jedes Element einzeln ausführen zu müssen:
int arr[30] = {1, 1, 1, 1, ...}; // that works, but takes too long to type
int arr[30] = {1}; // nope, that gives 1, 0, 0, 0, ...
int arr[30];
memset(arr, 1, sizeof(arr)); // That doesn't work correctly for arrays with multi-byte
// types such as int
Nur zu Ihrer Information, mit memset() auf diese Weise gibt es auf statischen Arrays:
for(count = 0; count < 30; count++)
arr[count] = 1; // Yup, that does it, but it's two lines.
Hat jemand andere Ideen? Solange es sich um C-Code handelt, sind der Lösung keine Grenzen gesetzt. (andere Bibliotheken sind in Ordnung)
es gibt wmemset() für “breite” char-Arrays
– Markus B
20. November 2012 um 16:10 Uhr
würden andere Bibliotheken nicht > 1 Zeile benötigen? #include libother
– mcalex
20. November 2012 um 16:12 Uhr
@MarcB – Nicht schlecht … zwei kleinere Probleme, zuerst verstehe ich wchar_t is compiler-specific and can be as small as 8 bits Das könnte also ein einzelnes Byte sein. Zweitens hatte ich auf etwas gehofft, das bei verschiedenen Typen funktionieren könnte. Aber kein schlechter Vorschlag. Vielen Dank.
– Mike
20. November 2012 um 16:18 Uhr
Mac OS X hat memset_pattern4(), memset_pattern8() und memset_pattern16() seit Version 10.5.
– Pascal Cuoq
20. November 2012 um 16:19 Uhr
@mcalex – Touché. Ok, wie wäre es mit “1 Liner pro Einstellung”, wir zählen nicht #includes oder mehr Optionen zu gcc
– Mike
20. November 2012 um 16:19 Uhr
iabdalkader
Dies ist eine GCC-Erweiterung:
int a[100] = {[0 ... 99] = 1};
Das ist genial, die Syntax war mir nicht bewusst. +1
– Mike
20. November 2012 um 19:00 Uhr
Hinweis für alle anderen, die dies verwenden, es gibt Leerzeichen zwischen den Ziffern und dem ... Was wichtig ist
– Mike
20. November 2012 um 19:04 Uhr
@Mike überprüfen Sie den Link, Sie können auch mehrere Bereiche und einzelne Elemente initialisieren.
– iabdalkader
20. November 2012 um 19:23 Uhr
Korrigieren Sie mich, wenn ich falsch liege, aber ausgewiesene Initialisierer in der C-Sprache sind: typedef struct { int x; int y} type; dann type t = { .x=1, .y=2 }; Ich habe die Notation .. noch nie gesehen oder gehört, dass sie als designierter Initialisierer bezeichnet wird. Ich glaube, dies ist eine GCC-Erweiterung, die über Standard-C-Initialisierer hinausgeht.
– Ludin
21. November 2012 um 7:49 Uhr
@Lundin, es ist eine GCC-Erweiterung, wie ich bereits erwähnt habe, und sie ist im Link unten beschrieben Ausgewiesene Initialisierer Sektion. Meine Antwort wurde bearbeitet, ich bin mir nicht sicher, wie sie heißt, aber ich denke, vielleicht ist “Range Initializer” besser geeignet?
Sie können auch Ihr gesamtes C-Programm in einer einzigen Zeile schreiben. Wenn jemand eine Begründung dafür liefern könnte, wie das Sinn macht, würde ich mich freuen, es zu hören.
– Ludin
21. November 2012 um 12:30 Uhr
Lundin
Der einzig sinnvolle Weg, dies während der Initialisierung (und nicht zur Laufzeit) zu tun, scheint zu sein:
Und als nächstes, #define ONE2 2 usw. Du hast die Idee.
BEARBEITEN: Der Grund, warum ich so viele Makros geschrieben habe, war, zu demonstrieren, wie flexibel diese Lösung ist. Für diesen speziellen Fall brauchen Sie nicht alle. Aber mit solchen Makros können Sie schnell und flexibel jede Art von Initialisierungsliste schreiben:
{
FIFTY1, FIFTY2, // 1,1,1,1... 50 times, then 2,2,2,2... 50 times
TWENTY3, EIGHTY4 // 3,3,3,3... 20 times, then 4,4,4,4... 80 times
... // and so on
};
AnT steht zu Russland
In C entwickeln Sie normalerweise Ihre eigene “Unterstützungsbibliothek” mit Makros wie
#define SET_ALL(a_, n_, v_)\
do { size_t i, n = (n_); for (i = 0; i < n; ++i) (a_)[i] = (v_); } while(0)
#define SET_ALL_A(a_, v_) SET_ALL(a_, sizeof(a_) / sizeof *(a_), v_)
#define ZERO_ALL(a_, n_) SET_ALL(a_, n_, 0)
#define ZERO_ALL_A(a_) SET_ALL_A(a_, 0)
und verwenden Sie sie dann in Ihrem Code als
int arr[30];
SET_ALL_A(arr, 1);
Das ist eigentlich ein wirklich wichtiger Punkt, warum ich nicht daran gedacht habe, nur ein Makro einzuschließen, um sich darum zu kümmern, ist mir schleierhaft …
– Mike
20. November 2012 um 17:24 Uhr
Wenn Sie ein ekliges Makro wie dieses erstellen, warum schreiben Sie nicht tatsächlich eines initialisieren das Array, anstatt es in der Laufzeit so zu setzen? Angenommen, “arr” hat eine statische Speicherdauer und Sie möchten die speziellen Initialisierungsregeln für solche Variablen nutzen (sie werden initialisiert, bevor main aufgerufen wird).
– Ludin
21. November 2012 um 12:27 Uhr
@Lundin: Wenn mir eine C-Funktion bekannt wäre, die es mir ermöglichen würde initialisieren das Array wie gewünscht, ich würde es verwenden. Aber leider habe ich keine Ahnung wie ich das machen soll. Ich sehe das obige “eklige Makro” als das Beste, was in C verfügbar ist. Wenn Sie etwas Besseres vorschlagen können, bin ich ganz Ohr.
– AnT steht zu Russland
21. November 2012 um 16:01 Uhr
Archie
Eine Zeile mit Zeigern!
for (int *p = a; p < (a + 30); p++) *p = 1;
Oder wenn du es bist vorzeitig Angst vor Leistungseinbußen durch wiederholtes Rechnen (a + 30):
for (int *p = a + 30 - 1; p >= a; p--) *p = 1;
Das ist eigentlich ein wirklich wichtiger Punkt, warum ich nicht daran gedacht habe, nur ein Makro einzuschließen, um sich darum zu kümmern, ist mir schleierhaft …
– Mike
20. November 2012 um 17:24 Uhr
Wenn Sie ein ekliges Makro wie dieses erstellen, warum schreiben Sie nicht tatsächlich eines initialisieren das Array, anstatt es in der Laufzeit so zu setzen? Angenommen, “arr” hat eine statische Speicherdauer und Sie möchten die speziellen Initialisierungsregeln für solche Variablen nutzen (sie werden initialisiert, bevor main aufgerufen wird).
– Ludin
21. November 2012 um 12:27 Uhr
@Lundin: Wenn mir eine C-Funktion bekannt wäre, die es mir ermöglichen würde initialisieren das Array wie gewünscht, ich würde es verwenden. Aber leider habe ich keine Ahnung wie ich das machen soll. Ich sehe das obige “eklige Makro” als das Beste, was in C verfügbar ist. Wenn Sie etwas Besseres vorschlagen können, bin ich ganz Ohr.
– AnT steht zu Russland
21. November 2012 um 16:01 Uhr
Neugieriger Hase
Für die Initialisierung auf einen statischen Wert habe ich im Allgemeinen erwogen, ihn vorzuziehen, wie in:
int arr[30] = {1, 1, 1, 1, ...};
In diesem Fall kann der Compiler eine optimierte Initialisierung im Präambelcode ausspucken (und tut dies normalerweise auch).
Manchmal ist die Initialisierung dynamischer, wie in diesem Beispiel:
int arr[30];
int x = fetchSomeValue();
for(int i=0; i<30; i++) arr[i] = x;
In diesen Fällen müssen Sie es codieren, und die allgemeine Regel lautet, die Lesbarkeit zu maximieren, nicht die Tipparbeit zu minimieren. Dieser Code wird einmal geschrieben und mehrmals gelesen.
13885000cookie-checkInitialisieren eines Arrays von Intsyes
es gibt wmemset() für “breite” char-Arrays
– Markus B
20. November 2012 um 16:10 Uhr
würden andere Bibliotheken nicht > 1 Zeile benötigen?
#include libother
– mcalex
20. November 2012 um 16:12 Uhr
@MarcB – Nicht schlecht … zwei kleinere Probleme, zuerst verstehe ich
wchar_t is compiler-specific and can be as small as 8 bits
Das könnte also ein einzelnes Byte sein. Zweitens hatte ich auf etwas gehofft, das bei verschiedenen Typen funktionieren könnte. Aber kein schlechter Vorschlag. Vielen Dank.– Mike
20. November 2012 um 16:18 Uhr
Mac OS X hat
memset_pattern4()
,memset_pattern8()
undmemset_pattern16()
seit Version 10.5.– Pascal Cuoq
20. November 2012 um 16:19 Uhr
@mcalex – Touché. Ok, wie wäre es mit “1 Liner pro Einstellung”, wir zählen nicht
#includes
oder mehr Optionen zugcc
– Mike
20. November 2012 um 16:19 Uhr