Vastauksia palautteeseen¶
Tällä sivulla vastaamme C-kielen osuudesta luento- ja harjoituspalautteessa esitettyihin kysymyksiin ja kommentteihin luentokappaleittain.
Yleistä¶
Q: Tarkistinohjelma kaatuu koko ajan.
A: Tällaisesta tiedosta olemme varsin kiinnostuneita. Voitko tulla näyttämään harjoituksiin tai lähettää viestiä, miten tarkalleen kaatuminen tapahtuu? Mukaan mielellään vastauksesi URL.
Yksi hyvä tapa saada tarkistin kaatumaan on tulostaa printf:llä jotain funktiossasi, kun tehtävä ei sitä edellytä. Tämä on tarkistinbugi jota olemme korjaamassa.
Q: Laitoin tehtävävastauksen koodia palautteeseen, enkä ole kuullut siitä sittemmin. Missä vika?
A: Palaute näkyy meille anonyymisti, joten emme tiedä keneen olla yhteydessä. Ja emme julkaise vastauksia tehtäviin, ainakaan ennenkuin deadline on paukkunut.
Q: Sivuaineopiskelijana (tai vastaavana) suoritan yhtaikaa Ohjelmoinnin Alkeet-kurssia ja JTKJ-kurssia. Nyt minulla on vaikeuksia suoriutua JTKJ-tehtävistä, koska ne edellyttävät osaamista, jota OA-kurssilla ei ole vielä käsitelty.
A: OA-kurssi vaaditaan JTKJ:n esitietoina. Kursseja ei ole laadittu niin, että ne voisi suorittaa yhtaikaa eikä kurssimateriaalia ole mitenkään synkronoitu. Olkaa yhteydessä opinnoistanne vastaaviin henkilöihin ja pyytäkää heitä korjaamaan kurssien suoritusjärjestys.
3. Bitit ja lukujärjestelmät¶
Q: Hihat palaa lukujärjestelmämuunnoksia ja bittioperaatioita tehdessä... ja hei laskimet on keksitty!
A: Nämä asiat ovat tieto/sähköinsinöörin sen verran perusosaamista, että ne pitäisi kyllä mennä päässälaskuna..
Q: Miten voin esittäää binääriluvun C:llä? Netissä käytettiin etuliitettä 0b.
A: Etuliite 0b ei ole standardinmukaista C:tä, vaan kääntäjien lisäominaisuus. Kurssilla käytettävässä gcc:ssä se sattuu toimimaan.
Binääriluvut on kyllä helppo esittää heksalukuina, kts luentomateriaali.
Q: Heksadesimaalissa yleensä negatiivinen on miinus (-) merkki eikä 8(0b1000) -> ylöspäin olevat bitit.
A: Totta, heksadesimaalien kanssa voi käyttää myös miinusmerkkiä. Tietokone toki käsittelee myös nämä miinusmerkkiset heksaluvut 2-komplementtilukuina, eli kääntäjä tekee sisäisesti itse muunnoksen.
Huomataan, että sijoitus
int8_t neg = -0x81
(ikäänkuin "kaksi miinusmerkkiä") ei mahdu lukualueeseen, vaan tarvitsee 9. merkkibitin, jolloin 8. bitti luetaan lukuarvoon kuuluvaksi. Kurssilla haluamme käyttää 2-komplementtiesitystä. Esimerkiksi, oheislaitteen laiterekisteriä lukiessa ainoa tapa välittää sekä positiivisia ja negatiivisia lukuja on 2-komplementtiesitys.
5. Bittioperaatiot C-kielessä¶
Q: Jos hiuksia halotaan niin eikö lopussa olevasta operaatioiden suoritusjärjestys -taulukosta puutu vasemmalta oikealle suoritettavat viittauksen jälkeiset sijoitusoperaattorit ++ ja --? Taulukosta löytyvät käsittääkseni vain oikealta vasemmalle suoritettavat "sijoita ensin ja viittaa nyt" ++ ja -- operaattorit. Esimerkki:
uint8_t n = 4;
printf("%d\n", n++); // <- puuttuu, palauttaa 4
printf("%d\n", ++n); // palauttaa 6
printf("%d\n", --n); // palauttaa 5
// jostain syystä näissä silmukoissa toimii myös ++i ja --i täysin samoin kuin i++ ja i--?!?
for (uint8_t i; i < 10; i++) {}
for (uint8_t i; i < 10; ++i) {}
A: Hyvä kysymys, tähän liittyy useampikin asia.
1) Taulukossa on tarkoitus kuvata suoritusjärjestystä laskevasti riveittäin niin, että ylempänä on korkeampi suoritusjärjestys (ts. prioriteetti) ja riveillä se riippuu suoritussuunnasta.
Suoritussuunta tarkoittaa sitä, että jos meillä on saman prioriteetin operaattoreita useampi samassa lauseessa, niin miten päin niiden suoritusjärjestys tulkitaan, oikealta vasemmalle vai vasemmalta oikealle? Operaattorilla Q:
(a Q b) Q c
vai a Q (b Q c)
? Kurssilla sulkeita käyttämällä ei näistä tarvitse murehtia. 2) Lisäksi, näiden unaaristen operaattorien käytössä funktion parametreinä tulee olla varovainen, koska arvojen laskentajärjestys (sidontajärjestys) on kääntäjäriippuvainen. Asiaa on käsitelty oppikirjassa (Kernigham & Ritchie, kpl 2.12).
// Tässä ei tiedetä kumpi operaatio suoritetaan ensin, ++ tai pow()
printf("%d %d", ++n, pow(2,n));
// Oikea tapa tehdä tämä olisi
++n;
printf("%d %d", n, pow(2,n));
3) Vielä, for-lauseella on aina sama suoritusjärjestys niin, että sijoitusoperaatio tulee viimeisenä. Ei siis ole väliä miten ++-operaattori on käytössä, koska se suoritetaan aina iteraation lopussa.
7. Ohjausrakenteet C:ssä¶
Q: En saa tulostettua 64-bittisiä lukuja printf:llä. (Googlella löysin kummallisen %PRI64d-määrevakion, jolla homma onnistuu..)
A: Isojen lukujen tulostaminen saattaa (arkkitehtuurista riipuen) vaatia muotoilumääreen
%lld
(long long int) käyttöä, kun "pelkkä" %ld
ei riitä. Jossain kääntäjissä voi tarvita tässä %i64d
-muotoilumäärettä. Lopuksi¶
Kurssilla todellakin annetaan vain kalpea aavistus C-kielestä ja sen käytöstä. Ihan vaan sen verran, että opimme käyttämään sitä työkaluna sulautettujen järjestelmien ohjelmoinnissa.
Anna palautetta
Kommentteja materiaalista?