Kirjautuminen

Haku

Tehtävät

Oppaat: C++-ohjelmointi: Osa 1 - Johdanto

  1. Osa 1 - Johdanto
  2. Osa 2 - Vakiot, muuttujat ja perustietotyypit
  3. Osa 3 - Ehdot, silmukat ja poikkeukset
  4. Osa 4 - Rakenteet, taulukot ja merkkijonot
  5. Osa 5 - Funktiot
  6. Osa 6 - Esittelyt, määrittelyt ja elinajat
  7. Osa 7 - Viittaukset, osoittimet ja dynaaminen muisti
  8. Osa 8 - Mallit
  9. Osa 9 - Luokkien perusteet
  10. Osa 10 - Luokkien erikoiset jäsenet
  11. Osa 11 - Luokkien perintä
  12. Liite 1 - C++-kehitysympäristöt
  13. Liite 2 - Valmis C++-kääntäjäpaketti

Kirjoittaja: Metabolix (2009).

C++ on perinteikäs ohjelmointikieli, jota voi käyttää monilla alustoilla ja lukuisissa käyttöjärjestelmissä. Se on monipuolinen kieli, joka sopii toisaalta matalan tason ohjelmointiin kuten käyttöjärjestelmien ja laiteajurien kirjoittamiseen ja toisaalta käytännöllisten sovellusten kuten toimisto-ohjelmien ja pelien tekemiseen.

C++:lla on maine tehokkaana kielenä. On totta, että C++:lla voi päästä erittäin hyviin tuloksiin, ja suuren käyttäjäkunnan ansiosta sille on myös monta tehokasta lisäkirjastoa. Jokainen ohjelma on silti vain juuri niin tehokas, kuin ohjelmoija siitä osaa tehdä, joten taitava Basicin käyttäjä voittaa kehnon C++-koodarin vaikka yhdellä kädellä.

C++ ei ole missään tapauksessa aina paras kieli. Sillä voi tehdä melkein mitä vain, ja tässä piileekin yksi kielen heikkouksista: C++:lla on hyvin helppo tehdä myös virheitä ja huonoja ratkaisuja. Kannattaakin harkita tarkkaan, olisiko omaan käyttötarkoitukseen tarjolla jokin helpompi kieli. Esimerkiksi nettisivuja ohjelmoidaan usein PHP:llä, Rubylla ja JavaScriptilla, Windows-ohjelmia tehdään paljon C#:lla, Linuxin pienissä komentoriviohjelmissa Perl ja Python ovat melko yleisiä valintoja, ja nämä kaikki ovat helpompia kuin C++.

Silti C++ ei ole turha. Sillä voi tehdä pienempiä, nopeampia tai muuten parempia ohjelmia kuin muilla kielillä, jos osaa. Sillä on jo tehty paljon ohjelmia, joita pitää edelleen kehittää ja korjailla. Sillä on tehty paljon esimerkkejä, joista voi oppia. On siis vielä monta syytä opetella C++:aa.

Opassarjasta

Tässä opassarjassa aloitetaan C++:n opettelu aivan alkeista: ensimmäinen ohjelma näyttää ruudulla yhden tekstirivin. Muutamassa ensimmäisessä osassa perehdytään kielen perusteisiin kuten muuttujiin, ehtolauseisiin ja funktioihin, ja näiden jälkeen siirrytään luokkiin ja oliopohjaiseen ohjelmointiin, tosin opassarja on näiltä osin vielä kesken. Opassarjan aikana käydään läpi pääasiassa C++:n ominaisuuksia ohjelmointikielenä, ja tavoitteena on, että oppaan tarjoamat tiedot riittävät suurenkin projektin tekemiseen – mutta sellaiseen tarvitaan yleensä paljon muutakin kuin vain C++:n syntaksia.

Opassarja käsittelee C++:aa pääosin sellaisena, kuin se on vuonna 1998 standardoitu; tämä standardi on yhä laajalti käytössä, ja tämän tuntemalla pääsee jo varsin pitkälle.

C ja C++

1970-luvun alkupuolella kehitettiin uusi, tehokas ohjelmointikieli C. Sillä kirjoitettiin valtaosa Unix-käyttöjärjestelmästä ja sittemmin myös Linuxista, Windowsista ja lukuisista muista, ja siitä tuli eräänlainen standardikieli, jota voi käyttää lähes missä tahansa ympäristössä. Nykyäänkin C:n merkittävimmät käyttöalueet ovat käyttöjärjestelmien ja sulautettujen järjestelmien kuten kodinkoneiden ohjelmointi.

C on rakenteiltaan melko yksinkertainen, jopa alkeellinen kieli. Tämä varmasti helpottaa sen käyttöä eri ympäristöissä, mutta valitettavasti C:stä samalla puuttuu monia ominaisuuksia, jotka auttavat suurten ohjelmien tekemistä. Yksi tällainen ominaisuus ovat luokat. C++ sai alkunsa vuonna 1979 nimellä C with Classes eli C-kieli luokilla, mutta vuonna 1983 nimeksi vaihdettiin C++, joka tarkoittaa C-kielessä muuttujan C arvon kasvattamista yhdellä. C++:n ensimmäinen ISO-standardi julkaistiin vuonna 1998 ja toinen vuonna 2011.

C++ muistuttaa ulkoisesti hyvin paljon C:tä, ja jotkut näkevätkin sen vain laajennettuna C-kielenä, johon on lisätty luokat ja merkillinen standardikirjasto. Nämä ja lukuisat muut C++:n lisäykset ovat kuitenkin hyvin olennaisia ja tekevät itse kielestä monin verroin mutkikkaamman. Perusteet ovat silti aivan samat kuin C:ssä, ja valtaosa C-ohjelmista kääntyykin myös C++-kääntäjällä hyvin pienin muutoksin. Toisaalta C++:n uudet ominaisuudet kannustavat monin paikoin hyvinkin erilaiseen ohjelmointitapaan kuin C:ssä.

Usein näkee käytettävän lyhennettä C/C++. Tämä on epämääräinen ilmaus, jonka käyttäjäkään tuskin aina tietää, mitä oikeastaan sillä tarkoittaa. Usein sillä viitataan sekä C:hen että C++:aan, mutta joskus tarkoitetaan ilmeisesti vain C++:aa muttei aivan tiedetä, onko se vain C:n alalaji vai oma kielensä. Toisinaan haukutaan, että "C/C++:lla" ohjelmoivat ihmiset kirjoittavat huonolaatuista koodia, joka ei noudata C++-tyylistä ohjelmointitapaa eikä edes varsinaisesti käytä mitään C++:n uusista ominaisuuksista mutta kuitenkin tekee jotain niin, ettei sitä voi kääntää C-kääntäjällä.

Kääntäjät ja kehitysympäristöt

C++-ohjelmoinnin kannalta kaikkein olennaisin asia on kääntäjä ja sen kanssa toimivat esikääntäjä ja linkkeri. Koodin kirjoittamiseen kannattaa lisäksi hankkia hyvä editori, joka osaa värittää varatut sanat ja muut tärkeät kohdat koodista ja auttaa koodin sisentämisessä. Joskus nämä toimitetaan samassa paketissa, joskus ne täytyy asentaa erikseen. Editoria, jossa voi helposti hallita myös käännösprosessia, kutsutaan IDEksi (Integrated Development Environment). Usein IDE sisältää myös monia muita kehityksen kannalta käytännöllisiä ominaisuuksia. Omien tottumusten mukainen kehitysympäristö nopeuttaa ohjelmointia.

Joitakin vaihtoehtoja käsitellään erillisessä liitteessä.

Esimerkkiohjelma

Yksinkertainen C++-ohjelma voisi näyttää kokonaisuudessaan vaikkapa tältä:

#include <iostream>

int main() {
	std::cout << "C++-ohjelmointi on kivaa!" << std::endl;
}

Tässä on sama ohjelma höystettynä kommenteilla, joissa kerrotaan, mitä mikin rivi tekee:

// Rivit //-merkinnästä eteenpäin ovat kommentteja, eli //:n jälkeen
// saa kirjoittaa, mitä haluaa, eikä tämä vaikuta ohjelmaan mitenkään.

// Lisäksi merkintä /* aloittaa kommentin ja */ lopettaa sen.
/* Tällainen kommentti voi olla monen rivin mittainen.
 * C-kielessä tämä oli pitkään ainoa tapa merkitä kommentti. */

// Liitetään ohjelmaan standardikirjaston otsikkotiedosto nimeltä iostream.
// Tätä otsikkotiedostoa tarvitaan tekstin tulostamiseen.
// Standardiotsikoiden nimet kirjoitetaan merkkien < ja > väliin.
#include <iostream>

// Määritellään pääohjelma. Se on funktio nimeltä main.
// Funktion ohjelmakoodi kirjoitetaan aaltosulkujen eli merkkien { ja } väliin.
int main() {
	// Tulostetaan hieman tekstiä ruudulle.
	// Tulostettava teksti syötetään std::cout-oliolle <<-operaattorilla.
	// std::endl tarkoittaa rivinvaihtoa ("enteriä").
	std::cout << "C++-ohjelmointi on kivaa!" << std::endl;
}

Koodista tässä muodossa ei kuitenkaan ole vielä käytännön iloa, vaan se pitää vielä esikääntää, kääntää ja linkittää, jotta siitä saataisiin käyttöjärjestelmän ymmärtämä ohjelma. Kun sopiva kääntäjä tai kehitysympäristö on asennettu käyttökuntoon, äskeinen esimerkkiohjelma voidaan kääntää ja ajaa. Lopputuloksen pitäisi näyttää tältä:

C++-ohjelmointi on kivaa!

Koodin kääntäminen GCC:llä eli g++:lla

Komentorivillä ohjelman voi kääntää g++:n kanssa yksinkertaisesti seuraavalla komennolla:
g++ koodi.cpp -o ohjelma.exe
Komennon alussa on käytettävä ohjelma, C++-kääntäjä g++. Tätä seuraava koodi.cpp on käännettävän kooditiedoston nimi. Kooditiedostoja voi kääntää kerralla useammankin antamalla samassa komennossa niiden kaikkien nimet. Ohjelmatiedoston nimi asetetaan merkinnällä -o ohjelma.exe.

Hieman lisää GCC:stä kerrotaan kehitysympäristöjen yhteydessä.

Koodista ohjelmaksi

Kun esimerkkiohjelma "käännetään", tapahtuu itse asiassa kolme eri prosessia: esikäännös, käännös ja linkitys.

Esikääntäjä (engl. precompiler) poistaa ensin koodista kaikki kommentit ja käsittelee #-merkillä alkavat koodirivit. Esimerkiksi #include-komento korvautuu kulmasuluissa tai lainausmerkeissä annetun tiedoston sisällöllä. Myös liitettävän sisältö käsitellään esikääntäjällä, eli se voi sisällyttää taas lisää tiedostoja. C:n ja C++:n esikääntäjän komennoista kerrotaan erillisessä oppaassa.

Kääntäjä (engl. compiler) kääntää varsinaisen C++-koodin konekielelle. Lopputuloksena on binaarimuotoinen objektitiedosto (engl. object file), jonka sisältö vastaa pääosin kirjoitettua koodia tietokoneelle sopivassa muodossa. Lopuksi linkkeri (engl. linker) yhdistää kääntäjän luomat objektitiedostot ja valmiit kirjastot (engl. library) yhteen toimivaksi ohjelmaksi.

Jos ohjelma vain välähtää

Tämä ja monet muut opassarjan esimerkkiohjelmat eivät keskustele käyttäjän kanssa siitä, milloin ohjelman pitää loppua, vaan ne loppuvat saman tien, kun ovat suorittaneet tehtävänsä. Äskeinen ohjelmakin sulkeutuu heti, kun on saanut tekstin tulostettua ruudulle. Jotkin kehitysympäristöt jättävät ohjelman tulosteen näkyville, mutta jos tämän oppaan esimerkkiohjelma "vain välähtää", paras ratkaisu on ajaa se komentoriviltä. Windowsissa komentoriville pääsee luomalla pikakuvakkeen ohjelmaan cmd (tai command, jos tämä ei toimi), oikeaan hakemistoon siirrytään komennolla cd "C:\oikea\hakemisto", ja ohjelma ajetaan kirjoittamalla ohjelmatiedoston nimi, vaikkapa ohjelma tai ohjelma.exe. Komentorivi suljetaan komennolla exit. Lisätietoa komentorivistä on aiheeseen omistautuneella sivustolla.

