Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Koulutehtävä: Suurin ja pienin luku

Sivun loppuun

Shooter99 [09.10.2012 14:20:00]

#

Moi Taas...

En viitsi aloittaa uutta topiccia niin laitan tänne vanhan jatkoksi... (Mod. huom: Aloita aina uusi, kun kysymys vaihtuu.)

Tehtävän anto on seuraava:

Tee ohjelma, joka ottaa vastaan kolme kokonaislukua ja tulostaa syötetyistä luvuista sekä pienimmän että suurimman. Pääohjelman tulee kysyä ja vastaanottaa kokonaisluvut. Laadi funktiot suurin() ja pienin(), jotka saavat parametreina syötetyt luvut. Vastaavasti funktiot palauttavat nimensä mukaiset arvot.

Vihje
Voit käyttää ohjelmassasi yhdistettyjä vertailuja ja if-else rakennetta.
Esimerkkitulostus

Anna 1. luku:1
Anna 2. luku:2
Anna 3. luku:3
Syöttämistäsi luvuista suurin oli 3 ja pienin 1.

Koodini on tämä:

#include<stdio.h>

int pienin();
int suurin();
int luku1, luku2, luku3;

int main(){

	int a, b, c, suurempi, pienempi;

	printf("Anna 1. luku:");
	scanf("%d", &a);
	printf("Anna 2. luku:");
	scanf("%d", &b);
	printf("Anna 3. luku");
	scanf("%d", &c);
	suurempi = suurin(a,b,c);
	pienempi = pienin(a,b,c);
	printf("Syöttämistäsi luvuista suurin oli %d ja pienin %d.", suurempi, pienempi);
}

int suurin(int luku1, int luku2, int luku3){
	int _suurin;

		if(luku1 < luku2 && luku1 < luku3){
			_suurin = luku1;
		}
		if(luku2 < luku1 && luku2 < luku3){
			_suurin = luku2;
		}
		else{
			_suurin = luku3;
		}
	}

int pienin (int luku1, int luku2, int luku3){
	int _pienin ;

		if(luku1 > luku2 && luku1 > luku3){
			_pienin = luku1;
		}
		if(luku1  > luku3 && luku2 > luku3){
			_pienin = luku2;
		}
		else{
			_pienin = luku3;
		}
	return 0;
}

saan tulokseksi isoin on 3 ja pienin on 0.
Eli onko toi isoin lukukaan oikein määritetty ?

vai onko koko hoito ihan päin peeeeetä...

Mod. lisäsi kooditagit!

Grez [09.10.2012 14:40:43]

#

No onhan toi nyt päin peetä sikäli, että esim. pienin palauttaa aina nolla. Laitat kyllä erilaisia arvoja muuttujaan _pienin, mutta et koskaan käytä ko. muuttujaa mihinkään. Suurin-funktiosta taas et palauta mitään, että mikäli toi kuitenkin kääntyy niin yhtä hyvin sieltä voisi tulla -428001 kuin 3, joka nyt hirveellä hillolla sattuu olemaan oikein.

Lähestymistavallasi on mielestäni myös jokseenkin turhaa edes tehdä mitään apumuuttujia. Jos toteat että luku1 on suurin, voisit yhtä hyvin sanoa suoraan return luku1. Lisäksi noi toimii väärin päin. Ja kannattaa huomata että else liittyy sitä edelliseen if:iin. Eli vaikka noi vertailuoperaattorit olis oikein päin ja palauttaisit apumuuttujasi, niin et saisi koskaan luku1:ä tulokseksi, kun se olisi aina luku2 tai luku3.

Yleiskommenttina sanoisin, että ohjelmoinnin ei pitäisi olla lähtökohtaisesti "yritys & erehdys" -menetelmää.

The Alchemist [09.10.2012 15:32:12]

#

Jossei ihminen kykene ymmärtämään, kummalla puolella operaattoria '<' on suurempi ja kummalla puolella pienempi luku, niin voi unohtaa koodaamisen ihan kokonaan. Tämä on fakta.

Metabolix [09.10.2012 15:46:42]

#

Jos monen ehdon tekeminen peräkkäin tuntuu vaikealta, tee ensin funktio, joka vertailee kahta lukua oikein (eli tarvitset vain yhden ehdon), ja hyödynnä sitten tietoa, että suurin(a, b, c) on sama kuin suurempi(a, suurempi(b, c)).

Shooter99 [09.10.2012 16:04:59]

#

> < merkit on väärin päin koska olen koittanut vain että mitä tapahtuu jos arvot kääntää toisinpäin...

Enkä voi väittää olevani mikään jeesus koodaamisen suhteen koska alotin ko. homman kuitenkin viikko sitten että jos tässä vaiheessa pitää olla joku guru ennen kuin tänne voi kysymyksiä laittaa niin taidan vaihtaa sit foorumia...

The Alchemist [09.10.2012 18:30:31]

#

Olettaen ettet ole kovin paljon nuorempi kuin tuo numero nimimerkkisi perässä antaisi olettaa, niin logiikan perussäännöt saisivat jo olla hallussa. Toinen pointtini oli se, ettei tuossa pasteamassasi koodissa ole yritystä vähääkään. Tuon perusteella et ole yrittänyt ajatella minuuttiakaan. Ei tänne kannata kirjoitella kysymyksiä, joita ei ole itse pohtinut etukäteen. Vastausten laatu on suoraan verrannollinen kysymyksen laatuun.

1. Operaattorit ovat tosiaan ihan miten sattuu ja lähinnä väärin päin.
2. Toinen funktioistasi edes palauta mitään - kääntäjäsikin valittaa tästä.

Jos sinulla on vaikeuksia hahmottaa ehtolauseiden seuraamukset, niin otat kynän ja paperia ja emuloit koodia parilla eri syötteellä paperille. Jokaisen ehtolausekkeen jälkeen kirjoitat välivaiheen ylös, kunnet olet suorituksen lopussa.

pr0l3 [09.10.2012 19:16:13]

#

siis kuka kirjottaa koodiin return 0 ja kysyy että miksi tulos on 0? :DDD lintsari

Shooter99 [09.10.2012 22:04:02]

#

Noh kyllä ainkin tämä koulun kääntäjä menee ohjelman läpi eikä herjaa mitään virheitä... sen takia onkin vähän hankala tietää mistä etsiä vikaa...

Teuro [09.10.2012 22:30:28]

#

Eka veto:

Anna 1. luku:10
Anna 2. luku:25
Anna 3. luku105
Syöttämistäsi luvuista suurin oli 105 ja pienin 0.
Process returned 50 (0x32)   execution time : 4.825 s
Press any key to continue.

Syöttestä nähdään, että suurin luku oli 105 ja pienin oli 10. Pienimmän haku siis toimii väärin. Tutkitaan siis kyseistä funktiota. Rivi riviltä tutkittuna funktio käyttäytyy seuraavasti:

Eli täysin riipumatta syötteistä funktio palauttaa arvon nolla. Samalla tavalla kannattaa tuo suurin funktio tarkistaa ajatuksen kanssa.

User137 [09.10.2012 22:54:57]

#

Pitää testata useammilla tavoilla, esim:
1, 2, 3
3, 2, 1
2, 3, 1
1, 3, 2
Kaikkien tapauksienhan pitää toimia. Voi olla että se "hillolla" toimiva suurimman luvun etsintäkin palauttaa väärin, kun jo sanottiin että return puuttuu kokonaan.

Blaze [09.10.2012 23:13:32]

#

User137 kirjoitti:

Pitää testata useammilla tavoilla, esim:

1, 1, 1
5, 5, 9
8971623, 19472386, 1239874
-13, 7, -8

Shooter99 [10.10.2012 00:08:35]

#

Ensinnäkin SUURI KIITOS TEURO!!!

- onko esiteltävän muuttujan arvo pakko alustaa ?

