Forum: Compiler & IDEs Statische 2D Char Arrays mit verschiedenen Größen
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
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
und nicht
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
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
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.
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.
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 | }
|
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 | }
|
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.
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.
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.
|