数据是信息的载体,有常量(constant)和变量(variable)之分。常量是不变的量,变量是可以改变或者可被赋值的量。编译器直接通过书写形式来识别常量,而识别变量时则需要先声明变量类型。
本文详细讲述C、C++、Java和Python中的基本数据类型。
C语言有多种数据类型,但总体可以分为两大类:整数类型和浮点类型,这也跟计算机存储数据的方式有关。整数是没有小数部分的数;浮点数是实数,是有小数部分的。基本数据类型由11个关键字组成:int
、short
、long
、unsigned
、char
、float
、double
、signed
、_Bool
’、_Complex
和_Imaginary
。
int
类型int
类型是有符号整数,有正负之分,也可以是0。一般用16位来存储一个int
值,int
的取值范围是-32768~32767,如果超过这个范围则会溢出,变为其它的数字。
声明int
类型变量时,先写上int
,再写上变量名。如果有多个变量名,用逗号分隔。例如
int x;
int x, y, z;
声明变量的目的有二:一是分配内存空间;二是指定变量名称。声明变量只是创建了变量,但是还没有值,可通过初始化的方式为变量赋值。初始化可与声明同时进行。例如
int x = 1;
int x = 1, y = 2, z = 3;
int a = 0x10; // 0x10是16进制数,16进制数以0x为前缀
int b = 010; // 010是10进制数,10进制数以0为前缀
如果赋值了一个小数,小数部分会被直接丢弃(截断)。
变量初始化不仅创建了存储空间还指定了初始值。
C语言还提供了short
、long
来修饰int
,可以控制变量占用的存储空间,变量取值范围也就不同。都属于有符号数。
类型 | 取值范围 |
---|---|
short int (简写short ) |
-32767~32767 |
long int (简写long ) |
-21474843647~2147483647 |
long long int (简写long long ) |
-9223372036854775807~9223372036854775807 |
shor
占16位,long
占32位,long long
占64位。
int
类型可能占16位,也可能占32位,这由计算机的字长决定。C语言规定short
类型存储空间不能大于int
,因此可能等于;long
占用的存储空间不能大于int
,因此也可能等于。
如果需要知道确切大小,可使用sizeof()
运算符计算,例如
sizeof(int);
这样可以得到int
类型的字节大小。
另外,C语言头文件limits.h
和float.h
中分别定义类整数类型和浮点数类型的大小限制信息,具体可查看此文。
上述类型都是有符号数,可正可负,这些有符号数前可用signed
修饰。而用关键字unsigned
修饰可表示无符号数。unsigned int
(简写unsigned
)仅表示非负数,取值范围就不是 -32768~ 32767了,而是0~65535了。unsigned
还可与上面表格中的short
、long
和long long
型组成其它无符号类型,取值范围如下表
类型 | 取值范围 |
---|---|
unsigned int (简写unsigned ) |
0~65535 |
unsigned long int (简写unsigned long ) |
0~4294967295 |
unsigned long long int (简写unsigned long long ) |
0~18446744073709551615 |
unsigned
类型适用于计数。如果所用数据超出了int
范围建议使用long long
类型,因为long
类型的范围可能与int
相同(由机器决定),而且long
类型会减慢运算速度。
char
类型char
类型用于存储字符,比如字母或者标点,当然数字也可作为字符的形式存储,但要注意数字和数字字符之间的区别。char
类型实际上也是整数类型,这是因为在计算机内部存储的字符也是整数,计算机使用数字编码来处理字符,最常用的是ASCII码。ASCII码的范围是0~127,因此,用8位来存储char
类型即可。
如果要表示基本字符集,也可以是16位或更大。
char
类型的声明方式与int
相同,在初始化时需要给字符加上单引号,例如
char a = 'A';
char
类型用整数存储,因此初始化为一个数字也可正确识别为字母,例如
char a = 65; // A的ASCII是65
上面两种方法等效。如果赋值多个字符,只有最后一个字符才有效,例如
char a = 'ABC';
上述变量a
被初始化为C。
char
类型也可分为有符号和无符号两种,分别使用signed
和unsigned
修饰,这可以在处理很小的数字时使用。如果只是用来处理字符串,则无需修饰。
该类型用来表示布尔值,即逻辑真或假,真用1表示,而假用0表示。因此,该类型实际上也是整数类型,只占1位的存储空间。声明和初始化如下
_Bool a = 1; // 逻辑假
_Bool b = 0; // 逻辑真
以上就描述完了整数类型。实际上,还有扩展的整数类型。
如果加入了stdbool.h
头文件,就可用bool
代替_Bool
,用true
和false
分别代替1和0。
C语言中,浮点数类型有三种:float
、double
和long double
。浮点数类型可用指数记数法(或e记数法)表示,指数计数法类似于科学记数法。
C语言规定,float
类型(单精度浮点类型)要至少表示6位有效数字(包含整数和小数),取值范围至少是 1 0 − 37 10^{-37} 10−37~ 1 0 37 10^{37} 1037。计算机存储一个浮点数需要32位。
另一种double
类型(双精度浮点类型)最小能表示10位有效数字,在需要64位来存储,相对于float
类型来说提高了精度。
long double
类型的精度则更高,至少与double
类型相同。
浮点类型变量的声明与初始化与int
类型相同,如下
float a = 2.3;
double b = 6.6e8; // e也可大写为E,表示10的指数
long double c;
小数常量(如上2.3)会被默认为double
类型,然后将其强行转化为float
类型,这会降低程序效率,一种方法是在数字后面跟上f或F后缀表示float
类型,如2.3F
。
小数也可用16进制数表示,在数字前加上0x前缀即可。也可用p或P代替e或E,用2的幂代替10的幂。
当数字过大,超过能表示的范围时就会发生上溢,这种情况下会赋一个表示无穷大的特定值,显示为inf
或者infinity
。如果数很小,发生了精度损失,则称为下溢。还有一种特殊的值为NaN(Not a Number),表示为未定义的值。
浮点数在计算的时候可能发生精度损失。
C99支持复数类型和虚数类型。C语言有三种复数类型
类型 | 含义 |
---|---|
float_Complex |
两个float 类型数分别表示实部和虚部 |
double_Complex |
两个double 类型数分别表示实部和虚部 |
long double_Complex |
两个long double 类型数分别表示实部和虚部 |
C语言还有3种虚数类型,分别为float_Imaginary
、double_Imaginary
和long double_Imaginary
。
如果包含complex.h
头文件,则可用complex
替代_Complex
,用imainary
替代_Imaginary
,用I
代替 − 1 \sqrt{-1} −1。
C11标准将复数软件包作为可选项。
C语言允许编写混合数据类型的表达式,但在计算时会自动转化。
以上都是C语言的基本类型,C语言没有字符串类型,但有许多衍生出来的类型,如数组、字符串、指针、结构、联合、枚举等。
C++与C一样,基本数据类型也分为两种:整数类型和浮点类型。
整数类型就是没有小数部分的数字,这一点与C语言相同,C++也提供了许多类型来存储整数,也同样可以分为有符号数和无符号数。
C++提供了short
、int
、long
和long long
,这与C语言是相同的,此处不再赘述,详见该文章第一部分C语言的第1、2小节。
变量的声明与初始化也与C语言一致,同样可以参考上一部分内容。另外,C++还有一种C没有的初始化方式,如下
int a(666);
可在变量声明时,在变量后面加入括号和数字的方式实现。这条语句中的小括号()
也可换成大括号{}
,如
int a{666};
int a{};
用大括号{}
同样可以完成初始化操作,如果大括号里不填数字,则初始化为0。
使用大括号的形式可以初始化许多种类型的变量,比如数组、结构体和类等。用大括号完成了初始化方式的统一,便于学习。
C++与C一样具有无符号类型,同样使用unsigned
关键字进行修饰,详细内容可见上一部分。
char
、wchar_t
类型C++中的char
类型与C相似,可以参照C语言部分。需要再次说明的是,char
类型也可以用来表示较小的整数,用signed char
表示有符号整数,而unsigned char
表示无符号整数。
除了char
类型以外,还有一种类型wchat_t
类型,它叫做宽字符类型,表示扩展字符集。初始化和使用时可以加上前缀L
来指示,如下
wchar_t a = L'A';
这种表示可以处理一些特殊符号。
C++11还增加了char16_t
和char32_t
两种类型,前者长16位,后者长32位,两者都是无符号的,前者使用前缀u
表示,后者使用U
作为前缀。
bool
类型在C中,布尔类型用_Bool
表示,而在C++中,则用bool
表示。可直接用true或false对布尔变量进行赋值,也可使用数字,如下
bool a = true;
bool b = false;
bool c = 20;
bool d = 0;
用数字赋值时,非0值都会转化为true,0被转化为false。
浮点数能够表示小数,能表示的范围也更大。浮点数具有三种类型:float
、double
和long double
,大部分内容也与C语言部分相同,可参见上面C语言部分。
auto
声明C++11提供了一个工具,在声明和初始化中使用关键字auto
,而不指定变量类型,编译器将把变量的类型设置为初始值的类型,例如
auto x = 4;
auto y = 1.5;
在上述过程中,x
被识别为int
类型,而y
被识别为double
类型。
除了这些之外,C++还有数组、字符串、结构体、共用体、枚举和指针等复合类型。
Java基本变量有byte
、short
、int
、long
、float
、double
、boolean
、char
和String
。
Java具有4种整数类型:byte
、short
、int
和long
,它们的存储位数不同,能表示的范围也就不同,如下表
类型 | 存储大小 | 取值范围 |
---|---|---|
byte | 8位 | -128~127 |
short | 16位 | -32768~32767 |
int | 32位 | -2147483648~2147483647 |
long | 64位 | -9223372036854775808~9223372036854775807 |
Java具有两种浮点数数类型:float
和double
,分别占32位和64位。
这些变量的声明和初始化都与C\C++相同。但是,与C\C++不同的是,如果初始化的数超过了变量类型的取值范围,则会发生编译错误;而在C\C++中,这种情况并不会报错。
boolean
类型boolean
数据类型用于声明一个具有值true或false的变量,与C\C++相同,但要注意名称上的不同。
char
类型类似于C\C++中的char
类型。
不同于char
类型只能表示单个字符,String
可以表示一系列字符,也即字符串。但String
是Java库中预定义的一个类,不是基本类型,而是引用类型,String
的使用可参考此文。
Java还有一些更复杂的类型,如数组。
Python中的基本数据类型有4种:整数(int
)、浮点数(float
)、字符串(str
)和布尔值(bool
)。
int
类型int
类型与C\C++和Java相同,表示整数,此处不再赘述。但是Python中没有其它的整数类型。
在Python中可用type
命令查看类型,如下
type(2)
上述命令显示int
类型。
float
类型浮点数类型与C\C++和Java也相同,表示小数。
str
类型Python中没有字符类型,只有字符串类型str
。
在Python中,字符串可用单引号'
或者双引号"
包围。而在C\C++和Java中,字符变量用单引号,Java字符串类型用双引号。
bool
类型bool
类型用true
或false
表示,在使用过程中不要用单引号或双引号包围,否则变为字符串类型。
Python在进行变量定义的时候不需要声明类型,例如
a = 123
而在C\C++或Java中需要写为
int a = 123;
在C\C++和Java中,声明变量在内存中开辟了一个存储空间用于存储数据,并标定了这个存储空间的名称,当把一个新的值赋值给变量时,这个新的值会覆盖原来的值,还是存储在这个地址中。
而Python不同,Python是以数据为中心的。变量存储在内存中,而变量名仅仅是这个数据的引用。当给变量赋新的值的时候,则更改了数据的引用,这个变量名会指向新的区域。可以使用id(a)
命令查看变量的a
的引用地址,当给a
赋予一个新的值,a
的值会发生变化。如果两个变量等于相同的数,则它们会引用同一个地址。