Opettelen tässä C:tä ja ohjelma on vielä keskeneräinen mutta yritän saada sen toimimaan tähän asti. Eli ohjelman suorituksen pitäis päättyä kun käyttäjä syöttää nollan, case kakkosessa "uhkapelaa" ja palaa do-lauseen alkuun ja sitten muissa tapauksissa palaa myös do-lauseen alkuun. Onko tuo do-while-lause edes oikein tehty jne... Tämmönen errori tulee kun yritän kääntää gcc:llä:
main.c:27: error: expected ';' before 'return'
Virhe voi tietysti olla jossain muussakin tiedostossa kuin main.c:ssä, mutta aloitetaan tästä:
main.c
#include "wallet.h" #include "gamble.h" #include <stdio.h> int main(void) { Wallet w = 100.0; int option; do { walletPrintBalance(w); printf("1. Visit the bank\n2. Visit the casino\n0. Exit program\n"); scanf("%d", &option); switch (option) { case 1: break; case 2: gamble (w); break; default: break; } } while (option) return 0; }
Lisää puolipiste while (option) rivin loppuun...
Siitähän se olikin kiinni. Osaako joku selittää miksi tohon puolipisteen tarvitsee?
Se on ihan C:n syntaksia. Kernighanin ja Ritcien teoksessa The C programming language lukee
The syntax of the do is
do statement while (expression);
Ja olisi aika epäselvää, jos joihinkin käskyihin tarvitsisi puolipisteen, mutta joihinkin ei. :P
Juhko kirjoitti:
Ja olisi aika epäselvää, jos joihinkin käskyihin tarvitsisi puolipisteen, mutta joihinkin ei. :P
Eihän niitä kaikkiin tarvitakaan, vaan laitetaan selkeyden vuoksi jos sattuu huvittamaan. Seuraava koodi toimii mainiosti:
int main(void){ int var = 0; do if(var == 0) var++; else if(var < 100) do var--; while(var > 0); goto label; else label: switch(var) case 1: do{ var += 3; case 5: var -= 4; default: var++; } while(var < 5 && var > -100); while(var > 8 << 8) var++; while(var < 5 && var > -5); }
ville-v kirjoitti:
Seuraava koodi toimii mainiosti:
GCC on eri mieltä. Ensimmäisenä huomauttaa siitä, että "do" pitäisi päättää rivin "while(var > 0);" jälkeen, mutta seuraavana onkin goto. Jos tuossa oli tarkoitus olla lauseita, jotka eivät pääty puolipisteeseen (tai lohkon lopettavaan aaltosulkuun), niin niitäkään en näe.
Mitä seuraava funktio palauttaa?
int f(void) { if (a == b) if (b == c) return 0; else return 1; return 2; }
Entä mikä on taulukon T sisältö seuraavan koodin lopussa?
int T[8] = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; int i = 0, j = 0; T[++j] = T[j++] + T[i++] + T[++i] + (i++) + j + T[j]++;
C:n (ja myös C++:n) standardi sisältää kohtia, joissa toiminta on määrittelemätöntä tai implementaation päätettävissä. Tämän takia ville-v:n kirjoittamaa koodia pitäisi ehdottomasti välttää, koska sen voi täysin perustellusti tulkita virheelliseksi juuri tuolla tavalla, kuin hunajavohveli kertoi.
Minusta ville-v:n vastaus meni muutenkin asian ohi, koska koodi ei demonstroinut tilannetta, jossa puolipiste olisi vapaaehtoinen. Minä en ainakaan tiedä yhtään merkintää, jossa olisi tapana käyttää ylimääräistä puolipistettä "selkeyden takia".
Puolipisteiden käyttöä voi ihailla tässä vanhassa keskustelussa.
Onko tuon funktion toiminta todellakin määrittelemätön? Itse olen ollut siinä uskossa, että standardin mukaan else liittyy aina lähimpään edeltävään ifiin, jolloin oikea jäsennys olisi väistämättä:
int f(void) { if(a == b) if(b == c) return 0; else return 1; return 2; }
Edit: ville-v:n koodissa en kokonaisuutena näe mitään tapaa, jolla sen voisi tulkita kelvolliseksi syntaksiksi.
hunajavohveli kirjoitti:
Itse olen ollut siinä uskossa, että standardin mukaan else liittyy aina lähimpään edeltävään ifiin
Tässä tapauksessa käykin tuuri. Valitettavasti merkitys ei kuitenkaan muutu erilaisella sisennyksellä (kuten ville-v:n while-silmukka osoitti), ja siksipä aloittelija onkin hukassa, kun sattuu luulemaan väärin päin:
if (x) if (y) f(); else g(); // if (x) { if (y) f(); else g(); }, vaikka toisin kai tarkoitettiin.
Muistaakseni joku on jo tätäkin ehtinyt foorumilla kysellä.
Keksiikö joku, millä logiikalla GCC sai taulukkoesimerkkini tiivistettyä seuraavaan muotoon?
T[1] = 101; i = 3; j = 2;
Metabolix kirjoitti:
Tässä tapauksessa käykin tuuri. Valitettavasti merkitys ei kuitenkaan muutu erilaisella sisennyksellä
Ei sellaista mielestäni kukaan ole väittänytkään tai antanut ymmärtää. Sen sijaan viestistäsi, että jotkin asiat ovat standardin mukaan määrittelemättömiä sai helposti käsityksen, että esittämäsi esimerkit olisivat olleet sellaisia.
Varmaan kaikki ymmärtävät että C:ssä "whitespacen" määrällä ja laadulla ei ole merkitystä lopputulokseen.
Metabolix kirjoitti:
Keksiikö joku, millä logiikalla GCC sai taulukkoesimerkkini tiivistettyä seuraavaan muotoon?
T[1] = 101; i = 3; j = 2;
No nuo i ja j nyt on triviaaleja, mutta oma veikkaukseni on, että se huomioi vain ne muuttujat, joissa i tai j arvo asetetaan ennen laskemista tai ei muutu, eli merkitsemäni:
T[++j] = T[j++] + T[i++] + T[++i] + (i++) + j + T[j]++; ^^^^^^ ^^^^^ ^
Eli ++i tuottaa i:ksi 1, jolloin T[1]=100, i++ on luettaessa vielä 1, j on luettaessa nolla, sitten j:tä kasvatetaan 1:ksi ja sijoitetaan tulos T[1]:een ja loput yhteenlaskun osat katoavat bittitaivaaseen.
Täytyy kyllä sanoa, että vähintään hämärä ja olen 99% varma että arvaukseni on ihan pieleen.
Aihe on jo aika vanha, joten et voi enää vastata siihen.