Permalänk
Medlem

[C++] Beräkna medelvärde

Sitter med ett program som jag håller på att konvertera och har hittat ett kodavsnitt som jag inte för mitt liv kan få till att den fungerar som tänkt.
Syftet med koden är att skapa ett medelvärde av 20 stycken värden.
Är det någon som kan förklara om detta verkligen fungerar som tänkt, eller om det är som jag misstänker - denna bit av koden är helt felaktig.

medel_2=0; medel_1=0; for(i=20;i--;i>1) { varden_2[i]=varden_2[i-1]; varden_1[i]=varden_1[i-1]; medel_2=medel_2 + varden_2[i]; medel_1=medel_1 + varden_1[i]; } varden_2[0]=invarde2; varden_1[0]=invarde1; medelvarde2=(medel_2 + varden_2[0]) / 20.0; medelvarde1=(medel_1 + varden_1[0]) / 20.0;

Visa signatur

Min signatur - inte din!

Permalänk
Medlem

Har för mig att ett fält som skall innehålla 20 olika tal börjar från [0] och slutar [19], i din loop så börjar du på 20 vilket är utanför 0-19.

är lite rostig, var ett par år sen jag rörde java/c++

Visa signatur

C2D E8400 @ 3.0 | ASRock G41M-GS3 | Corsair 4GB CL9 1333Mhz XMS3 | Intel 320 80gb SSD & Samsung 250Gb | Gigabyte GTX 460 768mb

Permalänk

Som WeiQ säger så indexeras en array med 20 element från 0 till 19.

Dessutom är din din for-loop helt fel.

http://www.cplusplus.com/doc/tutorial/control/

Visa signatur

PC Kontoret: Ryzen 5700X, 32GB, 6800 XT
PC Spelrum: Ryzen 5800X, 32GB, 7900 XT

Permalänk
Medlem

För att skapa ett medelvärde från en array så summera bara arrayen och dela med antalet element i arrayen ...

Lösning Borta!, fel forum :)

Visa signatur

There are 10 types of people in the world: Those who understand binary, and those who don't...

Asus Maximus VIII Hero | i7-6700K | ASUS GeForce GTX1070 Strix 8GB | G.Skill F4-2133C15Q-32GRK |

Permalänk
Medlem

Nu gjorde du ju jobbet åt honom, WarWolf.667.

Visa signatur

C2D E8400 @ 3.0 | ASRock G41M-GS3 | Corsair 4GB CL9 1333Mhz XMS3 | Intel 320 80gb SSD & Samsung 250Gb | Gigabyte GTX 460 768mb

Permalänk
Medlem

Hmm, jag hänger inte alls med hur du gör din beräkning, verkar onödigt komplicerat.
http://sv.wikipedia.org/wiki/Medelv%C3%A4rde

Det "enda" du i min mening behöver gör är att aggregera alla tal och sen dividera med 20.

Edit: Jahapp nu blev man ju omkörd av vargen för man gick och tog en kaffe

Permalänk
Medlem

Oj fel forum

Edit: Kaffe!, bra ide!

Visa signatur

There are 10 types of people in the world: Those who understand binary, and those who don't...

Asus Maximus VIII Hero | i7-6700K | ASUS GeForce GTX1070 Strix 8GB | G.Skill F4-2133C15Q-32GRK |

Permalänk
Medlem

Ja, syntaxen i for-loopen är helt fel.
Det är just det som jag är ute efter.
Det kodavsnittet fungerar inte som tänkt.
Däremot så kompilerar det, men det är en annan sak.

Visa signatur

Min signatur - inte din!

Permalänk
Avstängd

Alla variabler utom i måste vara typade som flyttal som du gjort dina beräkningar i exemplet.

Permalänk
Medlem

Intressant nog så är for-loopen inte så fel som man kan tro. Slutvillkoret (i--) exekveras nämligen innan loop-kroppen exekveras. i initialiseras därför till 20, men minskas till 19 innan loop-kroppen exekveras. For-loopen kör ju sedan tills slutvillkoret är falskt, vilket i C/C++ är samma sak som 0. i-- kommer att minska i med ett, men returnera värdet som i hade innan subtraktionen utfördes. Loop-kroppen kommer därför att köra med i = 0 den sista gången. Det sista i > 1 är helt irrelevant, och kan tas bort utan att påverka koden. Så loopen kommer faktiskt att gå från 19 till 0, även om jag misstänker att det mest är av en olyckshändelse

Permalänk
Medlem
Skrivet av perost:

Intressant nog så är for-loopen inte så fel som man kan tro. Slutvillkoret (i--) exekveras nämligen innan loop-kroppen exekveras. i initialiseras därför till 20, men minskas till 19 innan loop-kroppen exekveras. For-loopen kör ju sedan tills slutvillkoret är falskt, vilket i C/C++ är samma sak som 0. i-- kommer att minska i med ett, men returnera värdet som i hade innan subtraktionen utfördes. Loop-kroppen kommer därför att köra med i = 0 den sista gången. Det sista i > 1 är helt irrelevant, och kan tas bort utan att påverka koden. Så loopen kommer faktiskt att gå från 19 till 0, även om jag misstänker att det mest är av en olyckshändelse

Där hade vi den sista pusselbiten i dramat.
Ett oavsiktligt misstag som slinker igenom.

Men, är vi överens om att det enda värde som faktiskt läggs in i dessa arrayer, är det värde som placeras i element 0?

Visa signatur

Min signatur - inte din!

Permalänk
Hedersmedlem
Skrivet av Liftaren:

Men, är vi överens om att det enda värde som faktiskt läggs in i dessa arrayer, är det värde som placeras i element 0?

Så borde det vara. Men tar du hänsyn till att de kan innehålla vad som helst från början (eller vad är det som blir fel)?

Permalänk
Medlem
Skrivet av Elgot:

Så borde det vara. Men tar du hänsyn till att de kan innehålla vad som helst från början (eller vad är det som blir fel)?

Variablerna är deklarerade som "static", så de innehåller noll.
Kan inte svära på att det är standard, men den skillnaden noterade jag när jag testade. Var inte variablerna deklarerade som "static" så innehöll de skräp (alltid samma värde i och för sig), men som "static" innehöll de noll.

Kärnan i frågan är om jag tolkat rätt, dvs koden fungerar inte som tänkt.

Visa signatur

Min signatur - inte din!

Permalänk
Hedersmedlem
Skrivet av Liftaren:

Variablerna är deklarerade som "static", så de innehåller noll.
Kan inte svära på att det är standard, men den skillnaden noterade jag när jag testade. Var inte variablerna deklarerade som "static" så innehöll de skräp (alltid samma värde i och för sig), men som "static" innehöll de noll.

Kärnan i frågan är om jag tolkat rätt, dvs koden fungerar inte som tänkt.

Ett problem är dock som sagt

Citat:

Loop-kroppen kommer därför att köra med i = 0 den sista gången.

vilket borde kunna ställa till det till exempel här

varden_2[i]=varden_2[i-1];

Varför inte ändra loop-huvudet till hur du egentligen menar?

Permalänk
Medlem
Skrivet av Liftaren:

Variablerna är deklarerade som "static", så de innehåller noll.
Kan inte svära på att det är standard, men den skillnaden noterade jag när jag testade. Var inte variablerna deklarerade som "static" så innehöll de skräp (alltid samma värde i och för sig), men som "static" innehöll de noll.

Kärnan i frågan är om jag tolkat rätt, dvs koden fungerar inte som tänkt.

Deklarera _inte_ variablerna som static! Sätt istället variablens värde till 0 när du deklarerar den tex. int var = 0;

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av Elgot:

Ett problem är dock som sagt

vilket borde kunna ställa till det till exempel här

varden_2[i]=varden_2[i-1];

Varför inte ändra loop-huvudet till hur du egentligen menar?

Koden ska överges, det är bara en fråga om nuvarande funktionalitet.

Skrivet av Azodan:

Deklarera _inte_ variablerna som static! Sätt istället variablens värde till 0 när du deklarerar den tex. int var = 0;

Skickades från m.sweclockers.com

Utveckla gärna varför static inte är lämpligt.

Visa signatur

Min signatur - inte din!

Permalänk
Medlem
Skrivet av Liftaren:

Utveckla gärna varför static inte är lämpligt.

Static är inte lämpligt för att få dess sekundära funktionalitet. Det som static gör (när nyckelordet används framför en lokal variabel inuti en funktion) är att tvinga kvar den variabeln i minnet så länge programmet kör. Detta är inte bra om man inte faktiskt vill detta, och kan skapa otrevliga buggar / minnesläckor.

Dock tycker jag hela koden i sig är knasig, varför skall du konvertera denna? Känns som det är skrivet av en person som verkligen inte har koll, lite noteringar:

for(i=20;i--;i>1)

Ingen initialisering av indexvariabel, går visserligen att använda, men konstig praxis. Dvs inget "int xx = yy" utan bara "xx=yy".
Fel ordning på slutvillkor och uppdatering av variabel (det som perost påpekade).
Om det faktiskt varit korrekt skulle den itererat över 20-1 istället för 19-0, vilket i sig fungerar bättre med hur loopkroppen ser ut, men är konstigt i vilket fall.

varden_2[i]=varden_2[i-1]; varden_1[i]=varden_1[i-1]; medel_2=medel_2 + varden_2[i]; medel_1=medel_1 + varden_1[i];

Detta är intressant. Det som händer är ju att alla tal flyttas upp ett steg i vektorn, och sedan adderas till "medeltalet". Dvs 0-1-2-3 skulle ge 0-0-1-2 samt icke-delat medeltal 3.

Är du säker på medeltalsberäkning är vad kodbiten är menad att göra? Inte ens en nybörjare skulle väl komma på idén att skriva dessa omvägar för att göra något så simpelt som att beräkna medeltalet i två vektorer?

Visa signatur

Fractal Design Arc | Fractal Design Newton R2 650W | Asus Maximus Gene V | Asus GTX 680 | i7-2700k @ 4.6GHz w. Kühler 620 | 2133MHz 8GB RAM | A-data S510 SSD 120GB

Permalänk
Medlem
Skrivet av Liftaren:

Utveckla gärna varför static inte är lämpligt.

Jag antar att du har deklarerat static i en funktion då kommer variabeln att vara kvar i minnet även när man går ur funktionen och nästa gång man använder funktionen så kommer static variabeln ha kvar samma värde som den hade sist, alltså du kommer inte kunna använda funktionen fler än en gång.

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av Zorgie:

Static är inte lämpligt för att få dess sekundära funktionalitet. Det som static gör (när nyckelordet används framför en lokal variabel inuti en funktion) är att tvinga kvar den variabeln i minnet så länge programmet kör. Detta är inte bra om man inte faktiskt vill detta, och kan skapa otrevliga buggar / minnesläckor.

Hur menar du att en statisk variabel genererar en minnesläcka? Minnet kommer ju att frigöras när programmet avslutas. Det är ju inte som när man allokerar minne dynamiskt med t.ex. malloc och glömmer bort att free:a det. Jag håller dock med om att om man inte är ute efter just statisk minnesallokering för en variabel så bör det inte användas.

Skrivet av Zorgie:

Ingen initialisering av indexvariabel, går visserligen att använda, men konstig praxis. Dvs inget "int xx = yy" utan bara "xx=yy".

Att man inte skapar indexvariabeln i for-loopen är väl inte så konstigt? Jag har visserligen inte programmerat så mycket C++, utan mest C, och där är det (enligt ANSI C) inte tillåtet att deklarera variabler inuti for-loopen. Detta gäller ju inte i C++, men kan tänka mig att det är relativt normalt att många fortfarande gör på det sättet.

