Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C, vertailuoperaattorit

Sivun loppuun

Neepi [04.12.2019 12:18:18]

#

Hei,
Aloittelen ohjelmointia ja opiskeluiden myötä tuli vastaan tehtävä, jossa en pääse eteenpäin. Eli en osaa rakentaa koodia niin, että Ohjelmassa tapahtunut virhe!, ei tulostuisi joka kerralla.

Tämän pitäisi tulostua näin:

Juotko kahvia vai teetä (k/t)?k
Montako kuppia juot päivässä:2
Et taida juoda paljoa kahvia.

Mutta tulostuu näin:
Juotko teetä vai kahvia (t / k): k
Montako kuppia juot päivässä: 2
Et taida juoda paljon kahvia.
Ohjelmassa tapahtunut virhe!

#include <stdio.h>

int main(void)
{
	char kahvi;
	char vastaus;
	int kokonaisluku;

	printf("Juotko teetä vai kahvia (t / k): ");
	kahvi = getchar();
	getchar();


	if (kahvi == 'k') {
		printf("Montako kuppia juot päivässä: ");
		scanf("%d", &kokonaisluku);

		if (kokonaisluku <= 2)
			printf("Et taida juoda paljon kahvia.\n");
		else if (kokonaisluku >= 3 && kokonaisluku <=20)
			printf("Juotpa paljon kahvia!\n");
		else
			printf("Ohjelmassa tapahtunut virhe!\n");


	} else if (kahvi == 't' )
		printf("Montako kuppia juot päivässä? ");
		scanf("%d", &kokonaisluku);

		if (kokonaisluku <= 2 && kahvi == 't')
			printf("Et taida juoda paljon teetä.\n");
		else if (kokonaisluku >= 3 && kokonaisluku <=20 && kahvi == 't')
			printf("Juotpa paljon teetä!\n");
		else
			printf("Ohjelmassa tapahtunut virhe!\n");

	return 0;
}

Grez [04.12.2019 12:31:39]

#

Sisennyksesi johtavat harhaan, tässä sama koneellisesti korjatuilla sisennyksillä:

#include <stdio.h>

int main(void)
{
    char kahvi;
    char vastaus;
    int kokonaisluku;

    printf("Juotko teetä vai kahvia (t / k): ");
    kahvi = getchar();
    getchar();


    if (kahvi == 'k')
    {
        printf("Montako kuppia juot päivässä: ");
        scanf("%d", &kokonaisluku);

        if (kokonaisluku <= 2)
            printf("Et taida juoda paljon kahvia.\n");
        else if (kokonaisluku >= 3 && kokonaisluku <= 20)
            printf("Juotpa paljon kahvia!\n");
        else
            printf("Ohjelmassa tapahtunut virhe!\n");


    }
    else if (kahvi == 't')
        printf("Montako kuppia juot päivässä? ");
    scanf("%d", &kokonaisluku);

    if (kokonaisluku <= 2 && kahvi == 't')
        printf("Et taida juoda paljon teetä.\n");
    else if (kokonaisluku >= 3 && kokonaisluku <= 20 && kahvi == 't')
        printf("Juotpa paljon teetä!\n");
    else
        printf("Ohjelmassa tapahtunut virhe!\n");

    return 0;
}

Kuten nyt ehkä helpommin huomaa, tuon "else if (kahvi == 't')" jälkeen vain seuraava rivi suoritetaan vain kun vastaat t, muut suoritetaan myös vaikka vastaisit k.

Suositus on laittaa jokainen if:llä ja elsellä suoritettava lohko { } merkkeihin, niin vältät helpommin tuollaiset virheet.

Sinänsähän tuo toimii kai "oikein", jos vastaat juovasi teetä.

Neepi [04.12.2019 15:19:35]

#

Kiitos vastauksesta. Täytyy kerrata aaltosulkeiden käyttöä. En vieläkään ymmärrä, mitä minun pitäisi tuohon korjata.

Grez [04.12.2019 15:23:18]

#

No sinulla on kaksi lähes identtistä lohkoa, joista if (kahvi == 'k') jälkeisen olet laittanut kaarisulkeisiin ja else if (kahvi == 't') jälkeistä et ole laittanut kaarisulkeisiin. Muutenkin näyttää kohtuu ilmeiseltä että ole tarkoittanut tuohon jälkimmäiseenkin kaarisulkeet kuten sisennyksestäsi voisi päätellä.

Siis voisi kuvitella, että olet tarkoittanut tällaista:

#include <stdio.h>