Joku sentäs puhuu vielä suomeakin nyt ymmörsin jo että mikä on virheellistä kyseisessä lausekkeessa.

muutin pätkää näin.

int suurin(int luku1, int luku2, int luku3){
	int _suurin ;

    if(luku1 > luku2 && luku1 > luku3){
        _suurnn = luku1;
    }
    if(luku2  > luku1 && luku2 > luku3){
        _suurin = luku2;
    }
    if(luku3 > luku1 && luku3 > luku2){
        _pienin = luku3;
    }

}

Luulin että return 0; pitää olla aina koodin lopussa...

Mod. korjasi kooditagit!

User137 [10.10.2012 01:50:31]

#

Mitä kääntäjää käytät? Jos tuo menee läpi niin sulla on asetukset väärin ja se käyttää "viimeisintä toimivaa versiota". (suurnn = luku1) Sen voit testata vaikka printtaamalla "Hello world" ohjelman alussa. Jos ei näy niin mitään mitä teet koodiin ei ole vaikutusta, eikä olis ihme ettei kääntäjä varoita.

Visual Studiossa se tapahtuu Options valikosta:
Projects and Solutions -> Build and Run:
- Project out of date -> Always build
- When deployment errors occur -> Do not launch

int suurin(int luku1, int luku2, int luku3)
Sen takia että funktiosi tyyppi on int (eikä void), niin vähintään kerran tulee return:a kutsua numeron kanssa. Missään ei sanota että juuri nolla pitää palauttaa, eikös sinun pitänyt antaa funktion tuloksena se suurin luku?

Teuro [10.10.2012 11:10:11]

#

Shooter99 kirjoitti:

- onko esiteltävän muuttujan arvo pakko alustaa ?

Tähän kysymykseen sinun pitää itse löytää tai päätellä vastaus.

Shooter99 kirjoitti:

muutin pätkää näin.
– –
Luulin että return 0; pitää olla aina koodin lopussa...

Nythän tuo funktiosi ei palauta mitään, vaikka ilmoitat sen palauttavan int luvun. Mieleesi on ehkä jäänyt (virheellinen) mielikuva return lauseesta? Muutoinkin funktio on täynnä virheitä.

Sen avulla funktio palauttaa jonkun arvon. Tässä funktiossa pitäisi siis palauttaa juurikin tuo _pienin muuttujan sisältämä arvo.

Funktio saattaisi näyttää vaikkapa tällaiselta.

int pienin(int luku1, int luku2, int luku3) {
    if (luku1 < luku2 && luku1 < luku3) {
        return luku1;
    } else if (luku2 < luku1 && luku2 < luku3) {
        return luku2;
    }

    return luku3;
}

Tässä on oletuksena, että kaikki luvut ovat erilaisia. Esimerkiksi syötteellä 1, 1, 3 (ja muilla vastaavilla) funktio toimii virheellisesti.

Grez [10.10.2012 11:12:45]

#

Tuosta "Nolla pitää palauttaa" hommasta tulee mieleen että joko opetuksessa on menty perse edellä puuhun tai sitten sitä ei ole ymmärretty.

Eli siis hommahan menee niin, että ohjelman pääfunktion (main) pitäisi palauttaa tieto että onnistuiko suoritus vai tapahtuiko joku virhe. On siis lähtökohtaisesti väärin ajatella, että sen pitäisi palauttaa aina 0. Se, että virhettä ei tapahtunut, ilmaistaan arvolla 0. Eli alkeita kun harjoitellaan, niin yksinkertaisuuden nimissä sinne laitetaan että se ilmoittaa aina onnistuneensa, eli return 0. Se ei kuitenkaan tarkoita edes sitä että main-funktion pitäisi aina palauttaa nolla (kuten yllä lihavoidusta käy ilmi) eikä varsinkaan että minkään muun funktion pitäisi palauttaa nolla.

Eli, jos on opetettu että pitää aina palauttaa nolla, niin on menty perse edelle puuhun. Tai jos on opetettu se mitä edellä kirjoitin, niin opetus on OK, mutta ymmärrys on ollut se copy&paste-koodarin lähestymistapa, että esimerkkikoodissa lukee return 0 -> aina pitää palauttaa 0.

jalski [10.10.2012 17:32:49]

#

Kannattaa opiskellessa muistaa, että yksinkertainen on kaunista ja varmasti myös helpompi hahmottaa.

Miksei pienimmän kolmesta luvusta palauttavaa funktiota kirjoittaisi yksinkertaisesti vain:

int pienin(int luku1, int luku2, int luku3)
{
	int pienin = luku1;

	if (luku2 < pienin)
		pienin = luku2;
	if (luku3 < pienin)
		pienin = luku3;

	return pienin;
}

Macro [10.10.2012 18:29:28]

#

Kun sitä sitten halutaan laajentaa toimimaan vaikka taulukolla, niin pseudokoodilla menisi vaikka näin...

int pienin(int[] luvut) {
	int pienin = luvut[0];

	for(int i = 1; i < size(luvut); i++) {
		if(luvut[i] < pienin)
			pienin = luvut[i];
	}

	return pienin;
}

Pete2 [10.10.2012 18:45:21]

#

jalski kirjoitti:

Kannattaa opiskellessa muistaa, että yksinkertainen on kaunista ja varmasti myös helpompi hahmottaa.

Yksinkertaisuus on vain harvoin tehokasta.

int pienin( int luku1, int luku2, int luku3 )
{
	if( luku1 < luku2 )
	{
		if( luku3 < luku1 )
			return luku3;
		return luku1;
	}

	if( luku2 < luku3 )
		return luku2;

	return luku3;
}

jalski [10.10.2012 19:25:01]

#

Pete2 kirjoitti:

Yksinkertaisuus on vain harvoin tehokasta.

Tarkastitko kääntäjän tuottamat assembly listaukset, vai arvaatko vain?

Pete2 [10.10.2012 21:00:36]

#

jalski kirjoitti:

Tarkastitko kääntäjän tuottamat assembly listaukset, vai arvaatko vain?

Kuka tahansa assemblyn alkeet opetellut osaa suoraan sanoa, kuinka hidasta purkkaa funktiosi on: siihen ei tarvita mitään tarkistuksia. Kai nyt itsekin näet, että varaat muistia ja pahimmassa tapauksessa siirrät kaksi kertaa arvon muistista rekisteriin ja rekisteristä muistiin. Tämä kaikki siis täysin turhaan.

jalski [10.10.2012 21:36:38]

#

Pete2 kirjoitti:

Kuka tahansa assemblyn alkeet opetellut osaa suoraan sanoa, kuinka hidasta purkkaa funktiosi on: siihen ei tarvita mitään tarkistuksia. Kai nyt itsekin näet, että varaat muistia ja pahimmassa tapauksessa siirrät kaksi kertaa arvon muistista rekisteriin ja rekisteristä muistiin. Tämä kaikki siis täysin turhaan.

Ehkäpä kannattaisi hiukan kerrata niitä alkeita... ;-)

Eiköhän suurin osa kääntäjistä osaa käyttää rekistereitä funktion argumenttien välittämiseen. Ja vaikka tuohon käytettäisiinkin pinoa, niin käyttämäni kääntäjä ainakin kuitenkin käyttää rekisteriä tuon yhden lokaalin muuttujan tallentamiseen.

Versiosi on käyttämälläni kääntäjällä 26 tavua suurempi, eikä taida olla yhtään tehokkaampi.

      0x00000000(1/1/59)           ***Instruction eliminated     ;Start of function pienin
      0x00000000(2/1/59)           push      ebp
      0x00000001(3/1/59)           mov       ebp,esp
      0x00000003(4/1/59)           push      ebx
      0x00000004(5/1/59)           push      esi
      0x00000005(6/1/59)           push      edi
      0x00000006(7/1/59)           sub       esp,=16   ;Adjusted later if temporaries allocated and maybe overwritten by subroutine call
      0x0000000C(8/1/59)           ***Instruction eliminated     ;Register ebx contains p
      0x0000000C(9/1/59)           mov       ecx,l3
      0x0000000F(10/1/59)          ***Instruction eliminated     ;Register ecx contains l3
   0006           int p = l1;                                                    AT F
      0x0000000F(11/3/42)          mov       ebx,l1
   0007                                                                          AT 12
   0008           if (l2 < p)                                                    AT 12
      0x00000012(12/4/45)          cmp       ebx,l2
      0x00000015(13/4/45)          jle       Label#2
   0009                   p = l2;                                                AT 1B
      0x0000001B(14/4/47)          mov       ebx,l2
      0x0000001E(15/3/49)       Label     Label#2
   0010           if (l3 < p)                                                    AT 1E
      0x0000001E(16/4/51)          cmp       ecx,ebx
      0x00000020(17/4/51)          jge       Label#3
   0011                   p = l3;                                                AT 26
      0x00000026(18/4/53)          mov       ebx,ecx
      0x00000028(19/3/55)       Label     Label#3
   0012                                                                          AT 28
   0013           return p;                                                      AT 28
      0x00000028(20/2/57)          mov       eax,ebx
      0x0000002A(21/2/57)          ***Instruction eliminated
      0x0000002A(22/1/59)       Label     Label#1
      0x0000002A(23/1/59)          lea       esp,[ebp-12]
      0x0000002D(24/1/59)          pop       edi
      0x0000002E(25/1/59)          pop       esi
      0x0000002F(26/1/59)          pop       ebx
      0x00000030(27/1/59)          pop       ebp
      0x00000031(28/1/59)          ret
      0x00000000(1/1/62)           ***Instruction eliminated     ;Start of function pienin
      0x00000000(2/1/62)           push      ebp
      0x00000001(3/1/62)           mov       ebp,esp
      0x00000003(4/1/62)           push      ebx
      0x00000004(5/1/62)           push      esi
      0x00000005(6/1/62)           push      edi
      0x00000006(7/1/62)           sub       esp,=16   ;Adjusted later if temporaries allocated and maybe overwritten by subroutine call
      0x0000000C(8/1/62)           mov       ebx,luku3
      0x0000000F(9/1/62)           ***Instruction eliminated     ;Register ebx contains luku3
      0x0000000F(10/1/62)          mov       ecx,luku2
      0x00000012(11/1/62)          ***Instruction eliminated     ;Register ecx contains luku2
   0006   	if( luku1 < luku2 )                                                   AT 12
      0x00000012(12/4/42)          cmp       ecx,luku1
      0x00000015(13/4/42)          jle       Label#2
   0007   	{                                                                     AT 1B
   0008   		if( luku3 < luku1 )                                                  AT 1B
      0x0000001B(14/6/44)          cmp       ebx,luku1
      0x0000001E(15/6/44)          jge       Label#3
   0009   			return luku3;                                                       AT 24
      0x00000024(16/6/46)          mov       eax,ebx
      0x00000026(17/6/46)          jmp       Label#1
      0x0000002B(18/5/48)       Label     Label#3
   0010   		return luku1;                                                        AT 2B
      0x0000002B(19/4/50)          mov       eax,luku1
      0x0000002E(20/4/50)          jmp       Label#1
      0x00000033(21/3/52)       Label     Label#2
   0011   	}                                                                     AT 33
   0012                                                                          AT 33
   0013   	if( luku2 < luku3 )                                                   AT 33
      0x00000033(22/4/54)          cmp       ecx,ebx
      0x00000035(23/4/54)          jge       Label#4
   0014   		return luku2;                                                        AT 3B
      0x0000003B(24/4/56)          mov       eax,ecx
      0x0000003D(25/4/56)          jmp       Label#1
      0x00000042(26/3/58)       Label     Label#4
   0015                                                                          AT 42
   0016   	return luku3;                                                         AT 42
      0x00000042(27/2/60)          mov       eax,ebx
      0x00000044(28/2/60)          ***Instruction eliminated
      0x00000044(29/1/62)       Label     Label#1
      0x00000044(30/1/62)          lea       esp,[ebp-12]
      0x00000047(31/1/62)          pop       edi
      0x00000048(32/1/62)          pop       esi
      0x00000049(33/1/62)          pop       ebx
      0x0000004A(34/1/62)          pop       ebp
      0x0000004B(35/1/62)          ret

Shooter99 [10.10.2012 21:59:15]

#

Teuro kirjoitti:

Shooter99 kirjoitti:

- onko esiteltävän muuttujan arvo pakko alustaa ?

Tähän kysymykseen sinun pitää itse löytää tai päätellä vastaus.

Olen käsittänyt että luvun voi alustaa haluttaessa jollekin luvulle mutta silti kyseinen luku ei ole kuin pienen hetken se ko. luku josta itse päättelen että alustaminen ei ole pakollista koska kuitenkin alustettu luku saa toisen arvon.

User137 kirjoitti:

Mitä kääntäjää käytät? Jos tuo menee läpi niin sulla on asetukset väärin ja se käyttää "viimeisintä toimivaa versiota".

Teemme tehtävät suoraa koulun moodle ympäristössä niin en oikeastaan tiedä edes mikä versio siellä on mutta eipä tunnu paljon herjailevan mitään...

Asensin tuon codeblocxin ja dev++:n ja koitan jos niillä saisin näitä virheitäkin esille ihan omatoimisesti.

Ja pakko myöntää että en ole mikään nopea oppimaan sekä täällä lueskellessani c kielen ohjeita niin ne joko eteni vähän turhan nopeasti minulle tai sitten vain en ymmärrä tarpeeksi basic kamaa ennen kuin alan lukemaan niitä...

Metabolix [10.10.2012 22:05:54]

#

Shooter99, voisitko ystävällisesti lukea keskustelun ohjeet ja käyttää viesteissäsi esim. lainaustageja ja kooditageja? Muuten viestejäsi on vaikea lukea, esim. edellisestä viestistäsi ei saanut paljonkaan selvää (ennen moderaattorin korjausta).

Selvästikään jalski ei käyttänyt kovin kummoisia optimointiasetuksia omassa testissään, kun funktioista suurin osa on täysin turhia push- ja pop-rivejä ja hyppykäskyjä.

GCC 4.7.2 -kääntäjä -O3-optimoinnilla tuottaa x86-64-koneelle tällaista:

jalski:
	cmpl    %edi, %esi
	movl    %edx, %eax
	cmovle  %esi, %edi
	cmpl    %edx, %edi
	cmovle  %edi, %eax
	ret

Pete2:
	cmpl    %esi, %edi
	jge     .L3
	cmpl    %edi, %edx
	movl    %edi, %eax
	cmovle  %edx, %eax
	ret
.L3:
	cmpl    %esi, %edx
	movl    %esi, %eax
	cmovle  %edx, %eax
	ret

Empiirisessä kokeessani nämä koodit ovat lähtökohtaisesti aivan yhtä nopeat, vaikka erilaisissa mutkikkaammissa tilanteissa niissä ilmeneekin satunnaisia eroja – kuten nykyään missä tahansa, kun prosessorit ovat niin outoja.

jalski [10.10.2012 22:40:00]

#

Metabolix kirjoitti:

Selvästikään jalski ei käyttänyt kovin kummoisia optimointiasetuksia omassa testissään, kun funktioista suurin osa on täysin turhia push- ja pop-rivejä ja hyppykäskyjä.

Käytössä siis Fortran kääntäjän kylkiäisenä tullut vanha C++ kääntäjä. Kääntäjä on niin vanha, että ei esimerkiksi tue nimiavaruuksia ollenkaan.

Omaan käyttööni tuo kyseinen kääntäjä tosin riittää mainiosti. Käännösaikaiset virheet C-koodissa tuo löytää kiitettävästi ja tukee myös ajonaikaista tarkistusta.

Esimerkiksi ketjun aloittajan listaus ei kääntyisi ollenkaan ja antaisi käännettäessä:

Compiling file: main.cpp
C:\TEMP\MAIN.CPP(17) : error 140 - Function 'suurin' requires no arguments
C:\TEMP\MAIN.CPP(18) : error 140 - Function 'pienin' requires no arguments
C:\TEMP\MAIN.CPP(22) : comment 528 - Argument 'luku1' conceals a global declaration of the same symbol
C:\TEMP\MAIN.CPP(22) : comment 528 - Argument 'luku2' conceals a global declaration of the same symbol
C:\TEMP\MAIN.CPP(22) : comment 528 - Argument 'luku3' conceals a global declaration of the same symbol
C:\TEMP\MAIN.CPP(34) : error 441 - Function 'suurin' should return a value, yet does not contain a 'return' statement
C:\TEMP\MAIN.CPP(36) : comment 528 - Argument 'luku1' conceals a global declaration of the same symbol
C:\TEMP\MAIN.CPP(36) : comment 528 - Argument 'luku2' conceals a global declaration of the same symbol
C:\TEMP\MAIN.CPP(36) : comment 528 - Argument 'luku3' conceals a global declaration of the same symbol
*** Compilation failed
Compilation failed.

Metabolix [10.10.2012 23:17:42]

#

jalski kirjoitti:

Esimerkiksi ketjun aloittajan listaus ei kääntyisi [vanhalla C++-kääntäjällä] ollenkaan

Ei tuo käänny millään nykyaikaisellakaan C++-kääntäjällä, koska koodi ei yksinkertaisesti ole kelvollista C++-koodia vaan huonosti kirjoitettua C:tä. Itse asiassa vanhalla kääntäjällä voisi olla paremmat mahdollisuudet onnistua vahingossa kääntämään tuo.

Shooter99 [11.10.2012 10:59:13]

#

Ensinnäkin olen pahoillani ylläpitäjälle tuottamasta lisätyöstä koska en käyttänyt lainaa tagia.

Nyt se mikä itseäni alkaa huolestuttaa on että olenko missään vaiheessa osannut koodata mitään tehtäviä oikein koska koulun c kääntäjä ajaa ohjelman läpi ja ainut virhe on ollut se että palautti pienimpänä numerona 0:n

Eli jos vanhat tehtävät on mennyt läpi ja kone on ne hyväksynyt niin miten ihmeessä tiedän olenko oikeasti koodannut mitään oikein, ja kun olen kuvitellut koodaavani ko. asiat oikein ja ottanut oppia niistä niin olen vain oppinut koko ajan koodaamaan enemmän väärin...

User137 [11.10.2012 15:25:42]

#

Kuten sanoin aiemmin, niin voit tehdä ohjelmaan jonkun pienen näkyvän muutoksen jotta tiedät onko ajettu ohjelma viimeisimmästä koodista. Muutat vaikka kyselyä:
"Anna luku: " -> "Anna joku luku: ".

Kai sieltä jotain asetuksia voi muuttaa ohjelmointiympäristöön liittyen?

The Alchemist [11.10.2012 15:33:36]

#

Shooter99 kirjoitti:

Eli jos vanhat tehtävät on mennyt läpi ja kone on ne hyväksynyt niin miten ihmeessä tiedän olenko oikeasti koodannut mitään oikein, ja kun olen kuvitellut koodaavani ko. asiat oikein ja ottanut oppia niistä niin olen vain oppinut koko ajan koodaamaan enemmän väärin...

Asennat koneellesi C/C++-ympäristön ja testailet koodejasi sillä. Moodle on vain tarkistustyökalu toimiville vastauksille, sitä ei ole tarkoituskaan käyttää eri tapojen kokeilemiseen.

JaskaP [11.10.2012 15:35:49]

#

Kyllähän tuo eka koodi C-kääntäjällä menee läpi (varoituksin), mutta ei mene C++-kääntäjästä.

Hyvä tapa on että varoitukset päälle ja koodia korjataan kunnes varoituksia ei enää tule. Tosin silloinkin pitää tajuta tai ottaa selvää missä on vika, eikä räpeltää mitä sattuu.

Eka koodi antaa seuraavat varoitukset. Eikä pitäisi olla kauhean vaikeaa korjata:

gcc test1.c -o test1 -Wall
test1.c: Funktio ”suurin”:
test1.c:23:6: varoitus: variable ”_suurin” set but not used [-Wunused-but-set-variable]
test1.c: Funktio ”pienin”:
test1.c:37:6: varoitus: variable ”_pienin” set but not used [-Wunused-but-set-variable]
test1.c: Funktio ”suurin”:
test1.c:34:2: varoitus: ei-void-tyyppisen funktion loppu saavutettu [-Wreturn-type]
test1.c: Funktio ”main”:
test1.c:20:1: varoitus: ei-void-tyyppisen funktion loppu saavutettu [-Wreturn-type]

eq [12.10.2012 04:31:46]

#

JaskaP kirjoitti:

Kyllähän tuo eka koodi C-kääntäjällä menee läpi (varoituksin), mutta ei mene C++-kääntäjästä.

Hyvä tapa on että varoitukset päälle ja koodia korjataan kunnes varoituksia ei enää tule. Tosin silloinkin pitää tajuta tai ottaa selvää missä on vika, eikä räpeltää mitä sattuu.

Eka koodi antaa seuraavat varoitukset. Eikä pitäisi olla kauhean vaikeaa korjata:

test1.c: Funktio ”suurin”:
test1.c:34:2: varoitus: ei-void-tyyppisen funktion loppu saavutettu [-Wreturn-type]
test1.c: Funktio ”main”:
test1.c:20:1: varoitus: ei-void-tyyppisen funktion loppu saavutettu [-Wreturn-type]

Nämä varoitukset (ja läpimeno) olivat siis ns. "GNU C:llä" ja mitä tapahtui oli, että koodi menee tietystä C-kääntäjästä läpi. Sitä paitsi, esimerkiksi nykyisellä C:n määritelmällä lista olisi erilainen (jos oletetaan, että kääntäjä ei pukahtaisi muutoin kuin silloin kun standardi niin velvoittaa).

Onkohan kääntäjän pakko edes tehdä toimivaa binääriä, tai binääriä ollenkaan, kun joka tapauksessa sen ajonaikainen toiminta on määrittelemätön ("undefined")?

celeron55 [12.10.2012 12:49:28]

#

eq kirjoitti:

Onkohan kääntäjän pakko edes tehdä toimivaa binääriä, tai binääriä ollenkaan, kun joka tapauksessa sen ajonaikainen toiminta on määrittelemätön ("undefined")?

Clangissa on -fcatch-undefined-behavior jolla käännettynä tuo ohjelma tappaa itsensä ajon aikana ko. ongelman huomatessaan... ilmeisesti. Mutta mikään ei taida oletuksena tuollaista generoida.

Shooter99 [13.10.2012 06:22:54]

#

Moi!

on ollut vähän kiiru viikko niin en ole päässyt käymään täällä...

No tämän koulun c kääntäjän asetuksiin emme pääse vaikuttamaan mitenkään!

Ja nyt koneellani on tollanen 79 eri c/cpp ohjelmistoa millä vääntää ja kääntää...

Ehkä vielä 10 vuoden päästä osaan oikeasti tuottaa ohjelman mikä printtaa ulos
että HELLO WORLD!

No joo, löysin netistä tuollaisen 150 sivun c kielen oppaan mitä tässä alan kahlaamaan läpi seuraavaksi.


Sivun alkuun

Vastaus

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

Tietoa sivustosta