C++基本数据类型的字节数、范围大小、溢出处理

    C++有几种基本的数据类型:char、int、float、double,这些数据类型的字节数、范围大小根据操作系统、编译器的不同而不同。

图(1) C++基本数据类型的字节数

  • 在Windows上,同一种基本数据类型,其win32与win64的字节数是一致的;比如,int在win32、win64都是4个字节。
  • 在Linux上,大部分基本数据类型,其32位与64位的字节数是一致的;只有long类型的不相同(当然,long long除外,long long在32位、64位的Linux上,都是8字节)。比如,float在32位、64位的Linux上,都是4个字节;double在32位、64位的Linux上都是8个字节。

    当前,在Windows,有些复合数据类型,在不同位数上,其字节数是不同的。比如,string、size_t这类复合数据类型,string在win32上占28个字节,而在win64位上占40个字节。size_t在win32上占4个字节,而在win64位上占8个字节。

1、Windows系统

1.1 32位的编译器

32位 Windows上的数据类型与范围
type:           ************size**************
bool:           所占字节数:1   最大值:1               最小值:0
char:           所占字节数:1   最大值:127             最小值:-128
signed char:    所占字节数:1   最大值:127             最小值:-128
unsigned char:  所占字节数:1   最大值:255             最小值:0
wchar_t:        所占字节数:2   最大值:65535           最小值:0
short:          所占字节数:2   最大值:32767           最小值:-32768
int:            所占字节数:4   最大值:2147483647      最小值:-2147483648
unsigned:       所占字节数:4   最大值:4294967295      最小值:0
long:           所占字节数:4   最大值:2147483647      最小值:-2147483648
unsigned long:  所占字节数:4   最大值:4294967295      最小值:0
double:         所占字节数:8   最大值:1.79769e+308    最小值:2.22507e-308
long double:    所占字节数:8   最大值:1.79769e+308    最小值:2.22507e-308
float:          所占字节数:4   最大值:3.40282e+38     最小值:1.17549e-38
size_t:         所占字节数:4   最大值:4294967295      最小值:0
string:         所占字节数:28
type:           ************size**************

1.2 64位的编译器

64位 Windows上的数据类型与范围

type:           ************size**************
bool:           所占字节数:1   最大值:1                       最小值:0
char:           所占字节数:1   最大值:127                     最小值:-128
signed char:    所占字节数:1   最大值:127                     最小值:-128
unsigned char:  所占字节数:1   最大值:255                     最小值:0
wchar_t:        所占字节数:2   最大值:65535                   最小值:0
short:          所占字节数:2   最大值:32767                   最小值:-32768
int:            所占字节数:4   最大值:2147483647              最小值:-2147483648
unsigned:       所占字节数:4   最大值:4294967295              最小值:0
long:           所占字节数:4   最大值:2147483647              最小值:-2147483648
unsigned long:  所占字节数:4   最大值:4294967295              最小值:0
double:         所占字节数:8   最大值:1.79769e+308            最小值:2.22507e-308
long double:    所占字节数:8   最大值:1.79769e+308            最小值:2.22507e-308
float:          所占字节数:4   最大值:3.40282e+38             最小值:1.17549e-38
size_t:         所占字节数:8   最大值:18446744073709551615    最小值:0
string:         所占字节数:40
type:           ************size**************

    在Windows里,获取数据类型的字节数、范围大小的案例程序,如下:
    //getSize.cpp

#include<iostream>  
#include <limits>

using namespace std;

int main()
{
    
    
    cout << "type: \t\t" << "************size**************" << endl;
    cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);
    cout << "\t最大值:" << (numeric_limits<bool>::max)();
    cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;
    cout << "char: \t\t" << "所占字节数:" << sizeof(char);
    cout << "\t最大值:" << (int)(numeric_limits<char>::max)();
    cout << "\t\t最小值:" << (int)(numeric_limits<char>::min)() << endl;
    cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);
    cout << "\t最大值:" << (int)(numeric_limits<signed char>::max)();
    cout << "\t\t最小值:" << (int)(numeric_limits<signed char>::min)() << endl;
    cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);
    cout << "\t最大值:" << (int)(numeric_limits<unsigned char>::max)();
    cout << "\t\t最小值:" << (int)(numeric_limits<unsigned char>::min)() << endl;
    cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);
    cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();
    cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;
    cout << "short: \t\t" << "所占字节数:" << sizeof(short);
    cout << "\t最大值:" << (numeric_limits<short>::max)();
    cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;
    cout << "int: \t\t" << "所占字节数:" << sizeof(int);
    cout << "\t最大值:" << (numeric_limits<int>::max)();
    cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;
    cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);
    cout << "\t最大值:" << (numeric_limits<unsigned>::max)();
    cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;
    cout << "long: \t\t" << "所占字节数:" << sizeof(long);
    cout << "\t最大值:" << (numeric_limits<long>::max)();
    cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;
    cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);
    cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();
    cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;
    cout << "double: \t" << "所占字节数:" << sizeof(double);
    cout << "\t最大值:" << (numeric_limits<double>::max)();
    cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;
    cout << "long double: \t" << "所占字节数:" << sizeof(long double);
    cout << "\t最大值:" << (numeric_limits<long double>::max)();
    cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;
    cout << "float: \t\t" << "所占字节数:" << sizeof(float);
    cout << "\t最大值:" << (numeric_limits<float>::max)();
    cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;
    cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);
    cout << "\t最大值:" << (numeric_limits<size_t>::max)();
    cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;
    cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;
    // << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl;  
    cout << "type: \t\t" << "************size**************" << endl;

    system("pause");
    return 0;
}

2、Linux系统

2.1 32位编译器

32位 Linux上的数据类型与范围
type:           ************size**************
bool:           所占字节数:1   最大值:1               最小值:0
char:           所占字节数:1   最大值:Del            最小值:€
signed char:    所占字节数:1   最大值:Del            最小值:€
unsigned char:  所占字节数:1   最大值:255             最小值:0
wchar_t:        所占字节数:2   最大值:65535           最小值:0
short:          所占字节数:2   最大值:32767           最小值:-32768
int:            所占字节数:4   最大值:2147483647      最小值:-2147483648
unsigned:       所占字节数:4   最大值:4294967295      最小值:0
long:           所占字节数:4   最大值:2147483647      最小值:-2147483648
unsigned long:  所占字节数:4   最大值:4294967295      最小值:0
double:         所占字节数:8   最大值:1.79769e+308    最小值:2.22507e-308
long double:    所占字节数:8   最大值:1.79769e+308    最小值:2.22507e-308
float:          所占字节数:4   最大值:3.40282e+38     最小值:1.17549e-38
size_t:         所占字节数:4   最大值:4294967295      最小值:0
string:         所占字节数:28

2.2 64位编译器

64位 Linux上的数据类型与范围

type:           ************size**************
bool:           所占字节数:1   最大值:1                     最小值:0
char:           所占字节数:1   最大值:DEL                  最小值:€
signed char:    所占字节数:1   最大值:DEL                  最小值:€
unsigned char:  所占字节数:1   最大值:255                   最小值:0
wchar_t:        所占字节数:2   最大值:65535                 最小值:0
short:          所占字节数:2   最大值:32767                 最小值:-32768
int:            所占字节数:4   最大值:2147483647            最小值:-2147483648
unsigned:       所占字节数:4   最大值:4294967295            最小值:0
long:           所占字节数:8   最大值:9223372036854775807   最小值:-9223372036854775807
unsigned long:  所占字节数:8   最大值:18446744073709551615  最小值:0
double:         所占字节数:8   最大值:1.79769e+308          最小值:2.22507e-308
long double:    所占字节数:8   最大值:1.79769e+308          最小值:2.22507e-308
float:          所占字节数:4   最大值:3.40282e+38           最小值:1.17549e-38
size_t:         所占字节数:8   最大值:18446744073709551615  最小值:0
string:         所占字节数:40
type:           ************size**************

3、越界与溢出

    当变量的取值超过其最大值时,如果再加1,则出现越界,变量会从最大值变为最小值,即 MAX+1 → MIN,这里以Windows 64位上的long、int的最大值越界为例,进行说明。
    long、int的最大值都为2147483647,若再加1,则出现越界,直接变成最小值 -2147483648,如图表(1)所示:

表(1) 数据的上溢、下溢
最大值 Max Max+1(上溢) 最小值 Min Min-1(下溢)
bool 1 1 0 1
char 127 -128 -128 127
signed char 127 -128 -128 127
unsigned char 255 0 0 255
wchar_t 65535 0 0 65535
short 32767 -32768 -32768 32767
int 2147483647 -2147483648 -2147483648 2147483647
unsigned 4294967295 0 0 4294967295
long 2147483647 -2147483648 -2147483648 2147483647
unsigned long 4294967295 0 0 4294967295

    注意,bool在C++中是使用unsigned int表示的,所以bool的最大值加1不会溢出(1+1 < 4294967295 ),要加上unsigned int的最大值4294967295才会上溢出变为0(1+ 4294967295溢出,变为0)。

    //LongMax.cpp

#include<iostream>  
#include <limits>

using namespace std;

#pragma warning(disable:4804) 
#pragma warning(disable:4146) 

void LongMax()
{
    
    
    cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);
    cout << "\t最大值:" << (numeric_limits<bool>::max)();
    cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;
    cout << "char: \t\t" << "所占字节数:" << sizeof(char);
    cout << "\t最大值:" << (int)(numeric_limits<char>::max)();
    cout << "\t\t最小值:" << (int)(numeric_limits<char>::min)() << endl;
    cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);
    cout << "\t最大值:" << (int)(numeric_limits<signed char>::max)();
    cout << "\t\t最小值:" << (int)(numeric_limits<signed char>::min)() << endl;
    cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);
    cout << "\t最大值:" << (int)(numeric_limits<unsigned char>::max)();
    cout << "\t\t最小值:" << (int)(numeric_limits<unsigned char>::min)() << endl;
    cout << "short: \t\t" << "所占字节数:" << sizeof(short);
    cout << "\t最大值:" << (numeric_limits<short>::max)();
    cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;
    cout << "int: \t\t" << "所占字节数:" << sizeof(int);
    cout << "\t最大值:" << (numeric_limits<int>::max)();
    cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;
    cout << "unsigned int:\t" << "所占字节数:" << sizeof(unsigned int);
    cout << "\t最大值:" << (numeric_limits<unsigned>::max)();
    cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;
    cout << "long: \t\t" << "所占字节数:" << sizeof(long);
    cout << "\t最大值:" << (numeric_limits<long>::max)();
    cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;
    cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);
    cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();
    cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;
    cout << "type: \t\t" << "************size**************" << endl<<endl;
}

//上溢出
void MaxAddOne()
{
    
    
    bool boolA = 1;
    cout << "before boolA= " << boolA << endl;
    boolA += 4294967295;
    cout << "after  boolA= " << boolA << endl << endl;

    char charB = 127;
    cout << "before charB= " << (int)charB << endl;
    charB += 1;
    cout << "after  charB= " << (int)charB << endl << endl;

    signed char sigCharC = 127;
    cout << "before  signed sigCharC= " << (int)sigCharC << endl;
    sigCharC += 1;
    cout << "after   signed sigCharC= " << (int)sigCharC << endl << endl;

    unsigned char unsigCharD = 255;
    cout << "before  unsigned unsigCharD= " << (int)unsigCharD << endl;
    unsigCharD += 1;
    cout << "after   unsigned unsigCharD= " << (int)unsigCharD << endl << endl;

    wchar_t wchar_tE = 65535;
    cout << "before  wchar_t wchar_tE= " << wchar_tE << endl;
    wchar_tE += 1;
    cout << "after   wchar_t wchar_tE= " << wchar_tE << endl << endl;

    int intF = 2147483647;
    cout << "before  int intF= " << intF << endl;
    intF += 1;
    cout << "after   int intF= " << intF << endl << endl;

    unsigned unsigIntG = 4294967295;
    cout << "before  unsigned unisigndG= " << unsigIntG << endl;
    unsigIntG += 1;
    cout << "after   unsigned unisigndG= " << unsigIntG << endl << endl;

    long longH = 2147483647;
    cout << "before  long longH= " << longH << endl;
    longH += 1;
    cout << "after   long longH= " << longH << endl << endl;

    unsigned long unsigLongI = 4294967295;
    cout << "before unsigned long unsigLongI= " << unsigLongI << endl;
    unsigLongI += 1;
    cout << "after  unsigned long unsigLongI= " << unsigLongI << endl << endl;
}

//下溢出  
void MinSubOne()
{
    
    
    bool boolA = 0;
    cout << "before boolA= " << boolA << endl;
    boolA -= 1;
    cout << "after  boolA= " << boolA << endl << endl;

    char charB =-128;
    cout << "before charB= " << (int)charB << endl;
    charB -= 1;
    cout << "after  charB= " << (int)charB << endl << endl;

    signed char sigCharC = -128;
    cout << "before  signed sigCharC= " << (int)sigCharC << endl;
    sigCharC -= 1;
    cout << "after   signed sigCharC= " << (int)sigCharC << endl << endl;

    unsigned char unsigCharD = 0;
    cout << "before  unsigned unsigCharD= " << (int)unsigCharD << endl;
    unsigCharD -= 1;
    cout << "after   unsigned unsigCharD= " << (int)unsigCharD << endl << endl;

    wchar_t wchar_tE = 0;
    cout << "before  wchar_t wchar_tE= " << wchar_tE << endl;
    wchar_tE -= 1;
    cout << "after   wchar_t wchar_tE= " << wchar_tE << endl << endl;

    int intF = -2147483648;
    cout << "before  int intF= " << intF << endl;
    intF -= 1;
    cout << "after   int intF= " << intF << endl << endl;

    unsigned unsigIntG = 0;
    cout << "before  unsigned unisigndG= " << unsigIntG << endl;
    unsigIntG -= 1;
    cout << "after   unsigned unisigndG= " << unsigIntG << endl << endl;

    long longH = -2147483648;
    cout << "before  long longH= " << longH << endl;
    longH -= 1;
    cout << "after   long longH= " << longH << endl << endl;

    unsigned long unsigLongI = 0;
    cout << "before unsigned long unsigLongI= " << unsigLongI << endl;
    unsigLongI -= 1;
    cout << "after  unsigned long unsigLongI= " << unsigLongI << endl << endl;
}

int main()
{
    
    
    //上溢出
    cout << "--------------------(1)上溢出--------------------" << endl;
    MaxAddOne();

    //下溢出
    cout << "--------------------(2)下溢出--------------------" << endl;
    MinSubOne();
            
    system("pause");
    return 0;
}

    效果如下:

图(1) 上溢获得最小值,下溢获得最大值

猜你喜欢

转载自blog.csdn.net/sanqima/article/details/124703724