[Pascal] Pointers in array

Pagina: 1
Acties:

  • Shook
  • Registratie: Februari 2001
  • Laatst online: 29-09-2024
Ik ben bezig met het maken van een een array bestaande uit pointers. Ik weet hoe ik een array moet maken, ook hoe je pointers aanmaakt. Ik kan ook al een nieuwe pointer aanmaken, en deze linken aan een array. Nu kan ik het alleen nog niet oproepen.

De opdracht is een array van studenten, en elke student heeft een vakken pakket. De hoeveelheid vakken is variabel en ik moet dus straks instaat kunnen zijn, om ze weg te halen en bij te voegen.

De code tot nu toe:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
program vakkon;
uses wincrt;

type verwijzing = ^vakken;
     vakken = record
     vak:string;
     link:verwijzing;
     end;

     student = array [1..10] of verwijzing;



var  studenten:student;
     vak1:verwijzing;

begin
new (vak1);
vak1^.vak:='Duits';
studenten[1] := vak1;

writeln (studenten[1].vak);
end.


De aanroep van de writeln werkt dus niet.

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 22-08 17:59

Knutselsmurf

LED's make things better

dat moet worden studenten[1]^.vak

studenten[1] is tenslotte een pointer.....

- This line is intentionally left blank -


  • Shook
  • Registratie: Februari 2001
  • Laatst online: 29-09-2024
ach nee, ik meende dat absoluut geprobeerd te hebben. Snap er niks van.....Ja, snap het wel, maar dat het eerder niet werkte. Had vast iets anders fout. Knutselsmurf bedankt.

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01:25

Tomatoman

Fulltime prutser

Je hebt trouwens een memory leak, want na New geef je het gealloceerde geheugen nergens meer vrij.

Een goede grap mag vrienden kosten.


  • Shook
  • Registratie: Februari 2001
  • Laatst online: 29-09-2024
Ik ben nog bezig met hetzelfde programma, stukje verder en ik krijg die pointers niet helemaal goed. Ik heb nu de volgende code:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
program StudDatabase;
uses wincrt;

type verwijzing = ^vakken;
     vakken = record
     vak:string;
     link:verwijzing;
     end;

     student = array [1..10] of verwijzing;

     database = object
                studenten:student;
                hulpPointer:verwijzing;
                getal,i:integer;
                vak2,vak3,vak4,vak5,vak6:string;
                antwoord:char;

                constructor init;
                procedure voegStudentToe;
                procedure haalStudentWeg;
                procedure voegVakToe;
                procedure laatVakZien;
                procedure overzicht;
                end;

Constructor database.init;
begin
getal:=0;
While getal <= 10 do
      begin
           Studenten[getal]:=NIL;
           getal:=getal+1;
      end;
end;


procedure database.overzicht;
begin
getal:=1;
While getal <= 10 do
    begin
         writeln('Student nmr: ',getal,' heeft de volgende vakken:');
         if studenten[getal]^.link = nil then
         begin
         write(studenten[getal]^.vak,' ');
         end;
         if studenten[getal]^.link^.link = nil then
         begin
         write(studenten[getal]^.vak,' ');
         write(studenten[getal]^.link^.vak,' ');
         end;
         if studenten[getal]^.link^.link^.link = nil then
         begin
         write(studenten[getal]^.vak,' ');
         write(studenten[getal]^.link^.vak,' ');
         write(studenten[getal]^.link^.link^.vak,' ');
         end
         else
         begin
         writeln('De student heeft 0 of meer dan 3 vakken');
         end;
         getal:=getal+1;
    end;
    
end;

procedure database.voegStudentToe;
begin
     writeln('U wilt een student toevoegen');
     writeln('Geeft het nummer dat u aan de student wil toevoegen');
     readln(getal);
     new (hulpPointer);
     hulpPointer^.vak:='Nederlands';
     hulpPointer^.link:=nil;
     studenten[getal]:=hulpPointer;
     dispose (hulpPointer);
     Writeln('Student nmr ',getal, ' heeft al 1 Vak, Nederlands (dit is namelijk verplicht)');
end;

Procedure database.voegVakToe;
          begin

          antwoord:='j';

              new(studenten[getal]);
              
              writeln('Geef het nummer van de student');
              readln(getal);

          while antwoord = 'j' do
              begin
              writeln('Geef het vak');
              readln(vak2);
              
              new(hulppointer);
              hulppointer^.vak:=(vak2);
              hulppointer^.link:=studenten[getal];
              studenten[getal]:=hulppointer;
              dispose(hulppointer);

              writeln('nog een vak toevoegen? (j/n)');
              readln(antwoord);
              end;

              writeln(studenten[getal]^.vak);
              writeln(studenten[getal]^.link^.vak);
          end;

procedure database.laatVakZien;
Begin
     Writeln('Van welke student wilt u de vakken zien?');
     readln(getal);
     if studenten[getal]^.link = nil then
         begin
              write(studenten[getal]^.vak,' ');
         end;
         if studenten[getal]^.link^.link = nil then
            begin
                 write(studenten[getal]^.vak,' ');
                 write(studenten[getal]^.link^.vak,' ');
            end;
            if studenten[getal]^.link^.link^.link = nil then
               begin
                    write(studenten[getal]^.vak,' ');
                    write(studenten[getal]^.link^.vak,' ');
                    write(studenten[getal]^.link^.link^.vak,' ');
               end
     else
         begin
             writeln('De student heeft 0 of meer dan 3 vakken');
         end;
             getal:=getal+1;
end;

procedure database.haalStudentWeg;
begin
     writeln('U wilt een student weghalen');
     writeln('Geeft het nummer dat u aan de student wil toevoegen');
     readln(getal);
     studenten[getal]:=nil;
     Writeln('Student nmr ',getal, ' bestaat niet meer');
end;


var d:database;
    getal2,antwoord1:integer;
    antwoord:char;

begin
d.init;
antwoord:='j';
     while antwoord = ('j') do
           begin
                writeln('Er is/zijn momenteel ',getal2,' studenten in de database');
                writeln;
                writeln('Wilt u - 1. een student toevoegen');
                writeln('Wilt u - 2. een student weghalen');
                writeln('Wilt u - 3. een vak toevoegen/verwijderen bij een student');
                writeln('Wilt u - 4. De vakken van een student bekijken?');
                writeln('Wilt u - 5. Een overzicht van alle studenten en hun vakken');
                writeln('Wilt u - 6. Afsluiten');
                writeln;
                Writeln('Maak uw keuze');
                readln(antwoord1);

                                  if antwoord1 = 1 then
                                  d.voegStudentToe;
                                  If antwoord1 = 2 then
                                  d.haalStudentWeg;
                                  If antwoord1 = 3 then
                                  d.voegVakToe;
                                  If antwoord1 = 4 then
                                  d.laatVakZien;
                                  If antwoord1 = 5 then
                                  d.overzicht;
                                  If antwoord1 = 6 then
                                  antwoord:='n';

     Writeln('Wilt u nogmaals een actie uitvoeren? (J/N)');
     Readln(antwoord);
     end;
end.


Hij parst alles, alleen alles wat ik doe met de pointers in de linked list. Daar krijg ik een foutmelding van windows. Uiteraard iets met het geheugen, maar dat is logisch. Mijn vragen zijn de volgende (losstaand van, wtf doe ik fout):

Als ik vakken in de linked list smijt, en ik wil ze dan zien, dan kan hij er niet door heen. Ik heb eigenlijk ook geen idee hoe je op een nette manier de gegevens van een linked list kan tonen. (als er meerdere items inzitten dan). Alvast bedankt!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 22-08 17:59

Knutselsmurf

LED's make things better

Shook schreef op 28 April 2003 @ 16:05:
Ik ben nog bezig met hetzelfde programma, stukje verder en ik krijg die pointers niet helemaal goed. Ik heb nu de volgende code:
8< 8<

Als ik vakken in de linked list smijt, en ik wil ze dan zien, dan kan hij er niet door heen. Ik heb eigenlijk ook geen idee hoe je op een nette manier de gegevens van een linked list kan tonen. (als er meerdere items inzitten dan). Alvast bedankt!
Het bekijken van de elementen in een linked-list is eigenlijk heel eenvoudig. Je moet de volgende stappen volgen:

Als eerste laat je een pointer wijzen naar je eerste element. Deze noemen we ff P.

Zolang deze pointer niet NIL is, voer je de volgende operaties uit:
- doe wat je moet doen met P^.whatever.gegevens.
- P:=P^.next; <- Je schuift je huidige element in je lijst 1 plaats op.

