Initialisieren eines Arrays von Ints

Lesezeit: 6 Minuten

Mikes Benutzeravatar
Mike

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:

arr[0] = 0x01010101
arr[1] = 0x01010101
arr[2] = 0x01010101

Die andere Möglichkeit:

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

Benutzeravatar von iabdalkader
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?

    – iabdalkader

    21. November 2012 um 7:57 Uhr

for (count = 0; count < 30; count++) arr[count] = 1;

Eine Linie. 🙂

  • One line. :) sehr wahr… mit dieser lösung wurde der buchstabe des gesetzes eingehalten

    – Mike

    20. November 2012 um 17:29 Uhr

Benutzeravatar von Omkant
Omkant

Sie haben etwas über 2 Zeilen gesagt, aber Sie können es in einer Zeile mit Komma tun ,Operator.

for(count = 0; count < 30 ; arr[count] = 1,count++);

  • Ich mag diese Lösung eigentlich, die , Betreiber ist so unbenutzt.

    – Mike

    20. November 2012 um 17:30 Uhr

  • Welcher Kommaoperator ist so ungenutzt? Ich habe dich nicht verstanden.

    – Omkant

    20. November 2012 um 17:35 Uhr

  • Ich formuliere anders: “Ich mag diese Lösung, weil sie den Kommaoperator verwendet, und die Leute verwenden das nicht genug.”

    – Mike

    20. November 2012 um 17:48 Uhr

  • Alternative: for(count = 0; count < 30; arr[count++] = 1);

    – Hammar

    21. November 2012 um 5:27 Uhr


  • 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

Benutzeravatar von Lundin
Lundin

Der einzig sinnvolle Weg, dies während der Initialisierung (und nicht zur Laufzeit) zu tun, scheint zu sein:

#define ONE1     1
#define FIVE1    ONE1, ONE1, ONE1, ONE1, ONE1
#define TEN1     FIVE1, FIVE1
#define TWENTY1  TEN1, TEN1
#define FIFTY1   TWENTY1, TWENTY1, TEN1
#define HUNDRED1 FIFTY1, FIFTY1

int array [100][4] =
{
  HUNDRED1,
  HUNDRED1,
  HUNDRED1,
  HUNDRED1
};

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 mit Russlands Benutzer-Avatar
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


Archies Benutzeravatar
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


Benutzeravatar von CuriousRabbit
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.

1388500cookie-checkInitialisieren eines Arrays von Ints

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy