C++-ohjelmoinnin aloittaminen
Perustietotyyppien ominaisuuksista
Seuraavat kaksi ohjelmaa vaikuttavat ensi silmäyksellä identtisiltä:
Python
def main(): luku = int(input("Syötä luku: ")) if luku < 0: print("Oltava ei-negatiivinen!") else: tulos = 1 while luku > 0: tulos = tulos * luku luku -= 1 print("Kertoma on:", tulos) main()
C++
#include <iostream> using namespace std; int main() { cout << "Syota luku: "; int luku = 0; cin >> luku; if (luku < 0) { cout << "Oltava ei-negatiivinen!" << endl; } else { int tulos = 1; while (luku > 0) { tulos = tulos * luku; --luku; } cout << "Kertoma on: " << tulos << endl; } }
Jos ohjelmat suoritetaan alkuarvolla 17, Python tulostaa 355687428096000 ja kurssin työympäristössä C++-ohjelma voi tulostaa -288522240. C++:n laskema tulos on väärä, sillä ei-negatiivisten lukujen kertoma ei voi olla negatiivinen. Ongelma johtuu kokonaislukujen ylivuodosta.
Kokonaislukujen ylivuoto
Python on jossain määrin harvinainen ohjelmointikieli, koska sen kokonaislukujen arvoa rajoittaa lähinnä käytettävissä oleva muisti. Useimmissa ohjelmointikielissä kokonaisluvut esitetään konekielitasolla kiinteällä määrällä bittejä. Bittimäärä riippuu tavallisesti käytetystä tietokoneesta ja ohjelmointiympäristöstä. Kokonaislukutyypeissä käytetään usein 32 bittiä, mutta myös 16 tai 64 bittiä on mahdollisia.
32-bittisellä etumerkillisellä kokonaisluvulla voidaan esittää arvot väliltä -2147483648–2147483647, yhteensä 232 eri arvoa. Ylivuoto tapahtuu, kun laskutoimituksen tulos ylittää tyypin esitysalueen. Tällöin tulos ei vastaa matemaattista tulosta.
Ylivuotoa voi verrata siihen, kun auton matkamittari saavuttaa suurimman esitettävän lukeman ja “pyörähtää ympäri” takaisin alkuun.
C++:ssa etumerkillisen kokonaisluvun ylivuoto aiheuttaa määrittelemätöntä toimintaa. Joissakin ympäristöissä tulos voi kiertyä negatiiviseksi, mutta C++-kieli ei takaa tätä käyttäytymistä.
Alivuoto
Vastaava tilanne voi syntyä reaaliluvuilla laskettaessa. Reaaliluvut esitetään eri tavalla kuin kokonaisluvut, mutta niilläkin on rajallinen tarkkuus. Alivuoto tarkoittaa tilannetta, jossa reaaliluvun itseisarvo on niin pieni, ettei sitä pystytä erottamaan nollasta käytetyssä lukuesityksessä.
C++:n kokonaislukutyyppejä
C++ antaa ohjelmoijalle jonkin verran mahdollisuuksia valita, miten kokonaislukuja käsitellään. Tällä kurssilla käytetään erityisesti seuraavia tyyppejä:
int— tavallinen etumerkillinen kokonaislukutyyppi, joka sopii positiivisten ja negatiivisten arvojen käsittelyyn.unsigned int— etumerkitön kokonaislukutyyppi, jolla esitetään ei-negatiivisia arvoja.long int— kokonaislukutyyppi, jonka esitysalue voi ollaint-tyyppiä suurempi. Tämä riippuu käytetystä C++-toteutuksesta.unsigned long int— etumerkitön versiolong int-tyypistä.
C++-kieli ei määrää näille tyypeille yhtä kiinteää bittimäärää. Älä siis oleta, että int-tyyppiset kokonaisluvut esitetään aina 32 bitillä, vaikka näin on kurssin työympäristössä.