En dat was het eigenlijk al.....

- This line is intentionally left blank -


  • Shook
  • Registratie: Februari 2001
  • Laatst online: 29-09-2024
De code zou zijn, zoals je het benoemt:

while studenten[getal]^.link <> nil do
writeln(studenten[getal]^.vak);
studenten[getal]:=studenten^.link;

Dat snap ik, en was ik idd nog niet opgekomen. Het probleem is nu, dat hij geen resultaten geeft. Als ik bijvoorbeeld 3 vakken heb ingevoerd bij student nummer 6, en die vraag ik later op. Dan springt ie in een infinite loop met alleen maar lege regels. Ik snap niet waarom hij niet kan weergeven wat er in zit (er zit waarschijnlijk niks in); Het zit hem in het vullen van de linked list, maar wat het nou is...

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 16:19

Robtimus

me Robtimus no like you

Shook schreef op 28 April 2003 @ 18:26:
De code zou zijn, zoals je het benoemt:
code:
1
2
3
4
5
while studenten[getal]^.link <> nil do
begin
    writeln(studenten[getal]^.vak);
    studenten[getal]:=studenten^.link;
end;
Even een infinite loop voorkomen :)

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 22-08 17:59

Knutselsmurf

LED's make things better

In je code voor het toevoegen van een student zit een fout.
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
procedure database.voegStudentToe;
begin
     writeln('U wilt een student toevoegen');
     writeln('Geeft het nummer dat u aan de student wil toevoegen');
     readln(getal);
     new (hulpPointer);
     hulpPointer^.vak:='Nederlands';
     hulpPointer^.link:=nil;
     studenten[getal]:=hulpPointer;
     dispose (hulpPointer);
     Writeln('Student nmr ',getal, ' heeft al 1 Vak, Nederlands (dit is namelijk verplicht)');
end;

De dispose is hier fout. Daarmee geef je namelijk die geheugenruimte weer vrij !! Dat moet dus pas als je een student weghaalt.

- This line is intentionally left blank -


  • Shook
  • Registratie: Februari 2001
  • Laatst online: 29-09-2024
Voor zover ik weet staat de dispose prima, de hulppointer mag wel weg, de informatie is al gelinkt aan de studenten[getal]

Het weghalen, loste het probleem ook niet op, op een of andere manier komt er gewoon niks in de array. Ik heb de code bijna letterlijk (alleen andere variabele-namen) uit Savitch gehaald.

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01:25

Tomatoman

Fulltime prutser

Shook schreef op 28 April 2003 @ 16:05:
Ik ben nog bezig met hetzelfde programma, stukje verder en ik krijg die pointers niet helemaal goed. Ik heb nu de volgende code:
Delphi:
10
     student = array [1..10] of verwijzing;
Delphi:
27
28
29
30
31
32
33
34
35
Constructor database.init;
begin
getal:=0;
While getal <= 10 do
      begin
           Studenten[getal]:=NIL;
           getal:=getal+1;
      end;
end;
  1. Hier zit een bug in. Je bewerkt als eerst het array-element Studenten[0] en dat bestaat niet.
  2. Niet fout maar wel veel veiliger dan een while-constructie is een for-loop, want dan weet je zeker dat het programma nooit in een eindeloze lus raakt. Het is immers heel gemakkelijk om getal := getal + 1; te vergeten.
  3. getal kun je in deze code veel beter declareren als een locale variabele. De waarde van getal wordt hier immers niet buiten de procedure init gebruikt. De algemene regel luidt dat je variabelen 'zo locaal mogelijkmoet houden. Dat maakt je code leesbaarder, veel gemakkelijker onderhoudbaar en voorkomt lastig opspoorbare bugs.
Beter is dus:
Delphi:
27
28
29
30
31
32
33
constructor database.init;
var
  i: Integer;
begin
  for i := 1 to 10 do
    Studenten[i] := nil;
end;

En dan een paar tips. Kijk nog eens naar de volgende code.
Delphi:
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
var d:database;
    getal2,antwoord1:integer;
    antwoord:char;

begin
d.init;
antwoord:='j';
     while antwoord = ('j') do
           begin
                writeln('Er is/zijn momenteel ',getal2,' studenten in de database');

...

                                  If antwoord1 = 6 then
                                  antwoord:='n';

     Writeln('Wilt u nogmaals een actie uitvoeren? (J/N)');
     Readln(antwoord);
     end;
end.
Door verkeerd inspringen is de code hierboven lastig leesbaar. Waar hoort de end in de laaste regel bijvoorbeeld bij? Denk ook aan het juiste gebruik van spaties en hoofletters. Meestal maakt het voor de correctheid van de code geen verschil, maar het maakt alles gewoon een stuk leesbaarder. Het volgende is al beter:
Delphi:
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
var
  D: Database;
  Getal2, Antwoord1: Integer;
  Antwoord: Char;
begin
  D.Init;
  Antwoord := 'j';
  while Antwoord = 'j' do
  begin
    WriteLn('Er is/zijn momenteel ', Getal2, ' studenten in de database');

...

    if Antwoord1 = '6' then
      Antwoord := 'n';
    Writeln('Wilt u nogmaals een actie uitvoeren? (J/N)');
    ReadLn(Antwoord);
  end;
end.
De while-lus hierboven is trouwens een uitstekend voorbeeld van een geval waar je een repeat-lus zou kunnen gebruiken. Je loopt de lus altijd tenminste 1x door en gaat pas aan het einde kijken (dus niet zodra je de lus binnenkomt) of je hem nog een keer wilt doorlopen.
Delphi:
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
var
  D: Database;
  Getal2, Antwoord1: Integer;
  Opnieuw: Char;
begin
  D.Init;
  repeat
    WriteLn('Er is/zijn momenteel ', Getal2, ' studenten in de database');

...

    if Antwoord1 = '6' then
      Opnieuw := 'n';
    Writeln('Wilt u nogmaals een actie uitvoeren? (J/N)');
    ReadLn(Opnieuw);
  until Opnieuw <> 'j';
end.

Een goede grap mag vrienden kosten.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01:25

Tomatoman

Fulltime prutser

Een prima artikel over het netjes schrijven van code in (Object) Pascal vind je in de Object Pascal Style Guide. Om deze pagina te kunnen lezen moet je je waarschijnlijk wel (gratis) aanmelden bij het Borland Developer Network.

Een goede grap mag vrienden kosten.


  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 22-08 17:59

Knutselsmurf

LED's make things better

Shook schreef op 03 May 2003 @ 16:15:
Voor zover ik weet staat de dispose prima, de hulppointer mag wel weg, de informatie is al gelinkt aan de studenten[getal]

Het weghalen, loste het probleem ook niet op, op een of andere manier komt er gewoon niks in de array. Ik heb de code bijna letterlijk (alleen andere variabele-namen) uit Savitch gehaald.
De hulppinter mag dan geen nut meer hebben, maar de geheugenruimte waarnaar verwezen wordt heeft nog zeker wel nut. Er wordt 2 maal naar hetzelfde stuk geheugen verwezen. Als je vervolgens via 1 van de 2 pointers die ruimte vrijgeeft (wat dispose doet) dan wijst de andere pointer nog steeds naar dat adres, maar daar staan geen gegevens meer in !!

- This line is intentionally left blank -


  • Shook
  • Registratie: Februari 2001
  • Laatst online: 29-09-2024
De uiteindelijke code die ik heb ingeleverd is:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
program StudDatabase;
uses wincrt;

type verwijzing = ^vakken;
     vakken = record
     vak:string;
     link:verwijzing;
     end;

     student = array [1..10] of verwijzing;

     database = object
                studenten:student;
                hulpPointer:verwijzing;
                getal,i:integer;
                vak2,vak3,vak4,vak5,vak6:string;
                antwoord:char;

                constructor init;
                procedure voegStudentToe;
                procedure haalStudentWeg;
                procedure voegVakToe;
                procedure laatVakZien;
                procedure overzicht;
                end;

Constructor database.init;
begin
getal:=0;
While getal <= 10 do
      begin
           Studenten[getal]:=NIL;
           getal:=getal+1;
      end;
end;


procedure database.overzicht;
begin
getal:=1;
While getal <= 10 do
    begin
         while studenten[getal]^.link <>  nil do
               begin
                    writeln(studenten[getal]^.vak);
                    studenten[getal]:=studenten[getal]^.link;
               end;
         getal:=getal+1;
    end;
end;


procedure database.voegStudentToe;
begin
     writeln('U wilt een student toevoegen');
     writeln('Geeft het nummer dat u aan de student wil toevoegen');
     readln(getal);
     new (hulpPointer);
     hulpPointer^.vak:='Nederlands';
     hulpPointer^.link:=nil;
     studenten[getal]:=hulpPointer;
     Writeln('Student nmr ',getal, ' heeft al 1 Vak, Nederlands (dit is namelijk verplicht)');
end;


Procedure database.voegVakToe;
begin
     antwoord:='j';
     new(studenten[getal]);
                   
     writeln('Geef het nummer van de student');
     readln(getal);

     while antwoord = 'j' do
           begin
              writeln('Geef het vak');
              readln(vak2);
                        
              new(hulppointer);
              hulppointer^.vak:=(vak2);
              hulppointer^.link:=studenten[getal];
              studenten[getal]:=hulppointer;
              dispose(hulppointer);

              writeln('nog een vak toevoegen? (j/n)');
              readln(antwoord);
           end;
              
           while studenten[getal]^.link <>  nil do
           begin
                writeln(studenten[getal]^.vak);
                studenten[getal]:=studenten[getal]^.link;
           end;
end;

procedure database.laatVakZien;
Begin
     Writeln('Van welke student wilt u de vakken zien?');
     readln(getal);

     while studenten[getal]^.link <>  nil do
     begin
          writeln(studenten[getal]^.vak);
          studenten[getal]:=studenten[getal]^.link;
     end;
end;

procedure database.haalStudentWeg;
begin
     writeln('U wilt een student weghalen');
     writeln('Geeft het nummer dat u aan de student wil toevoegen');
     readln(getal);
     studenten[getal]:=nil;
     Writeln('Student nmr ',getal, ' bestaat niet meer');
end;


var d:database;
    getal2,antwoord1:integer;
    antwoord:char;

begin
d.init;
antwoord:='j';
     while antwoord = ('j') do
           begin
                writeln('Er is/zijn momenteel ',getal2,' studenten in de database');
                writeln;
                writeln('Wilt u - 1. een student toevoegen');
                writeln('Wilt u - 2. een student weghalen');
                writeln('Wilt u - 3. een vak toevoegen/verwijderen bij een student');
                writeln('Wilt u - 4. De vakken van een student bekijken?');
                writeln('Wilt u - 5. Een overzicht van alle studenten en hun vakken');
                writeln('Wilt u - 6. Afsluiten');
                writeln;
                Writeln('Maak uw keuze');
                readln(antwoord1);

                                  if antwoord1 = 1 then
                                  d.voegStudentToe;
                                  If antwoord1 = 2 then
                                  d.haalStudentWeg;
                                  If antwoord1 = 3 then
                                  d.voegVakToe;
                                  If antwoord1 = 4 then
                                  d.laatVakZien;
                                  If antwoord1 = 5 then
                                  d.overzicht;
                                  If antwoord1 = 6 then
                                  antwoord:='n';

     Writeln('Wilt u nogmaals een actie uitvoeren? (J/N)');
     Readln(antwoord);
     end;
end.

Hij doet het nu eindelijk, vervelend genoeg (iets wat technisch niet mogelijk is) soms ook niet. Waarschijnlijk bestaan er toch kleine conflicten tussen pascal en XP. Ik heb er geen anders geen andere reden voor.

Tomatoman, IcemanX en Knutselsmurf: Thanxs voor de hulp. Soms is programmeren echt een duo/multi job, zeker voor iemand zoals ik, die zich liever bezig houd met de grote lijnen ipv details (geen goede programmeurs eigenschap, i know). nogmaals bedankt.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Shook schreef op 05 May 2003 @ 11:06:
Hij doet het nu eindelijk, vervelend genoeg (iets wat technisch niet mogelijk is) soms ook niet. Waarschijnlijk bestaan er toch kleine conflicten tussen pascal en XP. Ik heb er geen anders geen andere reden voor.
En met niet doen bedoel je dat er soms iets mis gaat met de pointers? Dat is toch echt hoogstwaarschijnlijk een bug aan jouw kant en niet aan die van je pascal compiler. Het kan zeker niets te maken hebben met een combinatie van XP, dat is gewoonweg te ver gezocht :)

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1