Gå til innhold

C nybegynner hjelp


Anbefalte innlegg

Hei!

 

Noen som kan forklare hvorfor programmet ikke vil lese av alle verdier i arrayet n?

Oppgave går ut på at man skal gi tre verdier hvor A og B er intervallet, og N er antall steps, deretter skal alle verdiene fra A til B settes inn i en likning og summen skal lagres i et array.

Takker for hjelp!

 

#include <stdio.h>

#include <math.h>
int main()
{
float A;
float B;
int N;
 
int j=0;
printf("Gi en verdi for A:\n");
scanf("%f", &A);
printf("Gi en verdi for B:\n");
scanf("%f", &B);
printf("Gi en verdi for N:\n");
scanf("%d", &N);
float n[10];
float T=(B-A)/N;
 
printf("%f ,", T);
 
 
for (float i = A ; i<=B ; i=A+T)
{ j=j+1;
 
n[j]=i*i*(sin(3.14*i));
printf("%f ," , n[j]);
return(0);
}
}
 
Lenke til kommentar
Videoannonse
Annonse

Det er vel flere problemer her. Det første er at du tar return(0); inne i loopen, dvs du går ut etter første utregning.

Det andre er at du har laget et array med plass til 10 verdier, men 10 ikke har noen sammenheng med verdiene du bruker til å bestemme hvor mange ganger du ønsker å loope.

Lenke til kommentar

Det er vel flere problemer her. Det første er at du tar return(0); inne i loopen, dvs du går ut etter første utregning.

Det andre er at du har laget et array med plass til 10 verdier, men 10 ikke har noen sammenheng med verdiene du bruker til å bestemme hvor mange ganger du ønsker å loope.

 

Hvor burde return(0) plasseres? Prøvde å plassere den utenfor, men da fikk jeg segmentation fault 11. Når det gjelder lengden prøvde jeg opprinnelig å gi lengden av intervallet, men fikk noen feilmeldinger så satt den som 10 midlertidig for å forsøke å løse den første feilen.

Endret av OVOXO
Lenke til kommentar

Vel jeg kan ta tak i noen av problemene her ;)

 

Arrayet

For det første, når du skal ha et array hvor størrelsen bestemmes under kjøring så må du gjøre noe aktivt for å allokere arrayet:

float n[10];

Dette gir et array med 10 elementer, hvor første element er n[0] og siste element er n[9].

 

Én måte å allokere arrayet på er med calloc:

float *n = (float*)calloc(N, sizeof(float));

Merk at n er nå en peker til arrayet, og at du skal frigjøre minnet når du er ferdig med arrayet:

free(n);

Løkken

Det neste du bør se på er å fikse selve løkken:

for (float i = A ; i<=B ; i=A+T)

Hvis du ser hva i settes til i siste del så vil du se at denne løkken vil iterere uendelig.

Jeg antar at du ønsker å gjøre noe sånt:

for (float i = A ; i<=B ; i+=T)

Jeg har lagt ved en fil som har gjort disse endringene og som vil kjøre. Nå kan ikke jeg garantere at det løser oppgaven, og logikken i koden din er ellers uendret.

 

 

 

I tillegg så er der en rekke småpirk som kan påpekes:

Variabelnavn

I C er det vanligst å skrive variabelnavn på følgende måte: min_fantastiske_variabel, som kalles underscore. Mange foretrekker derimot camelCase som vil se ut som minFantastiskeVariabel; Uavhengig av hva du velger så bør du være konsekvent så du ikke har noen variabler med liten forbokstav og andre med stor. Du bør også unngå to variabler som heter det samme hvor den ene har stor forbokstav og anden andre har liten, det gir svært forvirrende kode (eksempel n og N i koden din).

 

Whitespace, indentering og newline

Du bør være konsekvent på bruken av whitespace, indentering og newline. Her finnes det også et hav av konvensjoner, og så lenge du koder for deg selv så kan du finne din egen. Men husk at det er svært irriterende for andre å lese kode som er inkonsekvent. Jeg anbefaler å bruke whitespace til indentering, siden tabs kan representeres ulikt. Det ser også best ut om du noen gang skal bruke git eller lignende. Hvor mange whitespaces som brukes kan diskuteres, både 2, 4 og 8 er vanlig, selv om 4 trolig er det mest vanlige (f.eks. Linux-kjernen bruker derimot 8). Du bør også velge hvordan du bruker whitespace rundt operatorer(=, <=, ==, +=, osv.) og paranteser. Angående newline så bør du også velge et prinsipp. Jeg ser f.eks. at du har newline for bracket inne i for-løkken men at neste statement fortsetter på samme linje som bracket.

 

 

 

Jeg kunne fortalt mye mer om koden i detalj, men det er grenser for hva folk klarer å forstå umiddelbart. Nå vet ikke jeg om dette er en skoleoppgave eller lignende, men du må gjerne spørre etter mer hjelp og forklaringer her på forumet. Du får sannsynligvis mer hjelp av dyktige kodere her enn fra skolen.

test.zip

  • Liker 1
Lenke til kommentar
  • 2 uker senere...

Prøver meg igjen;

 

Jeg har en temperaturmåler som leser av tallverdier, oppgaven går ut på at jeg skal avgi en temperatur også skal sensoren prøve å justere seg til eksakt verdi ved å øke/minke temperaturen. Den første testen sjekker om temperaturen er innenfor avgitt verdi med feilmargin på -/+ 10, hvis dette stemmer skal den gjøre noen modifikasjoner på temperaturen og dette skal gjentas til den treffer den avgitte temperaturen. Hvis temperaturen har et avvik på større enn 10, skal den da gjøre litt mer drastisk modifikasjoner frem til den er rundt +/- 10 fra avgitt temperatur. Samtidig hvis den består første testen kan temperaturmåleren fortsatt utsettes for sterk temperaturendring utenfra, og da skal den isteden kjøre den mer drastiske modifikasjoner. Dette skal kjøres i en evig while løkke.

 

Jeg tenkte å løse problemet med to forskjellig if -løkker, men lurte på om noen hadde forslag til hvordan jeg kan få programmet til å kjøre if-løkkene evig og evt. bytte hvis det skjer plutselig endringer i miljøet? :)

Lenke til kommentar

Jeg kan i det minste gi deg noen hint ;)

En while-løkke kan brukes litt som en for-løkke og vil kjøre så lenge et statement er sant:

while (statement) {
     //do something...
}

Hvis statement aldri er sant så kjører den aldri, hvis statement alltid er sant så kjører den evig.

 

Eksempel:

while (1) {
    printf("Ha!\n");
}

Du kan avbryte løkken med break.

 

Her er et eksempel med en løkke som kjører ti ganger:

int n = 0;

while (1) {

    printf("%i\n", ++n);

    if (n == 10) break;

}

printf("Done.\n");

Jeg ser for meg at du skal putte if-testene dine inne i en evig løkke.

 

Lek litt med dette og fortell oss hvor langt du kommer.

Lenke til kommentar

Tror jeg var litt dårlig til å formulere :p Men spørsmålet mitt var som følger, hvis vi tar en konkret situasjon;

 

Jeg avgir først en temperatur. Deretter har jeg en evig while løkke og inni den har jeg tre if/else tester.

 

Den første if testen sjekker om temperaturen er feil med  -10 <  x<+10 Da vil en funksjon inni if testen redusere temperaturen litt. Og denne vil da kjøre til temperaturen er lik det jeg avga.

 

Så har jeg en annen if test som kjører hvis temperaturen er over grensa på -/+ 10 som fører til at en funksjon som endrer temperaturen dramatisk kjører.

 

Og tilslutt vil jeg ha en else hvor den da er lik temperaturen jeg anga.

 

Si hvis jeg ønsker at temperaturen skal være 20*C. Den leser av temperaturen på 29*C, da vil den første if testen kjøre, men si jeg plutselig setter på peisen og temperaturen øker til 40*C, vil den da kunne gå ut av den første if testen og kjøre if løkke nummer 2 istedet?

Endret av OVOXO
Lenke til kommentar

Her er kode som gjør det du vil:

const float TARGET_TEMP = 20;

float hentTemperaturFraNoe() { return 23f; /*implementer selv*/}
bool floatWithinRange(float actual, float target, float delta) {
  return actual => target - delta && actual =< target + delta
}

int main() {
  while (true) {
    float temp = hentTemperaturFraNoe();
    if (floatWithinRange(temp, TARGET_TEMP, 0.1f)) {
      //temp is close to 'equal' to TARGET_TEMP
      //do something awesome
    }
    else if (floatWithinRange(temp, TARGET_TEMP, 10f)) {
      //do something awesome
    }
    else if (floatWithinRange(temp, TARGET_TEMP, 20f)) {
      //do something awesome
    }
  }
}

Usikker på om jeg skjønte hva du faktisk vil ha i if sjekkene dine, men der er en start.

Egentlig for temperatur bruker man en PID klontroller.

https://en.wikipedia.org/wiki/PID_controller

Disse kan kan ligne dette:

const float TARGET_TEMP = 20;

float hentTemperaturFraNoe() { return 23f; /*implementer selv*/}
float settTemperatur(float temp) { /*implementer selv, sett temp*/ }

int main() {
  float previous_error = 0;
  float integral = 0;
  float dt = 1; //loop every second
  while (true) {
    float measured_value = hentTemperaturFraNoe();
    float error = TARGET_TEMP - measured_value;
    integral = integral + error*dt;
    float derivative = (error - previous_error)/dt;
    float output = Kp*error + Ki*integral + Kd*derivative;
    float previous_error = error;
    settTemperatur(output);
    sleep(dt); //find a way to halt execution for dt seconds
  }
}

Endret av Enthroner
  • Liker 1
Lenke til kommentar

 

... vil den da kunne gå ut av den første if løkken og kjøre if løkke nummer 2 istedet?

Det er ingenting som heter "if løkke". 

Du har en while løkke med 3 if/else tester som evalueres for hver eneste runde i løkken.

 

 

Beklager, gikk litt fort. :)

Lenke til kommentar

 

Usikker på om jeg skjønte hva du faktisk vil ha i if sjekkene dine, men der er en start.

Egentlig for temperatur bruker man en PID klontroller.

https://en.wikipedia.org/wiki/PID_controller

Disse kan kan ligne dette:

const float TARGET_TEMP = 20;

float hentTemperaturFraNoe() { return 23f; /*implementer selv*/}
float settTemperatur(float temp) { /*implementer selv, sett temp*/ }

int main() {
  float previous_error = 0;
  float integral = 0;
  float dt = 1; //loop every second
  while (true) {
    float measured_value = hentTemperaturFraNoe();
    float error = TARGET_TEMP - measured_value;
    integral = integral + error*dt;
    float derivative = (error - previous_error)/dt;
    float output = Kp*error + Ki*integral + Kd*derivative;
    float previous_error = error;
    settTemperatur(output);
    sleep(dt); //find a way to halt execution for dt seconds
  }
}

Fantastisk, er dette jeg er på utkikk etter :D , men er et par ting jeg lurer på;

 

Hva er det return 23f gjør? Lurte også på hvordan man finner konstantene Kp, Ki og Kd? :hmm:

Endret av OVOXO
Lenke til kommentar

Aha, hvis jeg ønsker å innføre et lignende system for en båt som påvirkes av ytre krefter hvor jeg har mulighet til å avlese posisjon og styre hastigheten på motoren, vil jeg kunne være i stand til å beregne hva hastigheten må være for at jeg skal nå setpunktet? Hvis jeg beregnet output for posisjonen? Eller er jeg kun istand til å vite om hastigheten må økes/senkes utifra om output er positiv/negativ?

Lenke til kommentar

Programmet er ikke verre enn at en avgir en posisjon som båten skal holde i kun 1D, i tillegg til at den vil bli dratt bak av en kraft, og evt. dyttet på litt. Ville verdien man får ved output være mulig å beregne nøyaktig hastighet motoren måtte ha? Har googlet rundt og sett på et par yt videoer, men i de fleste tilfellene beregnes det på enten bare strøm som skal gis til motoren eller posisjonen til selve motoren :hm:

Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...