Permalänk
Hedersmedlem
Skrivet av Zorgie:

Detta är intressant. Det som händer är ju att alla tal flyttas upp ett steg i vektorn, och sedan adderas till "medeltalet". Dvs 0-1-2-3 skulle ge 0-0-1-2 samt icke-delat medeltal 3.

Är du säker på medeltalsberäkning är vad kodbiten är menad att göra? Inte ens en nybörjare skulle väl komma på idén att skriva dessa omvägar för att göra något så simpelt som att beräkna medeltalet i två vektorer?

Koden är ju dock en kombination av medelvärdesuträkning (det sista värdet adderas efteråt) och bufferthantering.

Permalänk
Medlem
Skrivet av pelleplu:

Hur menar du att en statisk variabel genererar en minnesläcka? Minnet kommer ju att frigöras när programmet avslutas. Det är ju inte som när man allokerar minne dynamiskt med t.ex. malloc och glömmer bort att free:a det. Jag håller dock med om att om man inte är ute efter just statisk minnesallokering för en variabel så bör det inte användas.

Att skapa en minnesläcka med static är nog inte speciellt troligt, men det går utmärkt utan att tvinga till sig reserverat minne med malloc, även om minnesläckan inte orsakar något mer än att krasha programmet.

Skrivet av pelleplu:

Att man inte skapar indexvariabeln i for-loopen är väl inte så konstigt? Jag har visserligen inte programmerat så mycket C++, utan mest C, och där är det (enligt ANSI C) inte tillåtet att deklarera variabler inuti for-loopen. Detta gäller ju inte i C++, men kan tänka mig att det är relativt normalt att många fortfarande gör på det sättet.

Bra poäng, själv kodade jag i C++ före C, och det har därför fallit naturligt för mig!

Skrivet av Elgot:

Koden är ju dock en kombination av medelvärdesuträkning (det sista värdet adderas efteråt) och bufferthantering.

Ur det perspektivet är koden ännu konstigare. Om man skulle lägga detta i en loop kommer alltså input-värdet läggas på plats 0 i varje loopsteg, och alla andra trycks upp ett steg. Detta sker dock endast upp till 20 platser, maxgränsen för vektorn. Borde då inte medeltalet beräknas m.h.a. det faktiska antal värden som är instoppade (max 20)?

Oavsett hur koden skall och inte skall funka, så känns det inte som att medeltalsberäkning är hela sanningen angående denna kod

Visa signatur

Fractal Design Arc | Fractal Design Newton R2 650W | Asus Maximus Gene V | Asus GTX 680 | i7-2700k @ 4.6GHz w. Kühler 620 | 2133MHz 8GB RAM | A-data S510 SSD 120GB

Permalänk
Medlem
Skrivet av Zorgie:

Oavsett hur koden skall och inte skall funka, så känns det inte som att medeltalsberäkning är hela sanningen angående denna kod

Variabelnamnen är översatta till svenska och betydelsen är just "genomsnittlig" eller "medel".

Skrivet av Zorgie:

Dock tycker jag hela koden i sig är knasig, varför skall du konvertera denna? Känns som det är skrivet av en person som verkligen inte har koll, lite noteringar:

Är du säker på medeltalsberäkning är vad kodbiten är menad att göra? Inte ens en nybörjare skulle väl komma på idén att skriva dessa omvägar för att göra något så simpelt som att beräkna medeltalet i två vektorer?

Konvertering är helt nödvändig, av anledningar jag inte kan gå in på här.
Den som skrivit programmet har bra koll i övrigt, men just denna funktion verkar vara en tankevurpa.

Skrivet av Azodan:

Jag antar att du har deklarerat static i en funktion då kommer variabeln att vara kvar i minnet även när man går ur funktionen och nästa gång man använder funktionen så kommer static variabeln ha kvar samma värde som den hade sist, alltså du kommer inte kunna använda funktionen fler än en gång.

Skickades från m.sweclockers.com

Det är på det viset att samtliga variabler är deklarerade som globala variabler.

Visa signatur

Min signatur - inte din!

Permalänk
Hedersmedlem
Skrivet av Zorgie:

Bra poäng, själv kodade jag i C++ före C, och det har därför fallit naturligt för mig!

Att deklarera variabeln utanför innebär också att man kan se vilket värde den senast hade efter loopen, vilket kan vara användbart ibland.

Skrivet av Zorgie:

Borde då inte medeltalet beräknas m.h.a. det faktiska antal värden som är instoppade (max 20)?

Det är väl dock ett designbeslut; vi vet ju som sagt inte vad syftet är.

Permalänk
Medlem
Skrivet av Liftaren:

Konvertering är helt nödvändig, av anledningar jag inte kan gå in på här.
Den som skrivit programmet har bra koll i övrigt, men just denna funktion verkar vara en tankevurpa.

Som Elgot var inne på så kommer koden att läsa från position -1 i arrayerna, så vad koden faktiskt gör är odefinierat. Om jag skulle gissa vad meningen med koden är så är det att shifta två arrayer och sedan stoppa in nya värden på första platsen. Dvs. om man har en array {1, 2, 3, 4, 5} och ett nytt värde 6 så får man {6, 1, 2, 3, 4}. Och sedan beräknar koden medelvärdet av varje ny array. Koden blir lite rörig eftersom den behandlar båda arrayerna samtidigt och utför shiftningen samtidigt som den beräknar medelvärdet.

Jag skulle skriva om koden så att den hanterar endast en array, och stoppa in koden i en funktion som kan anropas på varje array separat. Koden kan skrivas så här (inkludera cstring för memmove, numeric för accumulate):

memmove(varden + 1, varden, sizeof(varden) - sizeof(varden[0])); // Shifta arrayen. varden[0] = invarde; // Stoppa in nytt värde på första platsen. medelvarde = std::accumulate(varden, varden + 20, 0) / 20.0; // Beräkna medelvärdet av arrayen.

Permalänk
Medlem

Har väl sisådär två timmars erfarenhet av C++, men till och med jag kan se att ts tydligen inte vet vad han sysslar med

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av Snacker:

Har väl sisådär två timmars erfarenhet av C++, men till och med jag kan se att ts tydligen inte vet vad han sysslar med

Skickades från m.sweclockers.com

Det var inte det ts frågade om...

Han är här för att lära sig. Sluta klanka ner på människor med onödiga kommentarer som skapar onödiga kommentarer som denna...

Visa signatur

i7-6700K | MSI Z170A | MSI 1080 8GB | 16GB Kingston HyperX | Intel 600P 256GB | Samsung EVO Basic 840 250GB x2 raid 0 | Corsair RM 750W | 3 x Dell U2414H

Permalänk

Det enda du behöver göra är att addera alla värden och sen dela summan med antalet värden, där har du medelvärdet!

Permalänk
Medlem
Skrivet av Snacker:

Har väl sisådär två timmars erfarenhet av C++, men till och med jag kan se att ts tydligen inte vet vad han sysslar med

Skickades från m.sweclockers.com

Om du istället för att försöka hävda dig hade läst tråden, så hade du sett att det är inte jag som skrivit koden. Det är inga som helst fel på mina kunskaper i grundläggande C++, men jag är inte heller för uppblåst för att ställa en fråga när jag blir osäker. Kom tillbaka när du lämnat målbrottet.

Skrivet av Jesper.B93:

Det enda du behöver göra är att addera alla värden och sen dela summan med antalet värden, där har du medelvärdet!

Jag vet hur man bildar ett medelvärde, det är inte det som frågan gäller.

Tillbaka till topic:
Vi kan konstatera att programkoden inte gör det den borde. Det var det som jag ville få bekräftat av någon fler.
Tack för alla bra svar.

Visa signatur

Min signatur - inte din!