Marx är nöjd med hjälpen!
Marx 108
Postad: 16 feb 2020 Redigerad: 16 feb 2020

Primtal- Pascal

Jag har skrivit ett program som ska skriva ut alla primtal upp till det inmatade talet. Koderna ser ut så här:

Men när jag kör programmet så skrivs det inte något än "Runtime error...". Kan någon förklara vad det är som inte fungerar som det ska?

Ture 2241
Postad: 16 feb 2020 Redigerad: 16 feb 2020

 

Några allmänna synpunkter: kontrollera alltid indata! Anta exvis att man matar in -1, vad händer då? eller om man matar in  q?

Skriv kommentarer så man har en chans att förstå vad som förväntas hända!

Undvik flaggor som din variabel exit, det blir rörigt

Edit Jag tog bort en del eftersom frågan blev uppdaterad...

Ture 2241
Postad: 16 feb 2020

ska det inte vara ett semikolon efter write-satsen?

Marx 108
Postad: 16 feb 2020
Ture skrev:

ska det inte vara ett semikolon efter write-satsen?

Testade det också men det fungerar inte ändå!

Laguna 7663
Postad: 16 feb 2020 Redigerad: 16 feb 2020

Det var ett sällsynt värdelöst felmeddelande. Går det kanske att kompilera programmet med någon debug-inställning? Titta i manualen. Eller så kanske det finns en debugger.

Du säger inte hur långt programmet kom. Matade du in ett tal och i så fall vilket?

Edit: förvirrande indentering på ett ställe: efter if inne i y-loopen så kan man tro att y := y+2 bara görs om if:en är sann, men så är det ju inte, så koden är korrekt där, men förvirrande. Flytta ut y := y+2 åt vänster.

Allt inuti repeat borde vara inskjutet också.

Om du inte kommer på nån annan metod för att debugga, så sätt in write-satser precis överallt, så du ser vad som händer när du kör.

Ett fel är att du aldrig sätter exit till true efter första varvet, men jag ser inte att det ska orsaka en krasch.

Marx 108
Postad: 16 feb 2020
Laguna skrev:

Det var ett sällsynt värdelöst felmeddelande. Går det kanske att kompilera programmet med någon debug-inställning? Titta i manualen. Eller så kanske det finns en debugger.

Du säger inte hur långt programmet kom. Matade du in ett tal och i så fall vilket?

Edit: förvirrande indentering på ett ställe: efter if inne i y-loopen så kan man tro att y := y+2 bara görs om if:en är sann, men så är det ju inte, så koden är korrekt där, men förvirrande. Flytta ut y := y+2 åt vänster.

Allt inuti repeat borde vara inskjutet också.

Om du inte kommer på nån annan metod för att debugga, så sätt in write-satser precis överallt, så du ser vad som händer när du kör.

Ett fel är att du aldrig sätter exit till true efter första varvet, men jag ser inte att det ska orsaka en krasch.

Compilern stödjer inte 'debug mode' för Pascal. Så tyvärr går det inte att debugga.

Har skjutit in koderna inuti repeat och dessutom flyttat ut y:et åt vänster. Men samma meddelande får jag fortfarande.

Ska prova med write-satser.

Debuggers och felutskrifter är bra hjälpmedel men det är även kodgranskning som vi nu gör. Detta har jag funnit:

Loopen 'repeat ... until p=x' bör bytas till en 'while p<x do ... end' så att loopen inte körs om x är mindre än 2. Ett enkelt skydd mot för lågt angivna värden på 'x'.

Mellan rad 15 och 16 fattas 'begin' och därmed även ett 'end' mellan rad 22 och 23. Det är här det största problemet finns och som gör att programlogiken inte funkar.

Mellan rad 16 och 17 behöver flaggan 'exit' sättas till 'true' för att primtal över 2 ska skrivas ut.

Som Laguna skrev: indentera rad 21 korrekt så blir koden lättare att läsa.

Utskriften på raderna 23-24 behöver ligga efter loop-slutet på rad 25 för att alla primtal ska skrivas ut.

Om du behåller flaggan 'exit' så ge den ett mer beskrivande namn, t ex 'isPrime'.

jek7 33
Postad: 19 feb 2020

mitt förra svar försvann nog i devnull. jag kan inte pascal, men 207 verkar vara flyttalsfel så jag gissar att det är typomvandlingsprovlem med sqrt(), prova att byta den raden till "while y*y<p do" som bara är integers.

jek7 skrev:

mitt förra svar försvann nog i devnull. jag kan inte pascal, men 207 verkar vara flyttalsfel så jag gissar att det är typomvandlingsprovlem med sqrt(), prova att byta den raden till "while y*y<p do" som bara är integers.

Ett bra förslag från jek7 som antagligen snabbar upp exekveringen.

Jag har testat med FreePascal, felsökt koden och fann att kraschen sker på denna kodrad:

if p mod y=0 then

Modulo-operatorn (mod) gör en heltalsdivision och svarar med resten från den divisionen. I detta fall är y lika med noll och då blir det division med noll vilket är odefinierat och leder till en krasch.

FreePascal ger felkod 200 "Division by zero". Kolla vad felkod 207 betyder för din kompilator/länkare.

Marx 108
Postad: 22 feb 2020

Äntligen! Nu fungerar programmet:

Marx 108
Postad: 22 feb 2020
Lindehaven skrev:

Debuggers och felutskrifter är bra hjälpmedel men det är även kodgranskning som vi nu gör. Detta har jag funnit:

Loopen 'repeat ... until p=x' bör bytas till en 'while p<x do ... end' så att loopen inte körs om x är mindre än 2. Ett enkelt skydd mot för lågt angivna värden på 'x'.

Mellan rad 15 och 16 fattas 'begin' och därmed även ett 'end' mellan rad 22 och 23. Det är här det största problemet finns och som gör att programlogiken inte funkar.

Mellan rad 16 och 17 behöver flaggan 'exit' sättas till 'true' för att primtal över 2 ska skrivas ut.

Som Laguna skrev: indentera rad 21 korrekt så blir koden lättare att läsa.

Utskriften på raderna 23-24 behöver ligga efter loop-slutet på rad 25 för att alla primtal ska skrivas ut.

Om du behåller flaggan 'exit' så ge den ett mer beskrivande namn, t ex 'isPrime'.

Tack för tipsen!

Svara Avbryt
Close