include.h
___________________________________________________
typedef struct
{
Uint uifile;
Uint *nnel;
} Block;
extern Block Per[2];
______________________________________END INCLUDE.h
main.c
_____________________________________________________
#include <include.h>
Uint AC[] =
{
10,
20,
};
Uint DC[] =
{
30,
40
};
Block Per[] =
{
{
Ai, AC
},
{
Di, DC
}
};
unsigned short int Get 1(Uint uifile)
{
...........
}
unsigned short int Get 2 (Uint uifile)
{
......
}
__________________________ END MAIN
Get 1 soll folgendes machen. Suche in Block Per[] ob uifile = Ai
vorhanden ist, Wenn ja suche in AC[] nach einer nummer z.B 10 und return
den Index dieser nummer. Oder wenn Ui vorhanden ist in DI[]suchen.
Get 2 soll anhand des festgestellten Index aus get 1 nun rückschliessen
auf die nummer des jewieligen Index. Beispielsweise soll bei Index 1
innerhalb von AC dann die Zahl 20 return werden.
WIe kann man das machen?
Get1 und Get2 passen nicht zueinander. Get1 soll einen Index in per
liefern (für Get2) und einen Index einer Zahl in dem Array per[].nnel
sichten und diesen Index auch zurückliefern. Das sind zwei
Informationen, die zurückzugeben sind. Nur mit einem Index kommt du
nicht an die Zahl ran.
Aber ich könnte mir vorstellen, dass Get1 den Index-aus-Per
zurückliefert, bei dem uifile eingetragen ist.
Ich könnte mir dann vorstellen, dass Get2 den von Get1 ermittelten
Index-von-Per benutzt, um das Array (AC oder DC) zu finden und dessen
Elemente abzuklopfen, ob sie einer gesuchten Zahl entsprechen. Dieser
ware dann Index-in-xC.
Was dir dann noch in der Sammlung fehlt, ist eine Get3, die mit den
Indices aus Get1 (Index-aus-Per ) und Get2 (Index-in-xC) den Wert aus
deinem Datenfeld xC heraus fischt.
Bei der Implementierung brauchst du ausserdem Informationen wie gross
deine Arrays sind. Also musst du entweder die Elementanzahl in []
eintragen oder einen Stopperwert fürs Durchsuchen als letztes Element in
den Arrays eintragen.
Zunächst mal solltest du in die Struktur 'Block' noch die
Größe des Arrays eintragen. Zur Laufzeit ist diese Information
aus einem Block Objekt nicht mehr ableitbar, also muss sie
dort gespeichert werden:
1
typedefstruct
2
{
3
Uintuifile;
4
UintnnelSize;
5
Uint*nnel;
6
}Block;
7
8
9
UintAC[]={10,20};
10
UintDC[]={30,40};
11
12
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x) )
13
14
BlockPer[]=
15
{{Ai,ARRAY_SIZE(AC),AC},
16
{Di,ARRAY_SIZE(DC),DC}
17
};
18
19
//
20
// Suche in Block Per[] ob uifile = Ai
21
// vorhanden ist, Wenn ja suche in AC[] nach einer
22
// nummer z.B 10 und return den Index dieser nummer.
23
//
24
// Return: Index des gesuchten Elements
25
// -1 element nicht gefunden
26
// -2 uifile nicht gefunden
27
//
28
intGet_1(Uintuifile,uintelement)
29
{
30
size_ti,j;
31
32
for(i=0;i<ARRAY_SIZE(Per);++i){
33
34
if(Per[i].uifile==uifile){
35
36
for(j=0;j<Per[i].nnelSize;++j){
37
if(Per[i].nnel[j]==element)
38
returnj;
39
}
40
41
return-1;
42
}
43
}
44
45
return-2;
46
}
47
48
UintGet_2(Uintuifile,intindex)
49
{
50
size_ti;
51
52
for(i=0;i<ARRAY_SIZE(Per);++i){
53
54
if(Per[i].uifile==uifile){
55
if(index<0||index>=Per[i].nnelSize)
56
return0;
57
58
returnPer[i].nnel[index];
59
}
60
}
61
62
return0;
63
}
Für die 2.te Funktion musst du dir noch was überlegen, wie du den
Fehlerfall handhaben willst. Im Moment wird immer 0 retourniert.
Wenn 0 in deinen Daten nicht vorkommt, dann ist das ok, ansonsten
musst du mit dem Returnwert noch was anfangen. Für Get_1 hab ich
mir die Freiheit genommen und den Returnwert von Uint (wie er
eigentlich sein sollte) auf int geändert, damit ich 2 spezielle
Werte als Fehlerindikator durchbringe.
Lars wrote:
> Das habe ich bisher..>> unsigned short int get1 (Uint file, Uint *nnel)> {> Uint ui,uo = 0;
Beachte: ui ist nicht initalisiert
> for (ui;ui<=sizeof Per; ui++)
ui ist nach wie vor nicht initialisiert.
sizeof liefert die Größe des Objektes (in dem Fall Per)
in Bytes. Das kannst du hier nicht brauchen.
> {> if(BlockPer[ui] == file)
Wer oder was ist BlockPer
> {> if (file == Ai)
Warum Ai hier hardcoden. Im Per Array steht doch Ai drinnen.
Du musst das nur auswerten.
> {> nel = &AI[0];> for (ui;ui<=sizeof AI; ui++)
Autsch: Schon wieder ui
> {> nnel++;
Nö. nnel ist ein Pointer (wenn du damit den Pointer in der
Block Struktur meinst).
Den willst du ganz sicher nicht erhöhen. Er ist dein einziger
Pointer zu den Daten. In dem Moment in dem du den veränderst,
ist dein Zugang zu den Daten futsch.
> if(gesuchter_index == nnel)
Pointer mit Index vergleichen?
Das wird wohl so nichts werden
> {> return gesuchter_index;> }> }> }> if (uiProfile == iProfFDi)> {> ... ähnlich wie oben> }>> }> }> }>> geht das?
Nein.
Lars wrote:
> mh kann ich ARRAY_SIZE auch unter C verwenden. Code nicht unter C++ !!!
Mit deinen C-Kenntnissen ist es aber nicht weit her.
ARRAY_SIZE ist ein Makro! Und ich hab im Source Code die
Makro Definition angegeben.
1
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x) )
So kann man korrekt rausfinden, wieviele Elemente ein Array
besitzt, sofern x noch als Array sichtbar ist.
Man könnte es auch so schreiben
1
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]) )
es wird ganz einfach die Gesamtgröße des Arrays in Bytes durch
die Größe eines Elements (ebenfalls in Bytes) dividiert.
Ein Uint Array
Uint a[] = { 1, 2, 3 };
hat eine sizeof von 6 (wenn ich mal den sizeof(Uint) als 2 annehmen).
Das erste Element hat eine sizeof von 2 (weil es ja ein UInt ist),
daher besteht das Array aus 6 / 2 = 3 Elementen
Nachtrag:
Natürlich hättest du die Arraygrößen auch händisch reinschreiben
können. Letztendlich ist es ja egal, wo die Zahl herkommt, ob die
nun vom Compiler berechnet wird oder ob du sie im Quelltext
einträgst.
Aber die Compilerberechnung ist
* bequemer
* weniger anfällig für Fehler
Nehmen wir mal an, das Ganze sehe so aus ...
1
UintAC[]={10,20};
2
UintDC[]={30,40};
3
4
BlockPer[]=
5
{{Ai,2,AC},
6
{Di,2,DC}
7
};
... was ja völlig korrekt wäre.
In 2 Monaten kommst du drauf, dass bei AC noch ein Wert mehr dazu
muss.
1
UintAC[]={10,20,70};
2
UintDC[]={30,40};
3
4
BlockPer[]=
5
{{Ai,2,AC},
6
{Di,2,DC}
7
};
Ooops. Da die Ursprungsversion schon 2 Monate alt ist, kannst du dich
nicht mehr an jedes Detail erinnern. Das in der Definition von Per
die Arraygröße der Arrays einzutragen ist, hast du schon längst
vergessen. Da du das vergessen hast, denkst du auch nicht dran, und
der 2-er bleibt da drinn, obwohl es eigentlich
1
BlockPer[]=
2
{{Ai,3,AC},
3
{Di,2,DC}
4
};
heissen müste. Da dort aber nach wie vor eine 2 eingetragen ist, wird
auch deine Suchschleife die 70 nie finden, da ja die Suchschleife
auf die korrekt eingetragene Anzahl angewiesen ist.
Mit dem Makro kann dir das nicht passieren. Warum? Weil der
Compiler während der Compilezeit den sizeof Ausdruck auswertet.
1
UintAC[]={10,20,70};
2
UintDC[]={30,40};
3
4
BlockPer[]=
5
{{Ai,ARRAY_SIZE(AC),AC},
6
{Di,ARRAY_SIZE(DC),DC}
7
};
wird zu
1
UintAC[]={10,20,70};
2
UintDC[]={30,40};
3
4
BlockPer[]=
5
{{Ai,sizeof(AC)/sizeof(*AC),AC},
6
{Di,sizeof(DC)/sizeof(*DC),DC}
7
};
das wiederrum wird (noch während des Compilierens) zu
1
UintAC[]={10,20,70};
2
UintDC[]={30,40};
3
4
BlockPer[]=
5
{{Ai,6/2,AC},
6
{Di,4/2,DC}
7
};
und daraus folgt dann wieder
1
UintAC[]={10,20,70};
2
UintDC[]={30,40};
3
4
BlockPer[]=
5
{{Ai,3,AC},
6
{Di,2,DC}
7
};
Und damit steht die korrekte Array Größe in der Per Initialisierung,
ohne dass du dich darum kümmern musstest.
Sowas nennt man auch 'defensives Programmieren': Einen etwas
höheren Tippaufwand in Kauf nehmen um sich selbst vor potentiellen
Fehlern zu schützen, die möglicherweise auftreten können/werden.
Ganz abgesehen, dass
1
BlockPer[]=
2
{{Ai,ARRAY_SIZE(AC),AC},
3
{Di,ARRAY_SIZE(DC),DC}
4
};
besser dokumentiert, welche Funktion der 2-te Eintrag hat.
Diese Definition brauch ich mir nur ansehen um zu wissen, was
denn der Sinn der 2-ten Initialisierung eines Block ist.
Wohingegen ich bei
1
BlockPer[]=
2
{{Ai,2,AC},
3
{Di,2,DC}
4
};
nur raten kann (oder in der Struktur nachschauen müsste), was denn
die 2 sein könnten.
Also wenn ich es debuge dann sagt er, dass die Zeile
for( j = 0; j < Per[i].nnelSize; ++j ) {
nicht richtig erreicht wird was daran liegt, das nnelSize keinen Wert
hat. Ich lasse ja jetzt die Schleife durch per laufen sollte ich aber
nicht als die Grösse des Arrays angeben
also
Per[i].nnelSize = ARRAY_SIZE(Per) ?
Lars wrote:
> Also wenn ich es debuge dann sagt er, dass die Zeile>> for( j = 0; j < Per[i].nnelSize; ++j ) {>> nicht richtig erreicht wird was daran liegt, das nnelSize keinen Wert> hat.
Das kann nicht sein. Irgendeinen Wert muss es haben.
> Ich lasse ja jetzt die Schleife durch per laufen sollte ich aber> nicht als die Grösse des Arrays angeben>> also>> Per[i].nnelSize = ARRAY_SIZE(Per) ?
Nein.
Du hast irgendetwas anderes falsch gemacht.
Zeig mal alles.
Lars wrote:
> Fehler gefunden ich habe nach dem if die Klammern vergessen. Jedoch> verstehe ich nicht woher nnelSize seine Grösse bezieht.
Sag ich doch die ganze Zeit: Die steht bereits in der Struktur
drinnen.
Und die steht deshalb drinnen, weil sie hier
Also die erste Function wird nun korrekt durchlaufen und liefert mit den
korrekten Index. Jedoch wird dieser Index nicht in Funktion übergeben,
sonder irgendein "uninitialiserter Wert" 32980.
if( PerBlock[i].nnel[j] == element )
{
index = j;
return index; //Return Index
}
Muss ich den index ausserhalb der ersten Funktion nochmals schreiben
bevor er in die zweite gegeben wird oder speichert er die Variable Index
( auch ausserhalb von beiden Funktionen definiert ) bereits in der
ersten Fkt ab?
Lars wrote:
> Also die erste Function wird nun korrekt durchlaufen und liefert mit den> korrekten Index. Jedoch wird dieser Index nicht in Funktion übergeben,> sonder irgendein "uninitialiserter Wert" 32980.>> if( PerBlock[i].nnel[j] == element )> {> index = j;> return index; //Return Index> }>> Muss ich den index ausserhalb der ersten Funktion nochmals schreiben> bevor er in die zweite gegeben wird oder speichert er die Variable Index> ( auch ausserhalb von beiden Funktionen definiert ) bereits in der> ersten Fkt ab?
Wo kommt denn nun wieder die variable namens 'index' her?
In der ganzen Funktion, wie ich sie eingangs geschrieben habe
???
Poste mal deinen Code.
Schön langsam sieht es danach aus, dass du selbst nicht genau weist
was du willst.
> ich möchte einfach nicht das j returnen sondern einen Index dieser dann> in get2 gegeben wird.
Das ganze nochmal. Aber diesmal im deutschen Satz.
ich mochte das der Index aus der ersten Funktion, also in deinem Code
return j der zweiten Funktion übergeben wird.
ich habe j zu index umgetauft.
Dabei ist der Ablauf so das beide Funktionen von einer anderen Stelle
aufgerufen werden.
Problem: wenn ich "j" return und "j" der zweiten Funktionen übergeben
möchte dann steht das nicht mehr der korrekte errechnete Wert aus
Funktion 1 drinne sondern irgend ein Wert?=
Wie du die Variable innerhalb der Funktion nennst ist doch
völlig wurscht. Nachdem die Funktion verlassen wird existiert
die Variable ja sowieso nicht mehr.
Möglicherweise ist ja das das Problem.
verwendet werden die Funktionen zb so.
int main()
{
int index;
int value;
index = Get_1( Ai, 20 ); // suche nach 20 und erhalte den Index
value = Get_2( Ai, index ); // hole das Element an der Position index
// hier muss value 20 sein
// der Get_1 hat bestimmt wo in Ai ein Element mit dem Wert 20
// steht. Als Ergebnis liefert Get_1 eine 1 zurück um anzugeben
// dass AC[1] gleich 20 ist.
//
// Die Umkehrfunktion Get_2 besorgt den Wert aus AC (indem
// Ai angegeben wurde. Da index, der 2-te Parameter, der in
// die Funktion hineingeht, den Wert 1 hat, liefert die Funktion
// Get_2 den Wert von AC[1]. Und dieser ist 20
}
Lars wrote:
> ich mochte das der Index aus der ersten Funktion, also in deinem Code> return j der zweiten Funktion übergeben wird.
Ja dann mach das doch.
Die Funktion Get_1 liefert den Wert. Den fängst du in einer
Variablen auf und übergibst in an die 2-te Funktion
> ich habe j zu index umgetauft.
Namen sind Schall und Rauch.
Mir scheint du bastelst da irgendeine Beziehung zwischen den
Funktionen. Es gibt keine! Die Funktionen arbeiten auf serselben
Datenstruktur. Aber mehr als das haben die beiden nicht gemeinsam.
>> Dabei ist der Ablauf so das beide Funktionen von einer anderen Stelle> aufgerufen werden.>> Problem: wenn ich "j" return und "j" der zweiten Funktionen übergeben> möchte dann steht das nicht mehr der korrekte errechnete Wert aus> Funktion 1 drinne sondern irgend ein Wert?=
Zeig die Stelle des Aufrufs.
> Get1 (uifile, element);> index=j;> Get2(uifile, index);
Und was ist mit dem Returnwert?
Get1 liefert einen Wert!!!!!!
genau den Wert den du haben willst
index = Get1( uifile, element);
Steck doch bitte deine Nase in ein C-Grundlagenbuch!
Das sind absolute Basics.