Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C-kieli ja int-muuttujan ylivuoto

Ville [31.05.2009 12:03:09]

#

Kokeilin alla olevalla koodilla saada muuttuja vuotamaan yli.

Eikös ole niin että int tyypin arvoalue on -32768 - 32767.
Koodissa kun suoritan tuon yhteenlaskun niin eikös tuon summan arvon pitäisi mennä yli int alueen ja summaksi tulla jotain muuta kuin 32900 ?

#include<stdio.h>

int main()
{

    int summa = 0, arvo = 32700, luku = 200;
    summa = arvo + luku;
    printf("Summa on %d\n", summa);

    system("pause");
    return 0;

}

Metabolix [31.05.2009 12:10:10]

#

Nykyjärjestelmissä int on 32-bittinen, jolloin lukualue on -2147483648 – 2147483647. Voit todeta muuttujan koon tavuina itsekin (sizeof(muuttuja)), ja tavussa on kahdeksan bittiä, joten tästä selviää bittikoko ja samalla lukualue.

printf("sizeof(short) = %d\n", sizeof(short));
printf("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(long) = %d\n", sizeof(long));

16-bittisissä järjestelmissä short ja int ovat usein olleet 16-bittisiä ja long 32-bittinen. 32-bittisissä järjestelmissä short on 16-bittinen, int ja long 32-bittisiä ja long long 64-bittinen. Joissain 64-bittisissä järjestelmissä long on 64-bittinen, mutta muistaakseni MSVC kääntää sen yhä 32-bittisenä ja vasta long long on 64-bittinen.

Antti Laaksonen [31.05.2009 13:35:24]

#

Tällä koodilla voi tutkia int-muuttujan rajoja:

#include <stdio.h>
#include <limits.h>

int main(void) {
    printf("pienin int-muuttuja: %i\n", INT_MIN);
    printf("suurin int-muuttuja: %i\n", INT_MAX);
    return 0;
}

Schedler [31.05.2009 17:09:15]

#

Kannattaa myös tutustua C99:n määrittelyyn sisältyvään stdint.h -otsikkotiedostoon, jossa on määritetty erikokoiset kokonaislukumuuttujat: http://en.wikipedia.org/wiki/Stdint.h

Oletuksien tekeminen eri kokonaislukutyyppien leveydestä johtaa helposti koodin siirrettävyyden menetykseen, ja joissain tapauksissa vaikeasti löydettäviin ongelmiin.

eq [31.05.2009 18:21:28]

#

Metabolix kirjoitti:

Nykyjärjestelmissä int on 32-bittinen, jolloin lukualue on -2147483648 – 2147483647. Voit todeta muuttujan koon tavuina itsekin (sizeof(muuttuja)), ja tavussa on kahdeksan bittiä, joten tästä selviää bittikoko ja samalla lukualue.

printf("sizeof(short) = %d\n", sizeof(short));
printf("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(long) = %d\n", sizeof(long));

16-bittisissä järjestelmissä short ja int ovat usein olleet 16-bittisiä ja long 32-bittinen. 32-bittisissä järjestelmissä short on 16-bittinen, int ja long 32-bittisiä ja long long 64-bittinen. Joissain 64-bittisissä järjestelmissä long on 64-bittinen, mutta muistaakseni MSVC kääntää sen yhä 32-bittisenä ja vasta long long on 64-bittinen.

Näitä harvinaisemmista järjestelmistä puhuttaessa kannattaakin sitten jo ottaa huomioon, että tavussa on CHAR_BIT (>= 8) bittiä :). Yleisesti standardissa määritellään kaikkien muuttujatyyppien koille vain alaraja.

Metabolix [31.05.2009 19:07:08]

#

eq kirjoitti:

Näitä harvinaisemmista järjestelmistä ...

Toisaalta kun joku tulee kysymään asiaa kertomatta mitään koneestaan, voi nykymaailmassa olettaa, että käytössä on x86-prosessori ja DOS (16-bittinen) tai Windows, Linux tai Mac OS X (32- tai 64-bittinen) tai jossain harvinaisessa tapauksessa PowerPC ja Mac OS.

Vastaus

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

Tietoa sivustosta