int main(void)
{
	char kahvi;
	char vastaus;
	int kokonaisluku;

	printf("Juotko teetä vai kahvia (t / k): ");
	kahvi = getchar();
	getchar();


	if (kahvi == 'k') {
		printf("Montako kuppia juot päivässä: ");
		scanf("%d", &kokonaisluku);

		if (kokonaisluku <= 2)
			printf("Et taida juoda paljon kahvia.\n");
		else if (kokonaisluku >= 3 && kokonaisluku <=20)
			printf("Juotpa paljon kahvia!\n");
		else
			printf("Ohjelmassa tapahtunut virhe!\n");


	} else if (kahvi == 't' ) {
		printf("Montako kuppia juot päivässä? ");
		scanf("%d", &kokonaisluku);

		if (kokonaisluku <= 2)
			printf("Et taida juoda paljon teetä.\n");
		else if (kokonaisluku >= 3 && kokonaisluku <=20)
			printf("Juotpa paljon teetä!\n");
		else
			printf("Ohjelmassa tapahtunut virhe!\n");
    }

	return 0;
}

Huomaatko eron omaan koodiisi?

Neepi [04.12.2019 17:34:38]

#

Jes, kiitos! Tämä onnistui vihdoin.

Jaska [05.12.2019 09:17:12]

#

Minusta ainakin jotkut ohjelmoijat tykkäävät ajatella lukujen suuruusjärjestystä lukusuorana, jolloin vasemmalla on pienemmät luvut ja oikealla suuremmat. Tällöin vertailun kokonaisluku >= 3 voisi muuttaa muotoon 3 <= kokonaisluku. Jos suuruusvertailuissa käyttää aina vaan muotoa x<y tai x<=y vartailujen y>x ja y>=x asemesta, näkee heti, että kumpi luvuista onkaan suurempi tai yhtäsuuri kuin toinen.

The Alchemist [05.12.2019 11:47:46]

#

Jos tuo Jaskan teoria pitää paikkansa, niin se on omasta mielestäni huono tapa. Itse kirjoitan aina "jutun ytimen" ensin eli sen asian, jonka arvoa halutaan tarkastella, ja viimeiseksi sen, johon tarkasteltavaa arvoa verrataan. Vähän niin kuin kirjoittaisit päässäsi tarinaa. (Jos susia on laumassa enemmän kuin kaksi, ne syövät sinut.)

Olen itse ollut havaitse omani joidenkin kirjoittavan vertailun juuri eri päin mutta olen kuvitellut sen olevan sitä varten, että vakion tullessa ensimmäisenä näkee hidaslukuinen ohjelmoija nopeammin, minkä ehdon täyttyessä lohkossa oleva koodi suoritetaan. Mutta itse kirjoitan vain hyvin muotoiltua koodia, jolloin ei tarvitse kirkkailla, jotta roskasta saisi jotain selvää.

Grez [05.12.2019 11:59:16]

#

Olen samaa mieltä Alchemistin kanssa.

En niele ollenkaan tuota väitettä:

Jaska kirjoitti:

Jos suuruusvertailuissa käyttää aina vaan muotoa x<y tai x<=y vartailujen y>x ja y>=x asemesta, näkee heti, että kumpi luvuista onkaan suurempi tai yhtäsuuri kuin toinen.

Mielestäni toisinkin päin kirjoitettuna näkee heti kumpi luvuista on suurempi, se merkki on ihan yhtä helppo hahmottaa kummin päin vain.

Jos iso joukko ohjelmoijista olisi sitä mieltä, että on hyvä tapa kirjoittaa aina käyttäen vain < tai <= eikä koskaan > tai >= niin meillä olisi varmaan jo tarjolla ohjelmointikieli, jossa > ja >= operaattoreita ei olisi tarjolla.

Matematiikassakin on mielestäni (en ole matemaatikko joten voin olla väärässäkin) useimmiten tapana kirjoittaa muuttuja ensin, tyyliin x > 3 eikä 3 < x vaikka kumpikin varmasti on sinänsä hyväksyttävä merkintä.

Poikkeus on ehkä jos halutaan ilmaista väliä tyyliin:
2 < x < 5
eli x = ]2,5[

Ohjelmointikielillähän tuollaista kaksoisvertailua ei yleensä suoraan voi kirjoittaa, mutta jos ohjelmoija haluaa koodin vastaavan mahdollisimman hyvin matemaattista esitystä, niin voisin tuolla perusteella pitää ok:na myös:
2 < x && x < 5
vaikka itse normaalisti kirjoittaisinkin:
x > 2 && x < 5


Sivun alkuun

Vastaus

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

Tietoa sivustosta