Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Puolipiste puuttuu?

Sivun loppuun

Palvy [01.02.2009 14:55:23]

#

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;
}

Juhko [01.02.2009 15:16:12]

#

Lisää puolipiste while (option) rivin loppuun...

Palvy [01.02.2009 15:27:28]

#

Siitähän se olikin kiinni. Osaako joku selittää miksi tohon puolipisteen tarvitsee?

Jaska [01.02.2009 15:33:10]

#

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);

Juhko [01.02.2009 17:12:39]

#

Ja olisi aika epäselvää, jos joihinkin käskyihin tarvitsisi puolipisteen, mutta joihinkin ei. :P

ville-v [01.02.2009 17:29:55]

#

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);
}

hunajavohveli [01.02.2009 18:02:25]

#

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.

Metabolix [02.02.2009 14:40:17]

#

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.

hunajavohveli [02.02.2009 20:30:12]

#

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.

Metabolix [02.02.2009 21:46:53]

#

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;

Grez [02.02.2009 22:36:56]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta