Forum: Compiler & IDEs Statische 2D Char Arrays mit verschiedenen Größen


von Werner D. (werner_d350)


Lesenswert?

Hi, kann man statische 2D Char Arrays mit verschiedenen Größen 
definieren ?
Normalerweise sind die Größen immer gleich, also z.B. char a[5][10].
Also 5 Char Arrays mit jeweils 10 Chars.

Kann ich jetzt die ersten 2 Char Arrays mit 100 Bytes deklarieren ?
So daß
sizeof(a[0]) = 100
sizeof(a[1]) = 100
sizeof(a[2]) = 10
sizeof(a[3]) = 10
sizeof(a[4]) = 10

Ich möchte keine dyn. Arrays auf dem Heap haben.

Viele Grüße
Werner

von Michael B. (laberkopp)


Lesenswert?

Werner D. schrieb:
> Kann ich jetzt die ersten 2 Char Arrays mit 100 Bytes deklarieren ?
1
char a1[100],a2[100],a3[10],a4[10],a5[10];
2
char (*a)[5]={a1,a2,a3,a4,a5};
Zugriff mit
1
a[x][y]
und nicht
1
a[x,y]

von Werner D. (werner_d350)


Lesenswert?

Michael B. schrieb:
> char a1[100],a2[100],a3[10],a4[10],a5[10];
> char (*a)[5]={a1,a2,a3,a4,a5};

Funktioniert das auch unter c++ ?
Ich bekomme da ein Compiler Fehler error: scalar object 'a' requires one 
element in initializer

von Mikro 7. (mikro77)


Lesenswert?

Michael B. schrieb:
> char (*a)[5]= ...
Das wäre ein pointer auf ein array mit 5 chars.

Es sollte wohl heißen:
1
char *a[5]={a1,a2,a3,a4,a5};

Der sizeof operator funktioniert damit allerdings nicht so wie du dir 
das wünschst:

Werner D. schrieb:
> Kann ich jetzt die ersten 2 Char Arrays mit 100 Bytes deklarieren ?
> So daß
> sizeof(a[0]) = 100
> sizeof(a[1]) = 100
> sizeof(a[2]) = 10
> sizeof(a[3]) = 10
> sizeof(a[4]) = 10

von Werner D. (werner_d350)


Lesenswert?

Mikro 7. schrieb:
> Es sollte wohl heißen:char *a[5]={a1,a2,a3,a4,a5};

Da waren sie wieder, die Probleme mit den Pointern :))

Danke, compilieren hat schon mal funktioniert. Muß ich mir nur überlegen 
was ich anstelle von sizeof mache.

von Harald K. (kirnbichler)


Lesenswert?

Werner D. schrieb:
> Muß ich mir nur überlegen
> was ich anstelle von sizeof mache.

Na, was willst Du erreichen?

Willst Du zur Laufzeit herausfinden, wie groß Deine Arrays sind, und das 
nur aus a[] heraus?

Das könntest Du mit einem zusätzlichen Array erreichen:
1
char a1[100],a2[100],a3[10],a4[10],a5[10];
2
char *a[5]={a1,a2,a3,a4,a5};
3
char s[5]={sizeof(a1),sizeof(a2),sizeof(a3),sizeof(a4),sizeof(a5)};

(Übrigens kann bei der Arraydefinition für a[] und s[] die 5 weggelassen 
werden, der Compiler kann selbst zählen und bestimmt die Anzahl der 
Arrayelemente aus der Anzahl der Initialisierer)

Beitrag #7467950 wurde von einem Moderator gelöscht.
von Wilhelm M. (wimalopaan)


Lesenswert?

Du fragst nach C++? Dann nimm std::array<>. Weil nun unterschiedlich 
große Arrays jeweils unterschiedliche DT haben, kann man die Arrays oder 
Zeiger darauf nicht in einem anderen weiteren homogenen Container 
speichern. Da kommt std::variant<> ins Spiel. Zwar könnte man auf die 
Zeiger verzichten und die Array-Typen zu den Parametern des 
std::variant<> machen, was aber ungünstig ist, weil dann der 
Speicherbedarf steigt (std::variant<> ist eine type-safe-union). Also 
nimmt man Zeiger.
1
#include <cstdint>
2
#include <array>
3
#include <variant>
4
5
using a1_t = std::array<char, 100>;
6
using a2_t = std::array<char, 10>;
7
using v_t = std::variant<a1_t*, a2_t*>;
8
9
a1_t a1;
10
a1_t a2;
11
a2_t a3;
12
a2_t a4;
13
a2_t a5;
14
15
int main() {
16
    std::array<v_t, 5> aa{&a1, &a2, &a3, &a4, &a5};
17
18
    uint16_t l = 0;
19
20
    for(auto& e: aa) {
21
        std::visit([&](auto&& a){
22
            l += a->size();
23
        }, e);
24
    }
25
    return l;
26
}

von Wilhelm M. (wimalopaan)


Lesenswert?

Und wenn Du die Große der Arrays nicht als Compile-Zeit-Konstante 
benötigst, kannst Du auch gut ein std::span<> nehmen:
1
#include <cstdint>
2
#include <array>
3
#include <variant>
4
#include <span>
5
6
using a1_t = std::array<char, 100>;
7
using a2_t = std::array<char, 10>;
8
9
a1_t a1;
10
a1_t a2;
11
a2_t a3;
12
a2_t a4;
13
a2_t a5;
14
15
int main() {
16
    uint16_t l{};
17
18
    std::array<std::span<char>, 5> bb{a1, a2, a3, a4, a5};
19
    for(const auto& s: bb) {
20
        l += s.size();
21
    }
22
23
    return l;
24
}

von Daniel A. (daniel-a)


Lesenswert?

In C ist dies nicht möglich. Aber normalerweise braucht man sowas auch 
nicht. Dann packt man hat 2 Arrays in ein Struct.
1
struct {
2
  char a[5][10];
3
  char b[2][100];
4
} x;

Oder man macht sich eine Funktion (ungetestet):
1
#define SIZES X(5,10) X(2,100)
2
#define X(a,b) a*b+
3
typedef char specialarray_t[SIZES 0]
4
#undef X
5
size_t get_entry(char** ret, specialarray_t array, size_t index){
6
#define X(a,b) \
7
  if(index < a){ \
8
    *ret = array + index * b; \
9
    return b; \
10
  } \
11
  array += a*b; \
12
  index -= a;
13
  SIZES
14
#undef X
15
  *ret = 0;
16
  return 0;
17
}
18
#undef SIZES

Oder man speichert sich die Grösse auch noch irgendwo in der 
Datenstruktur ab. Kommt halt ganz drauf an, was man damit machen will.

von Rolf M. (rmagnus)


Lesenswert?

Harald K. schrieb:
> Willst Du zur Laufzeit herausfinden, wie groß Deine Arrays sind, und das
> nur aus a[] heraus?
>
> Das könntest Du mit einem zusätzlichen Array erreichen:

Da man Arrays aus char eh nur für Text verwenden sollte, kann man dann 
auch gleich die in C übliche Nullterminierung verwenden und hat dann 
auch die Länge und kann die ganzen Stringfunktionen von C verwenden.

von Werner D. (werner_d350)


Lesenswert?

Vielen Dank für die ganzen Antworten.
Ich habe es jetzt so gemacht wie Harald/Mikro 7/Michael es beschrieben 
hat. War am einfachsten in die bestehende Programmierung einzubinden ( 
Die war etwas umständlich)
Ich brauchte eine Funktion ähnlich der split-Funktion in JS und dazu 
brauche ich ein Array von char-Arrays (Strings).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.