Forum: Mikrocontroller und Digitale Elektronik Array in Bereiche aufteilen, struct vermeiden, aber wie


von Hans (Gast)


Lesenswert?

Hallo

Mir steht ein Array zur Verfügung. Dieser beinhaltet verschiedene Werte.
Wenn dieses Array eine bestimmtle Länge hat, möchte ich dieses in 10 
etwa gleich grosse Bereiche einteilen. Sagen wird 10 Bereiche.

also Bereich 1 Index 0-9
Berech 2 Index 10-19 etc. etc.

Jetzt möchte ich aber beim Zugriff auf die Bereiche sagen können:

if ((wert < bereich5.obereGrenze) && (wert > bereich5.untereGrenze))

damit ich gleich sehe, was damit gemeint ist.

Da komme ich um ein struct nicht herum oder? Mit Arrays geht das ja 
nicht.
Oder ist das anders möglich dies zu bewerkstelligen?

von Udo S. (urschmitt)


Lesenswert?

Möchtest du die Array-Zellen in Bereiche einteilen, oder die Werte in 
dem Array?

Wenn ich deine doch ziemlich konfuse Beschreibung lese, dann solltest du 
besser dein eigentliches Problem und nicht deinen dir ausgedachten 
"Algorithmus" zur Lösung beschreiben.

von Dirk B. (dirkb2)


Lesenswert?

Schon mal Pointer probiert?

von da1l6 (Gast)


Lesenswert?

Hallo,

klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info

da1l6

von Hans (Gast)


Lesenswert?

da1l6 schrieb:
> Hallo,
>
> klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info
>
> da1l6


Was für ein freundliches Forum. Hier ist man wohl gleich als Genies zur 
Welt gekommen und alles gleich vom Himmel gefallen.
Danke trotzdem

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Hans schrieb:
> da1l6 schrieb:
>> Hallo,
>>
>> klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info
>>
>> da1l6
>
>
> Was für ein freundliches Forum. Hier ist man wohl gleich als Genies zur
> Welt gekommen und alles gleich vom Himmel gefallen.
> Danke trotzdem

Das nicht, aber eine ausreichende Fähigkeit zum strukturierten Denken 
war eigentlich doch immer vorhanden.
Und bei deiner Aufgabenstellung hätte ich auch lieber das ursprüngliche 
Problem zurück...
WARUM ZUR HÖLLE willst du das Array unterteilen? Gibt es dafür 
irgendeinen nachvollziehbaren Grund?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Man kann z.B. eine Struktur schaffen

typedef struct
{
uint8 Wert1;
uint16 Wert2;
uint32 Wert3;
uint8 DummeZumAuffüllenAuf10Byte;
} st1;

Diese dann mit einem Array überlagern

union
{
  uint8 werte[100];
  st1 Strcturwerte[10];
} u1;

Zugriff wäre dann
u1.werte[0];
u1.Strcturwerte[1].Wert2;

Damit kann man auf die Daten roh zugreifen und per Struktur auf die 
Werte. Syntaktisch ist das vermutlich grad nicht ganz richtig, das wirst 
du schon selbst hin bekommen.

von Hans (Gast)


Angehängte Dateien:

Lesenswert?

Tim T. schrieb:
> Hans schrieb:
>> da1l6 schrieb:
>>> Hallo,
>>>
>>> klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info
>>>
>>> da1l6
>>
>>
>> Was für ein freundliches Forum. Hier ist man wohl gleich als Genies zur
>> Welt gekommen und alles gleich vom Himmel gefallen.
>> Danke trotzdem
>
> Das nicht, aber eine ausreichende Fähigkeit zum strukturierten Denken
> war eigentlich doch immer vorhanden.
> Und bei deiner Aufgabenstellung hätte ich auch lieber das ursprüngliche
> Problem zurück...
> WARUM ZUR HÖLLE willst du das Array unterteilen? Gibt es dafür
> irgendeinen nachvollziehbaren Grund?

Ich habe in 2 verschiedenen Arrays Werte zweier Graphen gespeichert.
Die Kurven sehen zB so wie oben im Bild aus. Zb zwischen den Werten 10 
und 20 soll etwas passieren. Zwischen anderen etwas Anderes. Die genaue 
Einteilung ist mir überlassen.
Ich nutze ein drittes Array worin ich die Indizes festhalte, damit ich 
sie nicht jedes Mal berechnen muss. Zum Beispiel Bereich 1 Index 10 -15. 
Bereich 2 21-32 etc.
Im Array dann zB {0, 5, 10, 15, 20, 25...} kann ich dann auf die 
Grenzwerte zugreifen, anstatt jedes Mal den Index für den Grenzwert zu 
berechnen. Bereich 1 wäre so nun Index 0 bis 1, Bereich 2 Index 10 bis 
15.
Das funktioniert zwar, aber ich müsste dann wie folgt arbeiten, wenn ich 
die Werte zweier Arrays auswerten möchte:

if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) && 
(wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )

Versteht ihr jetzt?
Auf diese Weise sehe ich nicht auf Anhieb, dass es Bereich 1 ist, nur 
daran, dass die Indizes 0 und 1 sind. Wie macht man es in der Praxis?

von Hans (Gast)


Lesenswert?

Hans schrieb:

>
> Ich habe in 2 verschiedenen Arrays Werte zweier Graphen gespeichert.
> Die Kurven sehen zB so wie oben im Bild aus. Zb zwischen den Werten 10
> und 20 soll etwas passieren. Zwischen anderen etwas Anderes. Die genaue
> Einteilung ist mir überlassen.
> Ich nutze ein drittes Array worin ich die Indizes festhalte, damit ich
> sie nicht jedes Mal berechnen muss.
> Im Array dann zB {0, 5, 10, 15, 20, 25...} kann ich dann auf die
> Grenzwerte zugreifen, anstatt jedes Mal den Index für den Grenzwert zu
> berechnen. Bereich 1 wäre so nun Index 0 bis 1, Bereich 2 Index 10 bis
> 15.
> Das funktioniert zwar, aber ich müsste dann wie folgt arbeiten, wenn ich
> die Werte zweier Arrays auswerten möchte:
>
> if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) &&
> (wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )
>
> Versteht ihr jetzt?
> Auf diese Weise sehe ich nicht auf Anhieb, dass es Bereich 1 ist, nur
> daran, dass die Indizes 0 und 1 sind. Wie macht man es in der Praxis?

So sollte es besser verständlich sein

von Achim B. (bobdylan)


Lesenswert?

Hans schrieb:
> Wie macht man es in der Praxis?

In meiner Praxis macht man es so, dass der nächste Patient aufgerufen 
wird, und dann auch "dranne" kommt.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich habe es zwar immer noch nicht so recht verstanden, das könnte ein 
Lösungsansatz sein:

Um schneller was zu errechnen und wenn das Array nicht mehr als 64 
Elemente hat könnte man sich eine Variable mit uint64_t anlegen. Jedes 
mal wenn das Ergebnis zutrifft setzt man da ein Bit, da dieser Typ 64 
Bits hat kann man somit Array Element [0] .. [63] jeweils ein Bit 
zuordnen.
Dann braucht man nur noch die Bits shiften/ausmaskieren um die Position 
zu finden.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

So langsam dämmert es. Also die Grundeigenschaft eines Bereiches ist das 
er sich durch zwei Positionen beschreiben lässt, Anfang und Ende. Ich 
würde dementsprechend diese zwei Informationen paarweise speichern, also 
eine Liste mit den zwei Indizes pro Knoten. Zum durchgehen der Bereiche 
musst du dann nur prüfen ob der Wert an der Stelle des zweiten Index 
größer als dein gesuchter Wert ist, wenn ja bist du im richtigen 
Bereich, wenn nicht zum nächsten Knoten und erneut prüfen.

von Stefan F. (Gast)


Lesenswert?

Tim T. schrieb:
> zwei Positionen beschreiben lässt, Anfang und Ende

Rate mal, was ein Pointer ist, bzw. wie man das Dingsbums nennt, das 
sich zwischen zwei Pointern erstreckt.

von A. S. (Gast)


Lesenswert?

Hans schrieb:
> Da komme ich um ein struct nicht herum oder?

Ja, ein struct, dass zwei integer enthält, begin und end.

Und von diesem struct dann ein Array, so viele Bereiche Du willst, z.b. 
8

struct sBereichsPtr B[8];

if wert2>Array[B[2].begin] ...

von Hans (Gast)


Lesenswert?

A. S. schrieb:
> Hans schrieb:
>> Da komme ich um ein struct nicht herum oder?
>
> Ja, ein struct, dass zwei integer enthält, begin und end.
>
> Und von diesem struct dann ein Array, so viele Bereiche Du willst, z.b.
> 8
>
> struct sBereichsPtr B[8];
>
> if wert2>Array[B[2].begin] ...

Danke für den Tipp

Stefanus F. schrieb:
> Tim T. schrieb:
>> zwei Positionen beschreiben lässt, Anfang und Ende
>
> Rate mal, was ein Pointer ist, bzw. wie man das Dingsbums nennt, das
> sich zwischen zwei Pointern erstreckt.

Wie würde man es mit Pointern machen?
Was meinst du mit dem Dingsbums zwischen 2 Pointern?
Da ist irgend einer Wert bestimmter Grösse zB 1 oder 2 Byte.
Dingsbums wäre dann also 1 oder 2 Byte.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Tim T. schrieb:
>> zwei Positionen beschreiben lässt, Anfang und Ende
>
> Rate mal, was ein Pointer ist, bzw. wie man das Dingsbums nennt, das
> sich zwischen zwei Pointern erstreckt.

Du bist ja ein ganz schlauer.
Und falls du noch mehr Schlaubischlumpf Wissen anbringen willst, köntest 
du mir noch erzählen das der Arrayindex ein Offset relativ zur 
Speicheradresse des ersten Arrayelementes ist, multipliziert mit der 
Elementgröße...

von A. S. (Gast)


Lesenswert?

da1l6 schrieb:
> Hallo,
>
> klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info
>
> da1l6

Max Kanat-Alexander:

> If somebody comes up to you and says something like, “How do I make this pony 
fly to the moon?”, the question you need to ask is, “What problem are you trying 
to solve?” You’ll find out that they really need to collect gray rocks. Why they 
thought they had to fly to the moon, and use a pony to do it, only they know. 
People do get confused like this.

von Stefan F. (Gast)


Lesenswert?

Hans schrieb:
> Wie würde man es mit Pointern machen?
> Was meinst du mit dem Dingsbums zwischen 2 Pointern?

Mit zwei Pointern beschreibst du einen Bereich im Speicher (Anfang und 
Ende).

Ich weiß, dass manche Leute Pointer eklig finden, aber C Entwickler 
müssen damit klar kommen. Ich finde auch Wasser eklig und doch kann ich 
den Kontakt damit nicht ganz vermeiden.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Hans schrieb:
>> Wie würde man es mit Pointern machen?
>> Was meinst du mit dem Dingsbums zwischen 2 Pointern?
>
> Mit zwei Pointern beschreibst du einen Bereich im Speicher (Anfang und
> Ende).
>
> Ich weiß, dass manche Leute Pointer eklig finden, aber C Entwickler
> müssen damit klar kommen. Ich finde auch Wasser eklig und doch kann ich
> den Kontakt damit nicht ganz vermeiden.

Und bringt hier keinerlei Vorteile, ob er sich nun jeweils den Index der 
Anfangs und End Arrayelemente merkt oder die Speicheradresse der beiden 
Elemente, ist hierbei total egal.

von Stefan F. (Gast)


Lesenswert?

Tim T. schrieb:
> Und bringt hier keinerlei Vorteile, ob er sich nun jeweils den Index der
> Anfangs und End Arrayelemente merkt oder die Speicheradresse der beiden
> Elemente, ist hierbei total egal.

Ja, kann man so sehen. Für mich wäre die Nutzung von Pointern einfacher. 
Aber ich bin ja nicht jeder.

von Hans (Gast)


Lesenswert?

Stefanus F. schrieb:
> Tim T. schrieb:
> Und bringt hier keinerlei Vorteile, ob er sich nun jeweils den Index der
> Anfangs und End Arrayelemente merkt oder die Speicheradresse der beiden
> Elemente, ist hierbei total egal.
>
> Ja, kann man so sehen. Für mich wäre die Nutzung von Pointern einfacher.
> Aber ich bin ja nicht jeder.

Könntest du mal win bsp geben?

von Stefan F. (Gast)


Lesenswert?

Hans schrieb:
> Könntest du mal win bsp geben?

Keine Lust. Das sollte in jedem Lehrbuch zu C im Kapitel über Pointer 
oder Buffer stehen.

von Stefan F. (Gast)


Lesenswert?

Ok, einen kleines Beispiel gebe ich Dir:
1
#include <stdio.h>
2
#include <string.h>
3
4
void ausgeben(char* von, char* bis)
5
{
6
    while (von<bis)
7
    {
8
        putchar(*von);
9
        von++;
10
    }
11
}
12
13
int main()
14
{
15
    char text[]="Das ist ein Array, gefüllt mit Zeichen";
16
    
17
    char gesucht[]="ein Array";
18
    char* start=strstr(text,gesucht); 
19
    char* ende=start+strlen(gesucht);
20
    
21
    ausgeben(start,ende);
22
}

Das Schöne an der Funktion ausgeben() ist, dass die keine Ahnung haben 
muss, was sie ausgeben soll. Es muss nicht unbedingt ein Text in diesem 
einen Array sein. Der Text könnte auch ganz woanders stehen.

Zahlreiche Funktionen aus der Standard C Binbliothek machen es etwas 
anders: Sie erwarten einen Zeiger auf den Anfang und dann einen Integer, 
der die Länge angibt.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

&array[4] ist z.B. die Speicheradresse des fünften Wertes, &array[9] die 
des zehnten. Wenn du dir jetzt den Bereich merken willst, kannst du also 
entweder die Indexe 4 und 9 speichern oder die jeweiligen 
Speicheradressen (&array[4] und &array[9]).
Aber zugeben ich bin auch nicht wirklich motiviert dir das jetzt alles 
vorzukauen.

von zitter_ned_aso (Gast)


Lesenswert?

Hans schrieb:
> if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) &&
> (wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )

Laut deiner Skizze liefern die Funktionen steigende / fallende Werte. Du 
prüfst aber so als würden beide Funkionen steigende Werte liefern.

von Hans (Gast)


Lesenswert?

Tim T. schrieb:
> &array[4] ist z.B. die Speicheradresse des fünften Wertes,
> &array[9] die des zehnten. Wenn du dir jetzt den Bereich merken willst,
> kannst du also entweder die Indexe 4 und 9 speichern oder die jeweiligen
> Speicheradressen (&array[4] und &array[9]).
> Aber zugeben ich bin auch nicht wirklich motiviert dir das jetzt alles
> vorzukauen.

schon verstanden, danke

von zitter_ned_aso (Gast)


Lesenswert?

Wenn die Werte in einem Array liegen und aufsteigend sortiert sind, dann 
wäre vielleich so etwas eine Möglichkeit? (einfach Intervallgrenzen in 
einem zweidim. Array ablegen)
1
    //Anzahl der Unterteilungen (Bereiche)
2
    #define ANZ_BER 5
3
    
4
    int arr[]={
5
                1,3, //Bereich 1
6
                4,6,7,8,11, //Bereich 2
7
                13,15,16,18,21,23,26,//Bereich 3
8
                29,32,37,42, //Bereich 4
9
                47,49 //Bereich 5
10
            };
11
    
12
    int indizes[ANZ_BER][2]={
13
                                {0,1},  // linke u. rechte Indizes fuer Bereich 1
14
                                {2,6},  // -||- fuer Bereich 2 
15
                                {7,13}, //usw.
16
                                {14,17},
17
                                {18,19}
18
                            };
19
    
20
    int aktueller_wert=39;
21
22
    for(int i=0; i<ANZ_BER; i++){
23
        
24
        if(aktueller_wert>=arr[indizes[i][0]] && aktueller_wert<=arr[indizes[i][1]]){
25
            printf("%d liegt im Bereich %d\n", aktueller_wert, i+1);
26
        }   
27
    
28
    }

von zitter_ned_aso (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> Hans schrieb:
>> if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) &&
>> (wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )
>
> Laut deiner Skizze liefern die Funktionen steigende / fallende Werte. Du
> prüfst aber so als würden beide Funkionen steigende Werte liefern.

wenn "graph1" rot ist (siehe Skizze), dann solltest du das anders 
testen.
1
if( ((wert1 <= graph1[iArray[0]]) && (wert1 > graph1[iArray[1]])) usw...


Das habe ich gemeint.

Die Funktionswerte von "graph1" (rot) werden ja kleiner.

von Hans (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> Wenn die Werte in einem Array liegen und aufsteigend sortiert
> sind, dann wäre vielleich so etwas eine Möglichkeit? (einfach
> Intervallgrenzen in einem zweidim. Array ablegen)    //Anzahl der
> Unterteilungen (Bereiche)
>     #define ANZ_BER 5
>
>     int arr[]={
>                 1,3, //Bereich 1
>                 4,6,7,8,11, //Bereich 2
>                 13,15,16,18,21,23,26,//Bereich 3
>                 29,32,37,42, //Bereich 4
>                 47,49 //Bereich 5
>             };
>
>     int indizes[ANZ_BER][2]={
>                                 {0,1},  // linke u. rechte Indizes fuer
> Bereich 1
>                                 {2,6},  // -||- fuer Bereich 2
>                                 {7,13}, //usw.
>                                 {14,17},
>                                 {18,19}
>                             };
>
>     int aktueller_wert=39;
>
>     for(int i=0; i<ANZ_BER; i++){
>
>         if(aktueller_wert>=arr[indizes[i][0]] &&
> aktueller_wert<=arr[indizes[i][1]]){
>             printf("%d liegt im Bereich %d\n", aktueller_wert, i+1);
>         }
>
>     }

Die Werte der Graphen können sich bei mir immer leicht ändern.
Das iwo so das Problem. So müsste ich viel zu viel anpasse. Sortiert 
sind sie auch nicht. kann sein dass 2 oder 3 werte hintereinander die 
gleichen sind aber der andere graph die gleichrn indizes betreffend sich 
ändern können.

daher möchte ich die werte in den arrays möglichst nicht anfassen müssen

zitter_ned_aso schrieb:
> zitter_ned_aso schrieb:
> Hans schrieb:
> if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) &&
> (wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )
>
> Laut deiner Skizze liefern die Funktionen steigende / fallende Werte. Du
> prüfst aber so als würden beide Funkionen steigende Werte liefern.
>
> wenn "graph1" rot ist (siehe Skizze), dann solltest du das anders
> testen.if( ((wert1 <= graph1[iArray[0]]) && (wert1 > graph1[iArray[1]]))
> usw...
>
> Das habe ich gemeint.
> Die Funktionswerte von "graph1" (rot) werden ja kleiner.

ach das meinst du
darauf habe ich beim erklären gar nicht geachtet, weil ich noch gar 
nicht so weit bin

von Jobst Q. (joquis)


Lesenswert?

Stefanus F. schrieb:
> Mit zwei Pointern beschreibst du einen Bereich im Speicher (Anfang und
> Ende).

Stefanus F. schrieb:
> Zahlreiche Funktionen aus der Standard C Bibliothek machen es etwas
> anders: Sie erwarten einen Zeiger auf den Anfang und dann einen Integer,
> der die Länge angibt.

Die Lösung mit zwei Pointern bevorzuge ich auch, um einen Pufferbereich 
zu beschreiben. Denn der Endpointer bleibt beim Schreiben in einen 
Puffer immer gleich, während die Länge des noch freien Bereichs immer 
neu berechnet werden muss.

Die Standard C Bibliothek ist in mancher Hinsicht nicht optimal.

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.