Toinen vaihtoehto on lisätä ohjelman loppuun koodia, joka estää ohjelmaa sulkeutumasta ilman lupaa. Seuraavan ohjelman saa suljettua Windowsissa painamalla näppäinyhdistelmän Control-Z ja enterin, Linuxissa ja Mac OS X:ssä taas toimii Control-D. Useimmissa järjestelmissä toimii lisäksi Control-C, joka sulkee ohjelman väkisin kesken kaiken – tämä ehkä kannattaa pitää mielessä, jos jokin oma kokeilu jääkin jumiin!

#include <iostream>

int main() {
	std::cout << "C++-ohjelmointi on kivaa!" << std::endl;

	std::cout << "Syötä Control-D, Control-Z tai Control-C" << std::endl;
	std::cin.clear();
	while (std::cin.good()) {
		std::cin.get();
	}
}

Loppuhuomau(tu)ksia


Kommentit

anton1234 [16.05.2010 20:11:56]

#

Miksi jokaisen cout:in eteen pitää laittaa tuo std::? Ei tarvitse laittaa jokaisen cout:in eteen std::tä, kun kirjoittaa int main():in alle using namespace std.

Esim. Hello world

#include <iostream>
int main()
{
using namespace std; // <--

cout << "hello world" << endl;

cin.get();
}

Metabolix [16.05.2010 20:40:18]

#

anton1234: Nimiavaruuksista ja niiden käytöstä kerrotaan opassarjan kuudennessa osassa. Joskus taitavampana ohjelmoijana ehkä ymmärrät myös, että lyhyempi koodi ei suinkaan ole aina parempi tai selkeämpi.

Santeri P. [20.01.2011 19:44:50]

#

Mahtavaa! Hyvin selkeästi kirjoitettu opas.
Opetan tämän oppaan avulla kavereitani ohjelmoimaan,mutta joitain asioita muunnan hieman selkeämmiksi.

pekde [05.04.2011 23:43:44]

#

Hei, olen vähän anton1234 linjoilla, että miksi näissä ohjeissa ei vaan suoraan käytetä using namespace std?

Ohjelmointikirjoissakin kuitenkin käytetään sitä. Ja kun ei tässä vaiheessa kai oleteta, että monikaan näitä oppaita lukijoista tulee huippuohjelmoiksi, vaikka jokainen taitavammaksi pyrkiikin.

Minusta selkeyden vuoksi on paljon mukavampi lukea koodia, jossa ei couttin ym. edessä ole mitään ylimääräistä toskaa, kun kerran tuolla alkumäärittelyllä voi sen välttää (ja on hyvän ohjelmointitavan mukaista). Ja onhan sitä mukavampi kirjoittaakin, kun säästää paljon naputtelua. Muuten tällaiselle aloittelijalle oikein hyvää juttua. Paljon selkeämmin ja olennaisemmin selvitetty asioita, kuin useimmilla englanninkielisillä sivuilla.

Le-Co-Las [16.09.2011 14:04:35]

#

Minusta on hyvä että alku harjoituksissa/esimerkeissä ei ole linkattu koko kirjastoa mukaan. Myöhemmässä vaiheessa ymmärtää sitten asian pointin ja näin se jää varmasti paremmin mieleen.
Opas etenee selkeästi ja on jaettu hyvin eri aihepiireihi/osiin.

Kiitos, Metabolix

Metabolix [16.09.2011 14:22:26]

#

pekde kirjoitti:

Ohjelmointikirjoissakin kuitenkin käytetään sitä. – – (ja on hyvän ohjelmointitavan mukaista)

