PhelpsTransposed Skrevet 6. februar 2014 Del Skrevet 6. februar 2014 (endret) Hei!Når jeg kjører koden under får jeg av en eller annen grunn ikke tilgang til v[] elementene i sumfunksjonkoden, noe som vises ved at summen blir 0. Hvorfor?Første gang jeg koder i C, men har kodet en del før. Sorry om det er et dumt spørsmål.EDIT: tabbed meg ut ved å referere til v[n] istedenfor v #include <math.h> #include <stdlib.h> #include <stdio.h> void fyllfunksjon(double v[], int n) { for (int i = 1; i < n; ++i) { v[(i-1)] = 1/(pow(i,2)); } } double sumfunksjon(double v[], int n, double sum) { for (int i = 0; i < n-1; ++i) { sum = sum + v[n]; } return sum; } int main() { int k; int n; double sum; n = pow(2,2); double v[n]; fyllfunksjon(v, n); sum = sumfunksjon(v, n, sum); printf("%f\n", sum); } Endret 6. februar 2014 av PhelpsTransposed Lenke til kommentar
Glutar Skrevet 6. februar 2014 Del Skrevet 6. februar 2014 Hvis du ønsker å fylle hele arrayen (4 elemementer) så må du endre i fyllfunksjon til: for (int i = 0; i < n; ++i) { v[i] = 1/(pow(i+1,2)); } og for å printe alle 4 elementene for (int i = 0; i < n; ++i) I C får uinitialiserte variabler tilfeldig verdi, endre "double sum;" til "double sum = 0;" for å initialisere sum til 0. 1 Lenke til kommentar
PhelpsTransposed Skrevet 6. februar 2014 Forfatter Del Skrevet 6. februar 2014 (endret) Takk for svar! Ett spørsmål til: med denne koden får jeg rett og slett ikke riktig sum. Sjekk den modifiserte, her får jeg sum på k = 14 på 1.423611, men dette er feil (http://www.wolframalpha.com/input/?i=sum+1%2Fn^2%2C+n%3D1+to+14)Er det fordi jeg bruker double - ikke long? #include <math.h> #include <stdlib.h> #include <stdio.h> void fyllfunksjon(double v[], int n) { for (int i = 1; i <= n; ++i) { v[(i-1)] = 1/(pow(i,2)); } } double sumfunksjon(double v[], int n) { double thesum = 0.0; for (int i = 0; i <= n; ++i) { thesum = thesum + v[i]; } return thesum; } int main() { int k = 0; int n = 0; double sum = 0; double S = pow(M_PI,2)/6; double difference; for (k = 3; k <= 14; ++k) { n = pow(2,2); double v[n-1]; fyllfunksjon(v, n); sum = sumfunksjon(v, n); printf("%s %d\n", "The sum with k = ", k); printf("%f\n", sum); difference = S - sum; printf("%s\n", "S - Sn:"); printf("%f\n", difference); } } Endret 6. februar 2014 av PhelpsTransposed Lenke til kommentar
Glutar Skrevet 6. februar 2014 Del Skrevet 6. februar 2014 (endret) Størelsen på v er n - 1. Så hvis n er 4 kan v inneholde 3 elementer. Begge for loopene dine skriver/leser utenfor arrayen. fyllfunksjon vil skrive til v[0], v[1], v[2] og v[3] som er 1 utenfor arrayen. Kan fikses ved å endre "<=" til "<". sumfunksjon vil lese v[0], v[1], v[2], v[3] og v[4] som er 2 utenfor arrayen. Kan fikses ved å endre til: for (int i = 0; i < n-1; i++); Endret 6. februar 2014 av Glutar Lenke til kommentar
Lycantrophe Skrevet 7. februar 2014 Del Skrevet 7. februar 2014 (endret) Oh boy. Her var det mye. Er det fordi jeg bruker double - ikke long? void fyllfunksjon(double v[], int n) { for (int i = 1; i <= n; ++i) { v[(i-1)] = 1/(pow(i,2)); } } Stil, men denne ville jeg forandret til: void fill( double v[], int size ) { double *elem = v; for( int i = 1; i <= size; ++i, ++v ) *v = 1.0 / ( i * i ); } Disse gjør akkurat det samme. Siden du alltid skal kvadrere er det like greit å bruke i * i. Her bruker jeg pointer arithmetic (vet du hva det er?), men du kan også bruke v[i-1] om du foretrekker det. Dersom du bruker mitt eksempel må du bruke 1.0 og ikke 1, hvis ikke vil du bedrive heltallsdivisjon og få feil svar. double sumfunksjon(double v[], int n) { double thesum = 0.0; for (int i = 0; i <= n; ++i) { thesum = thesum + v[i]; } return thesum; } Du har en logikk-feil i iterasjonen din. Du vil ha < n, ikke <= n. Husk at arrays er 0-indeksert i C. Mer stil: double sum( const double v[], int size ) { const double *elem = v; double sum = 0; for( int i = 0; i < size; ++i, ++v ) sum += *v; return sum; Det er mange nifty måter å skrive dette på, men ingen grunn til å komplisere mer enn vi allerede har gjort. Men så til den store saken. int main() { int k = 0; int n = 0; double sum = 0; double S = pow(M_PI,2)/6; double difference; for (k = 3; k <= 14; ++k) { n = pow(2,2); double v[n-1]; fyllfunksjon(v, n); sum = sumfunksjon(v, n); printf("%s %d\n", "The sum with k = ", k); printf("%f\n", sum); difference = S - sum; printf("%s\n", "S - Sn:"); printf("%f\n", difference); } } Hvorfor har du rotet inn n her? Dette gjør at du kun jobber med de fire første elementene i hver sekvens, noe som gjør at summen din blir for liten. Om du inspiserer output vil du se at alle utregninger gir identisk svar. Fjern alle n og bytt ut med k, unntatt i arrayen. Det skal være v[ k ], ikke v[ k - 1 ]. Selv om du -aksesserer- med index-1 må størrelse fortsatt være så stor som du vil ha. Ellers: #1: int n = 0; n = pow( 2, 2 ). Hvorfor setter du ikke bare n = pow( 2, 2 ) med en gang? Den brukes jo aldri ellers. #2: n er alltid 2² = 4. Hvorfor skriver du ikke bare 4? #3: Kan du skrive C99? Flytt isåfall deklarasjonene inn til der du bruker de. #4: printf( "%s\n", "S - Sn" ); printf( "%f\n", difference ) -> printf( "S - Sn\n%f\n", difference ); Resten skal jeg ikke pirke på med mindre du vil. Foreslår følgende main: int main() { const double S = pow(M_PI,2)/6; for ( int k = 3; k <= 14; ++k) { double v[ k ]; fyllfunksjon(v, k); const double sum = sumfunksjon(v, k); printf( "Sum with k = %d: %f\n", k, sum ); printf( "S - Sn: %f\n", S - sum ); } } edit: hva i helvete er vitsen med code-tag hvis den ikke respekterer whitespace? skyt deg, ipb. Endret 10. februar 2014 av Lycantrophe Lenke til kommentar
PhelpsTransposed Skrevet 7. februar 2014 Forfatter Del Skrevet 7. februar 2014 Tusen takk for svar og hjelp! Skal gå gjennom og rette opp forslagene. Har såvidt kodet bitte bittelitt i C, og knapt noe i Fortran, ellers bare i C# og Java før så dette er veldig uvant.Kan forklare noe rot først, jeg tok egentlig bort den k iterasjonen for å forsøke å løse problemet uten den først, og når jeg satt den tilbake så glemte jeg å ordne skikkelig. Riktig skal være: n = pow(2,k); i for-løkka i main. Ellers takk for svar, skal rydde opp. Vet ikke hva pointer arithmetic er, forresten.Igjen, takk for at dere tok dere tid! Lenke til kommentar
Lycantrophe Skrevet 7. februar 2014 Del Skrevet 7. februar 2014 Wait. I wolframalpha-uttrykket ditt kjører du summe-funksjonen fra 1 -> k. Hvorfor skal du plutselig summere til ? -- En peker i C er egentlig en helt vanlig verdi, altså et tall. Pekeraritmetikk er som "vanlig" aritmetikk, men med peker-verdier i stedet. Her er det viktig å huske på at en array oppfører seg som en peker. Hvorfor dette er unyansert og ikke helt riktig er en lang og komplisert diskusjon, så dette går vi ikke inn på. Uansett, i dette tilfellet så kan du se på array-verdien som en peker til det første elemenetet. Fordi kompilatoren din vet at alle elementer har verdien double (aka den vet størrelsen på hvert element i arrayen) vil ++pointer gjøre at pointeren peker på ett element til høyre. I dette tilfellet er det mest stil. Jeg har ikke sansen for å aksessere en array med offset når du uansett skal gjennom hele, selv om en smart nok™ kompilator klarer å optimalisere det bort. Vet du hva en iterator er? Mener at C# har slikt. Lenke til kommentar
zotbar1234 Skrevet 10. februar 2014 Del Skrevet 10. februar 2014 (endret) v[(i-1)] = 1/(pow(i,2)); Den store feilen er likevel at du driver heltallsdivisjon (integer division). Som du ser har jeg forandret 1 -> 1.0. Dette gir deg mellomresultatene du vil ha. I din versjon må man nok bruke 1.0. I den opprinnelige versjonen er resultatet av en 1/pow(...) en double og det foregår ikke heltallsdivisjon (med forbehold om at jeg misforstod hva kommentaren refererte til) Endret 10. februar 2014 av zotbar1234 Lenke til kommentar
Lycantrophe Skrevet 10. februar 2014 Del Skrevet 10. februar 2014 Det har du rett i, det er bare jeg som blander. Testet med min egen, og da fikk jeg intdiv-feil. Fjerner den aktuelle biten fra posten. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå