C++ Basic 03--数据类型

目录

Table of Contents

目录

C++ 数据类型

基本的内置类型

typedef 声明

枚举类型

关于 typedef 的几点说明:

typedef 与 #define 的区别:


C++ 数据类型

使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。

您可能需要存储各种数据类型(比如字符型、宽字符型、整型、浮点型、双浮点型、布尔型等)的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么。


基本的内置类型

C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的 C++ 数据类型:

一些基本类型可以使用一个或多个类型修饰符进行修饰:

  • signed
  • unsigned
  • short
  • long

下表显示了各种变量类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值。

注意:不同系统会有所差异。

类型范围
char1 个字节-128 到 127 或者 0 到 255
unsigned char1 个字节0 到 255
signed char1 个字节-128 到 127
int4 个字节-2147483648 到 2147483647
unsigned int4 个字节0 到 4294967295
signed int4 个字节-2147483648 到 2147483647
short int2 个字节-32768 到 32767
unsigned short int2 个字节0 到 65,535
signed short int2 个字节-32768 到 32767
long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
signed long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int8 个字节0 to 18,446,744,073,709,551,615
float4 个字节+/- 3.4e +/- 38 (~7 个数字)
double8 个字节+/- 1.7e +/- 308 (~15 个数字)
long double16 个字节+/- 1.7e +/- 308 (~15 个数字)
wchar_t2 或 4 个字节1 个宽字符

从上表可得知,变量的大小会根据编译器和所使用的电脑而有所不同。

下面实例会输出您电脑上各种数据类型的大小。

#include<iostream>  
#include<string>  
#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最大值:" << (numeric_limits<char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;  
    cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);  
    cout << "\t最大值:" << (numeric_limits<signed char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;  
    cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);  
    cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();  
    cout << "\t\t最小值:" << (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;  
    return 0;  
}

运行结果:

type: 		************size**************
bool: 		所占字节数:1	最大值:1		最小值:0
char: 		所占字节数:1	最大值:		最小值:\200
signed char: 	所占字节数:1	最大值:		最小值:\200
unsigned char: 	所占字节数:1	最大值:\377		最小值:
wchar_t: 	所占字节数:4	最大值:2147483647		最小值:-2147483648
short: 		所占字节数:2	最大值:32767		最小值:-32768
int: 		所占字节数:4	最大值:2147483647	最小值:-2147483648
unsigned: 	所占字节数:4	最大值:4294967295	最小值:0
long: 		所占字节数:8	最大值:9223372036854775807	最小值:-9223372036854775808
unsigned long: 	所占字节数:8	最大值:18446744073709551615	最小值:0
double: 	所占字节数:8	最大值:1.79769e+308	最小值:2.22507e-308
long double: 	所占字节数:16	最大值:1.18973e+4932	最小值:3.3621e-4932
float: 		所占字节数:4	最大值:3.40282e+38	最小值:1.17549e-38
size_t: 	所占字节数:8	最大值:18446744073709551615	最小值:0
string: 	所占字节数:24
type: 		************size**************
Program ended with exit code: 0

typedef 声明

您可以使用 typedef 为一个已有的类型取一个新的名字。下面是使用 typedef 定义一个新类型的语法:

typedef type newname; 

例如,下面的语句会告诉编译器,feet 是 int 的另一个名称:

typedef int feet;

现在,下面的声明是完全合法的,它创建了一个整型变量 distance:

feet distance;

枚举类型

枚举类型(enumeration)是C++中的一种派生数据类型,它是由用户定义的若干枚举常量的集合。

如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型。所谓"枚举"是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。

创建枚举,需要使用关键字 enum。枚举类型的一般形式为:

enum 枚举名{ 
     标识符[=整型常数], 
     标识符[=整型常数], 
... 
    标识符[=整型常数]
} 枚举变量;
    

如果枚举没有初始化, 即省掉"=整型常数"时, 则从第一个标识符开始。

例如,下面的代码定义了一个颜色枚举,变量 c 的类型为 color。最后,c 被赋值为 "blue"。

enum color { red, green, blue } c;
c = blue;

默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推。但是,您也可以给名称赋予一个特殊的值,只需要添加一个初始值即可。例如,在下面的枚举中,green 的值为 5。

enum color { red, green=5, blue };

在这里,blue 的值为 6,因为默认情况下,每个名称都会比它前面一个名称大 1,但 red 的值依然为 0。

#include <iostream>
using namespace std;
enum time 
{ 
    first,second,
    third,forth,fifth
};

int main()
{
    enum time a=fifth;
    if (a==fifth) 
    {
        cout << "Succeed!";
    }
    return 0;
}

 

例:枚举和switch随便做一个判断名次的举例

#include<iostream>
using namespace std;

int  main()
{
    enum rank
    {
        first,second,third
    };

    int nRank=1;
    switch (nRank)
    {
        case first:
            cout << "第一名";
            break;
        case second:
            cout << "第二名";
            break;
        case third:
            cout << "第三名";
            break;
        default:
            break;
    }
    // system("pause");
    return 0;
}

运行结果为:第二名

当修改枚举类型整形常数后:

#include <iostream>
using namespace std;

int  main()
{
    enum rank
    {
        first=1,second=2,third=3
    };

    int nRank = 1;
    switch (nRank)
    {
        case first:
            cout << "第一名";
            break;
        case second:
            cout << "第二名";
            break;
        case third:
            cout << "第三名";
            break;
        default:
            break;
    }
    // system("pause");
    return 0;
}

运行结果为:第一名

默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推。


关于 typedef 的几点说明:

  1. typedef 可以声明各种类型名,但不能用来定义变量。用 typedef 可以声明数组类型、字符串类型,使用比较方便。
  2. 用typedef只是对已经存在的类型增加一个类型别名,而没有创造新的类型。
  3. 当在不同源文件中用到同一类型数据(尤其是像数组、指针、结构体、共用体等类型数据)时,常用 typedef 声明一些数据类型,把它们单独放在一个头文件中,然后在需要用到它们的文件中用 #include 命令把它们包含进来,以提高编程效率。
  4. 使用 typedef 有利于程序的通用与移植。有时程序会依赖于硬件特性,用 typedef 便于移植。

typedef 与 #define 的区别:

1. 执行时间不同

  • 关键字 typedef 编译阶段有效,由于是在编译阶段,因此 typedef 有类型检查的功能。
  • #define 则是宏定义,发生在预处理阶段,也就是编译之前有效,它只进行简单而机械的字符串替换,而不进行任何检查

【例1】typedef 会做相应的类型检查:

typedef unsigned int UINT;
 
void func()
{
    UINT value = "abc"; // error C2440: 'initializing' : cannot convert from 'const char [4]' to 'UINT'
    cout << value << endl;
}

【例2】#define不做类型检查:

// #define用法例子:
#define f(x) x*x
int main()
{
    int a=6, b=2, c;
    c=f(a) / f(b);
    printf("%d\n", c);
    return 0;
}

程序的输出结果是: 36,根本原因就在于 #define 只是简单的字符串替换。

2、功能有差异

typedef 用来定义类型的别名,定义与平台无关的数据类型,与 struct 的结合使用等。

#define 不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

3、作用域不同

#define 没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。

而 typedef 有自己的作用域。

【例3】没有作用域的限制,只要是之前预定义过就可以

void func1()
{
    #define HW "HelloWorld";
}
 
void func2()
{
    string str = HW;
    cout << str << endl;
}

例4】而typedef有自己的作用域

void func1()
{
    typedef unsigned int UINT;
}
 
void func2()
{
    UINT uValue = 5;//error C2065: 'UINT' : undeclared identifier
}

【例5】

class A
{
    typedef unsigned int UINT;
    UINT valueA;
    A() : valueA(0){}
};
 
class B
{
    UINT valueB;
    //error C2146: syntax error : missing ';' before identifier 'valueB'
    //error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
};

上面例子在B类中使用UINT会出错,因为UINT只在类A的作用域中。此外,在类中用typedef定义的类型别名还具有相应的访问权限,

【例6】:

class A
{
    typedef unsigned int UINT;
    UINT valueA;
    A() : valueA(0){}
};
 
void func3()
{
    A::UINT i = 1;
    // error C2248: 'A::UINT' : cannot access private typedef declared in class 'A'
}

 

而给UINT加上public访问权限后,则可编译通过。

【例7】:

class A
{
public:
    typedef unsigned int UINT;
    UINT valueA;
    A() : valueA(0){}
};
 
void func3()
{
    A::UINT i = 1;
    cout << i << endl;
}

4、对指针的操作

二者修饰指针类型时,作用不同。

typedef int * pint;
#define PINT int *
 
int i1 = 1, i2 = 2;
 
const pint p1 = &i1;    //p不可更改,p指向的内容可以更改,相当于 int * const p;
const PINT p2 = &i2;    //p可以更改,p指向的内容不能更改,相当于 const int *p;或 int const *p;
 
pint s1, s2;    //s1和s2都是int型指针
PINT s3, s4;    //相当于int * s3,s4;只有一个是指针。
 
void TestPointer()
{
    cout << "p1:" << p1 << "  *p1:" << *p1 << endl;
    //p1 = &i2; //error C3892: 'p1' : you cannot assign to a variable that is const
    *p1 = 5;
    cout << "p1:" << p1 << "  *p1:" << *p1 << endl;
 
    cout << "p2:" << p2 << "  *p2:" << *p2 << endl;
    //*p2 = 10; //error C3892: 'p2' : you cannot assign to a variable that is const
    p2 = &i1;
    cout << "p2:" << p2 << "  *p2:" << *p2 << endl;
}

结果:

p1:00EFD094  *p1:1
p1:00EFD094  *p1:5
p2:00EFD098  *p2:2
p2:00EFD094  *p2:5

 

还可以用 typedef 来定义与平台无关的类型。

比如定义一个叫 FALSE 的浮点类型,在目标平台一上,让它表示最高精度的类型为:

typedef long double FALSE; 

在不支持 long double 的平台二上,改为:

typedef double FALSE; 

在连 double 都不支持的平台三上,改为:

typedef float FALSE; 

也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。

标准库就广泛使用了这个技巧,比如 size_t。 另外,因为 typedef 是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Techblog of HaoWANG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值