(Nämä kohdat ilmeisesti liittyivät yhteen?) Kirjat eivät todista mitään. Varsinkin suomalaisissa ja aloittelijoille suunnatuissa kirjoissa on kasoittain virheitä ja huonoja tapoja, ja tuskinpa ne englanninkielisetkään aina ovat oikeassa. Ja vaikka yksi tapa olisi oikea, toinen voi silti olla ihan yhtä oikea.

pekde kirjoitti:

Minusta selkeyden vuoksi on paljon mukavampi lukea koodia, jossa ei couttin ym. edessä ole mitään ylimääräistä toskaa, kun kerran tuolla alkumäärittelyllä voi sen välttää

Se olkoon sitten sinun mielipiteesi. Minusta taas on paljon mukavampi lukea koodia, jossa ei tarvitse arvailla, onko esimerkiksi ws tai vector juuri tässä kohti standardikirjaston luokka vai jokin koodarin oma keksintö – molemmat kun ovat aivan yleisiä nimiä ja minullakin muuttujilla (joskus luokillakin) käytössä.

pekde kirjoitti:

Ja onhan sitä mukavampi kirjoittaakin, kun säästää paljon naputtelua.

Harvoinpa fyysinen kirjoitusnopeus on ohjelmoinnissa rajoittava tekijä, tai jos on, asia ei ole noista parista merkistä kiinni.

Helwet [24.09.2012 15:42:22]

#

Pakko sanoa etta putkan oppaat ovat parempia kuin luennot tai kirjat :)

OliO [24.10.2012 14:46:00]

#

Harvinaisen hyvä opassarja.

Mayson [29.01.2014 08:58:46]

#

Tähän saakka mitä itse olen lueskellut voin todeta että kaikki kirjat on potaskaa tähän verraten, niin paljon vanhentunutta tietoo useimmiten kirjoissa eikä niistä voi soveltaa samaan tyyliin, siispä ohjelmointiputka kunniaan! :D

Matias [08.07.2014 12:52:37]

#

Hyvä opas!

epe07 [09.04.2016 12:22:02]

#

C++ syntaxi on...

AlleViivattu [18.08.2016 18:34:24]

#

Eikö kohdassa "Jos ohjelma vain välähtää" voisi laittaa esimerkiksi näin:

#include <iostream>
#include <conio.h> //(en ole varma tarviiko laittaa conio.h)

int main() {
	std::cout << "C++-ohjelmointi on kivaa!" << std::endl;
    getch();
}

Metabolix [20.08.2016 08:44:13]

#

AlleViivattu kirjoitti:

Eikö kohdassa "Jos ohjelma vain välähtää" voisi laittaa esimerkiksi näin: – – conio.h – – getch

Ei voi, koska conio.h ja getch eivät kuulu standardiin ja niitä ei ole useimmissa järjestelmissä.

Tietenkin ohjelman voi tehdä monella muulla tavalla: voi vaikka tehdä ohjelmaan valikon tai silmukan, jossa kysytään käyttäjältä, vieläkö jatketaan.

mlwr [06.01.2018 17:12:18]

#

Voiko return 0;:a käyttää std::endl;n sijan?

int main() {

    std::cout << "c++ohjelmointi on kivaa!\n";

    return 0;
}

Metabolix [07.01.2018 22:14:39]

#

mlwr kirjoitti:

Voiko return 0;:a käyttää std::endl;n sijan?

Ei voi, niillä ei ole mitään tekemistä keskenään. Koodissasi std::endl on korvattu merkinnällä \n, joka tarkoittaa tekstissä rivinvaihtoa. Sen sijaan return-lause lopettaa funktion (tässä tapauksessa koko ohjelman) eikä ole main-funktion lopussa lainkaan tarpeen.

Puukyy [26.02.2020 17:40:43]

#

Selkeä ja hyvin jäsennelty opas, jota myös aloittelijan on kohtuullisen helppo seurata. Kiitokset Metabolixille vaivannäöstä!

tositoo [10.05.2020 10:34:34]

#

Tämä opas on selkeä ja helppo ymmärtää. Kiitos Metabolix!

tositoo [01.01.2021 12:19:00]

#

Voisiko lisätä tiedostosta lukemisen ja tiedostoon kirjoittamisen? Tai onko siitä koodivinkki?

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta