基本数据类型
数据类型概述
数据类型就像你的身份证,它定义了变量或常量可以存储的数据种类、取值范围和可执行的操作。为了方便新手入门,这里不会一股脑地列出所有细节,而是先介绍一些常见、常用的数据类型。
C++
整型
整型用于存储整数值,不同类型有不同的存储空间和取值范围。
int | 4字节 | 约 |
|
long long | 8字节 | 约 |
需要特别注意的是,当数据范围可能超出 int
类型的限制时,应使用 long long
类型,避免整数溢出导致错误结果。
浮点型
浮点型用于存储带小数点的数值,不同类型有不同的精度和范围。
float (不建议使用) | 4字节 | 6-7位有效数字 | |
double | 8字节 | 15-16位有效数字 | |
long double | 16字节 | 18-19位有效数字 |
需要特别注意的是,浮点数计算存在精度误差,不应直接用 ==
比较两个浮点数是否相等,而应判断它们的差值是否小于某个很小的数(如 1e-9
,即 )。此外,应尽量避免使用
float
类型,因为它的精度较低,容易导致计算误差。
字符型
字符型用于存储单个字符,在C++中使用 char
类型。
char | 1字节 | 可表示ASCII字符集中的字符 |
需要特别注意的是,char
类型在C++中既可以当作字符使用,也可以当作小整数使用。例如,'A'
的ASCII值为65,可以进行算术运算:'A' + 1
的结果为66,对应字符 'B'
。
布尔型
布尔型用于表示逻辑值,只有两种可能的取值:真(true
)和假(false
)。
bool | 1字节 | true 或 false |
任何非零值都被视为 true |
需要特别注意的是,在 C++ 中,bool
类型的变量可以隐式转换为整数类型,其中 true
转换为 1
,false
转换为 0
。反之,整数类型也可以隐式转换为 bool
类型,其中 0
转换为 false
,非零值转换为 true
。
Java
整型
整型用于存储整数值,不同类型有不同的存储空间和取值范围。
int | 4字节 | 约 |
|
long | 8字节 | 约 |
需要特别注意的是,Java中的整型字面量默认为 int
类型,如果要表示 long
类型的字面量,需要在数字后面加上 L
或 l
,如 123L
。
浮点型
Java的浮点型数据类型遵循IEEE 754标准,有固定的精度和范围。
float (不建议使用) | 4字节 | 6-7位有效数字 | |
double | 8字节 | 15-16位有效数字 |
需要特别注意的是,Java中的浮点型字面量默认为 double
类型,如果要表示 float
类型的字面量,需要在数字后面加上 F
或 f
,如 123.45f
。与C++类似,浮点数计算也存在精度误差,不应直接用 ==
比较两个浮点数是否相等,而是判断它们的差值是否小于某个很小的数(如 1e-9
,即 )。此外,应尽量避免使用
float
类型,因为它的精度较低,容易导致计算误差。
字符型
Java的字符型使用 char
类型,采用Unicode编码,可以表示世界上大多数书面语言的字符。
char | 2字节 | 可表示Unicode字符集中的字符 |
需要特别注意的是,Java中的 char
类型是无符号的,取值范围是 0 到 65535,不能表示负数。字符字面量使用单引号,如 'A'
,而字符串字面量使用双引号,如 "Hello"
。
布尔型
Java的布尔型使用 boolean
类型,只有两种可能的取值:真(true
)和假(false
)。
boolean | 1位或1字节 | true 或 false |
不能与整数类型相互转换 |
需要特别注意的是,与C++不同,Java中的 boolean
类型不能与整数类型相互转换,必须使用条件表达式来产生布尔值。
Python
整型
Python的整型(int
)可以表示任意大小的整数,不受位数限制。
int | 可变 | 无限制 | 只受可用内存限制 |
需要特别注意的是,Python 3中只有一种整数类型 int
,可以表示任意大的整数,不会发生整数溢出。这与C++和Java不同,后者的整型有固定的大小和范围。
浮点型
Python的浮点型(float
)遵循IEEE 754标准,通常是双精度的。
float | 8字节 | 15-16位有效数字 |
需要特别注意的是,Python中的浮点数计算也存在精度误差,不应直接用 ==
比较两个浮点数是否相等,而应判断它们的差值是否小于某个很小的数(如 1e-9
,即 )。
字符串型
Python中没有单独的字符类型,字符就是长度为1的字符串。
str | 可变 | Unicode字符序列 | 不可变类型 |
需要特别注意的是,Python中的字符串是不可变的,一旦创建就不能修改。字符串可以用单引号、双引号或三引号(用于多行字符串)表示。
布尔型
Python的布尔型(bool
)只有两种可能的取值:真(True
)和假(False
)。
bool | 1字节 | True 或 False |
True 和 False 首字母大写 |
需要特别注意的是,Python 中的布尔值 True
和 False
首字母必须大写。布尔值可以参与算术运算,其中 True
被当作 1
,False
被当作 0
。
变量与常量
变量和常量是编程中最基本的概念之一,它们用于在程序中存储和管理数据。简单来说,变量就像是一个可以存放数据的盒子,而常量则是一个贴上了"请勿移动"标签的盒子。
变量的定义与初始化
变量必须先定义后使用,定义变量时需要指定其数据类型和名称,还可以选择性地进行初始化(赋初值)。
C++
在C++中,变量的定义语法如下:
数据类型 变量名 = 初始值; // 定义并初始化
数据类型 变量名; // 仅定义,不初始化
例如:
int a = 10; // 定义整型变量a并初始化为10
double b = 3.14; // 定义浮点型变量b并初始化为3.14
char c = 'A'; // 定义字符型变量c并初始化为'A'
bool d = true; // 定义布尔型变量d并初始化为true
int e; // 仅定义整型变量e,不初始化
需要特别注意的是,在 C++ 中,未初始化的变量可能包含随机值,这可能导致程序行为不可预测。因此,建议在定义变量时就进行初始化。
Java
在 Java 中,变量的定义语法与 C++ 类似:
数据类型 变量名 = 初始值; // 定义并初始化
数据类型 变量名; // 仅定义,不初始化
例如:
int a = 10; // 定义整型变量a并初始化为10
double b = 3.14; // 定义浮点型变量b并初始化为3.14
char c = 'A'; // 定义字符型变量c并初始化为'A'
boolean d = true; // 定义布尔型变量d并初始化为true
int e; // 仅定义整型变量e,不初始化
需要特别注意的是,在 Java 中,局部变量(方法内定义的变量)必须先初始化后才能使用,否则编译器会报错。而成员变量(类中定义的变量)如果不显式初始化,会被自动初始化为默认值(如 int
为 ,
boolean
为 false
)。
Python
Python是动态类型语言,变量不需要预先声明类型,而是在赋值时自动确定类型:
变量名 = 值 # 定义并初始化变量
例如:
a = 10 # 整型变量
b = 3.14 # 浮点型变量
c = 'A' # 字符串变量(Python没有单独的字符类型)
d = True # 布尔型变量(注意首字母大写)
需要特别注意的是,Python 中的变量必须先赋值后使用,没有"仅定义不初始化"的概念。此外,Python 变量的类型可以随时改变,这与 C++ 和 Java 等静态类型语言不同。
常量的定义与使用
常量是指在程序运行过程中值不能被修改的量。
C++
在C++中,可以使用 const 关键字定义常量:
const 数据类型 常量名 = 值;
例如:
const int MAX_VALUE = 100; // 整型常量
const double PI = 3.14159; // 浮点型常量
const char GRADE = 'A'; // 字符型常量
const bool IS_ENABLED = true; // 布尔型常量
需要特别注意的是,C++中的常量必须在定义时初始化,之后不能再修改其值。
Java
在Java中,可以使用 final 关键字定义常量:
final 数据类型 常量名 = 值;
例如:
final int MAX_VALUE = 100; // 整型常量
final double PI = 3.14159; // 浮点型常量
final char GRADE = 'A'; // 字符型常量
final boolean IS_ENABLED = true; // 布尔型常量
需要特别注意的是,Java中的常量(用final修饰的变量)必须且只能被赋值一次,可以在声明时初始化,也可以在构造方法中初始化。
Python
Python没有内置的常量类型,但有一个约定俗成的规则:使用全大写字母命名的变量被视为常量,表示不应该修改它们的值:
MAX_VALUE = 100 # 整型"常量"
PI = 3.14159 # 浮点型"常量"
GRADE = 'A' # 字符串"常量"
IS_ENABLED = True # 布尔型"常量"
需要特别注意的是,这只是一种编程约定,Python并不会阻止你修改这些"常量"的值。如果需要真正的常量,可以使用第三方库或自定义类实现。
基础输入输出
我们写的程序往往是为了实现某些特定的功能,比如计算两个数的和、求一个数的平方根等等。而这些功能往往需要我们从外部获取数据(比如告诉程序我们要求哪两个数的和),然后将结果输出到外部(将计算结果告诉给我)。在大部分编程语言中,我们通过终端(即代码运行的界面)对程序进行输入,程序也会在终端上将程序运算的结果进行输出。
接下来,我们要学习如何控制程序将终端上你输入的数据进行读入,以及如何将程序运算的结果进行输出到终端,最终的效果如下图所示(以 C++ 输入两个正整数,输出两个数的和为例,其他语言效果类似)。
C++
在 C++ 中,我们使用 cin
进行输入,使用 cout
进行输出。他们对应的语法分别为:
cin >> 需要输入的变量名; // 输入
cout << 需要输出的变量名; // 输出
此外,如果需要连续输入或输出若干个变量,只需要把其他变量在这个基础上直接用 >>
或 <<
连接起来即可,例如:
cin >> 需要输入的变量名1 >> 需要输入的变量名2 >> 需要输入的变量名3; // 输入
cout << 需要输出的变量名1 << 需要输出的变量名2; // 输出
cin 语句会自动读入用户在终端的输入,并以空格或换行作为默认的该次读入的结束的标识(后面的内容则会被留给下一个需要读入的变量),然后把这一部分的值直接赋值给需要输入的变量。
同时,在我们输出变量时,如果直接无脑输出一堆变量,他们就会黏在一起而不会自动换行,这可能会导致我们的输出结果变得奇怪。所以,我们也可以在输出的各个变量之间加入空格(' '
)或换行符('\n'
或 endl
,注意 endl
不需要引号),以达到我们想要的输出效果。
下面是一个简单的例子:
#include <bits/stdc++.h>
using namespace std;
int main() {
// 整型输入输出
int a;
cin >> a;
cout << a << '\n';
// 浮点型输入输出
double b;
cin >> b;
cout << b << '\n';
// 字符型输入输出
char c;
cin >> c;
cout << c << '\n';
// 布尔型输入输出
bool d;
cin >> d; // 输入非零值为true,0为false
cout << d << '\n'; // 输出1或0
return 0;
}
Java
在Java中,我们使用 Scanner
类的若干个内置函数(见下方大表格)进行输入,使用 System.out
进行输出。他们对应的语法分别为:
Scanner scanner = new Scanner(System.in); // 创建Scanner对象
待输入变量名 = scanner.next对应变量类型的后缀();
待输入变量名 = scanner.nextInt(); // 例如,输入整数时
System.out.println(待输出变量名); // 输出并换行
System.out.print(待输出变量名); // 输出不换行
scanner.close(); // 关闭Scanner
此外,如果需要连续输入或输出若干个变量,可以使用多个输入方法和输出方法:
// 输入多个变量
int 待输入变量名1 = scanner.nextInt();
int 待输入变量名2 = scanner.nextInt();
int 待输入变量名3 = scanner.nextInt();
// 输出多个变量
System.out.println(待输出变量名1);
System.out.println(待输出变量名2);
System.out.println(待输出变量名3);
Scanner 类会自动读入用户在终端的输入,并以空格或换行作为默认的该次读入的结束的标识,然后把这一部分的值直接赋值给需要输入的变量。
以下是Java中常用的Scanner类输入方法表格:
int | nextInt() | 读取一个整数 | int a = scanner.nextInt(); |
long | nextLong() | 读取一个长整数 | long a = scanner.nextLong(); |
double | nextDouble() | 读取一个双精度浮点数 | double a = scanner.nextDouble(); |
boolean | nextBoolean() | 读取一个布尔值("true"或"false") | boolean a = scanner.nextBoolean(); |
String | next() | 读取下一个字符串(以空格或换行为分隔) | String a = scanner.next(); |
String | nextLine() | 读取下一行字符串(以换行符为分隔) | String a = scanner.nextLine(); |
char | next().charAt(0) | 读取一个字符(先读取一个字符串,再取第一个字符) | char a = scanner.next().charAt(0); |
需要特别注意的是,在使用 nextLine()
方法之前如果使用了其他 next某某某()
方法,可能需要额外调用一次 nextLine()
来先读入之前没读入的换行符,然后才能读入到这一次真正想要读入的一行内容。
同时,在我们输出变量时,可以使用 System.out.println()
进行带换行的输出,或使用 System.out.print()
进行不换行的输出。如果需要在变量之间添加空格或其他分隔符,可以使用字符串连接操作符 +
。
下面是一个简单的例子:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 整型输入输出
int a = scanner.nextInt();
System.out.println(a);
// 浮点型输入输出
double b = scanner.nextDouble();
System.out.println(b);
// 字符型输入输出
char c = scanner.next().charAt(0);
System.out.println(c);
// 布尔型输入输出
boolean d = scanner.nextBoolean(); // 输入"True"或"False"
System.out.println(d);
scanner.close(); // 关闭Scanner
}
}
需要特别注意的是,使用 Scanner 类时,不同类型的输入有不同的方法,如 nextInt() 、 nextDouble() 、 next() 等,在输入时需要我们根据预计的输入数据类型进行规定。使用完毕后应调用 close() 方法关闭Scanner。
Python
在Python中,我们使用 input() 函数进行输入,使用 print() 函数进行输出。
input()
函数只能读入一行字符串,但是你可以通过类型转换和字符串分割来把读入的字符串转化为你需要的数据类型。
print()
函数可以输出多个任意类型的变量,默认以空格各个变量之间的分隔符,换行为所有变量均被输出完成后的结束标识符。如果你希望指定其他的分隔符和结束标识符,你可以更改 print() 函数的 sep 和 end 参数。
他们对应的语法分别为:
待输入变量名1 = input() # 输入字符串
待输入变量名2 = int(input()) # 输入字符串后转化为整数类型
待输入变量名3 = float(input()) # 输入字符串后转化为浮点数类型
print(待输出变量名) #默认分隔符、结束标识符的单个变量输出
print(待输出变量名1,待输出变量名2,待输出变量名3) #默认分隔符、结束标识符的多个变量输出
print(待输出变量名1,待输出变量名2,待输出变量名3,sep=分隔符,end=结束标识符) # 指定分隔符、结束标识符的输出
同时,如果希望在输入以空格为分隔符,我们可以在读入一整行字符串后,以空格为分隔符,分割成若干个字符串,然后再对每个字符串进行类型转换。可以参考下面的语法:
待输入变量名1,待输入变量名2,待输入变量名3 = map(待输入变量类型,input().split(分隔符))
下面是一个简单的例子:
# 整型输入输出
a = int(input())
print(a)
# 浮点型输入输出
b = float(input())
print(b)
# 字符串输入输出
c = input()
print(c)
# 布尔型输入输出
d = bool(int(input())) # 输入0为False,非0为True
print(d)
# 一次性输入多个整数(以空格分隔)
x, y, z = map(int, input().split())
print(x, y, z, sep=', ', end='.\n')
进阶输入输出
C++
在 C++ 中,我们可以使用 fixed
和 setprecision
来控制浮点数的输出精度。常见的应用有以下两种:
- 保留小数点后
位(四舍五入),对应的语法为:
cout << defaultfloat; //清空以前对小数输出格式的设置
cout << fixed << setprecision(n) << 待输出变量名; // 输出待输出变量名(保留n位小数)
- 保留有效数字
位(四舍五入),对应的语法为:
cout << defaultfloat; //清空以前对小数输出格式的设置
cout << setprecision(n) << 待输出变量名; // 输出待输出变量名(保留n位有效数字)
下面举一个简单的例子:
#include <bits/stdc++.h>
using namespace std;
int main() {
double d = 3.1415926;
cout << fixed << setprecision(3) << d << endl; // 输出3.142
cout << defaultfloat; //清空以前对小数输出格式的设置
cout << setprecision(3) << d << endl; // 输出3.14
return 0;
}
总结一下, fixed 和 setprecision(n) 一起使用时,表示小数点后的位数;单独使用 setprecision(n) 表示有效数字的位数。
Java
在 Java 中,我们可以使用 System.out.printf()
来控制浮点数的输出精度。常见的应用有以下两种:
- 保留小数点后
位(四舍五入),对应的语法为:
System.out.printf("%.nf", 待输出变量名);
- 保留有效数字
位(四舍五入),对应的语法为:
System.out.printf("%.ng", 待输出变量名);
下面举一个简单的例子:
public class Main {
public static void main(String[] args) {
// 设置浮点数精度
double pi = 3.1415926;
System.out.printf("%.3f", pi); // 输出3.142
System.out.print("\n"); //换行
System.out.printf("%.3g", pi); // 输出3.14
}
}
Python
在 Python 中,f-string(格式化字符串字面量)是 Python 3.6 引入的一种字符串格式化方法,它提供了一种简洁、直观的方式来在字符串中嵌入表达式。
f-string 的基本语法是在字符串前加上字母 f
或 F
,然后在字符串中使用花括号 {}
来包含 Python 表达式,此时这个表达式在得到结果后,会被自动填充到花括号对应的位置。例如:
name = "World"
print(f"Hello, {name}!") # 输出: Hello, World!
f-string 可以被用来实现很多功能:
- 表达式求值:
花括号内可以是任何有效的Python表达式
print(f"2 + 2 = {2 + 2}") # 输出: 2 + 2 = 4
- 格式说明符 :
可以在表达式后添加冒号和格式说明符,如果要保留小数点后 位(四舍五入),可以使用
:.nf
格式说明符;如果要保留有效数字 位(四舍五入),可以使用
:.ng
格式说明符。
pi = 3.14159
print(f"Pi is approximately {pi:.2f}") # 输出: Pi is approximately 3.14
- 数字格式化 :
可以使用 :,
、 :_
、 :e
、 :%
等格式说明符来控制数字的输出格式。
num = 1234567
print(f"{num:,}") # 添加千位分隔符: 1,234,567
print(f"{num:_}") # 使用下划线作为千位分隔符: 1_234_567
print(f"{num:e}") # 科学计数法: 1.234567e+06
print(f"{num:%}") # 百分比: 123456700.000000%
类型转换
C++
C++ 提供了两种类型转换方式:隐式转换和显式转换。
-
隐式转换:我们可以通过将一种类型的变量直接赋值给另一种类型的变量,此时被赋值的变量就相当于是主动赋值变量由原本数据类型转化为新数据类型后的值。此时,编译器会自动将一种类型转换为另一种类型,无需额外的代码。
-
显式转换:我们也可以使用强制类型转换运算符来将一种类型的变量强制转换为另一种类型的变量。此时,我们需要在变量名前加上括号,并在括号内指定要转换的目标类型。例如,如果我们要把一个
double
类型的变量(假设这个变量叫d
)转换为int
类型的变量,此时表示变量d
在被转化类型后的结果的表达式为:(int) d
。需要注意的是,这个操作只能得到转换后的值,并不会改变原本变量的值,也就是说,此时变量d
的数据类型并没有发生改变,仍然为double
类型。
特殊的,在 C++ 中,我们无法直接通过 (string) 整数类型变量名
的方法将整数类型变量转换为字符串类型变量,也无法直接通过 (int) 字符串类型变量名
的方法将字符串类型变量转换为整数类型变量。如果需要,可以尝试使用下面三个函数:
stoi()
函数:将字符串转换为整数。stod()
函数:将字符串转换为双精度浮点数。to_string()
函数:将数值转换为字符串。
具体的用法可以参考下面两个例子:
#include <bits/stdc++.h>
using namespace std;
int main() {
// 隐式转换
int a = 5;
double b = a; // int转double
// 显式转换
double c = 3.14;
int d = (int)c; // double转int,结果为3
// 字符串转数值
string str = "123";
int f = stoi(str); // 字符串转int
double g = stod("3.14"); // 字符串转double
// 数值转字符串
string h = to_string(42); // 数值转字符串
return 0;
}
需要特别注意的是,从浮点型转换为整型时,小数部分会被截断,而不是四舍五入。
Java
Java 提供了两种类型转换方式:隐式转换和显式转换。
- 隐式转换:我们可以通过将一种类型的变量直接赋值给另一种类型的变量,此时被赋值的变量就相当于是主动赋值变量由原本数据类型转化为新数据类型后的值。此时,编译器会自动将一种类型转换为另一种类型,无需额外的代码。例如:
public class Main {
public static void main(String[] args) {
int a = 5;
double b = a; // int 自动转 double(5 → 5.0)
long c = 100L;
float d = c; // long 自动转 float(100 → 100.0f)
}
}
- 显式转换:我们也可以使用强制类型转换运算符来将一种类型的变量强制转换为另一种类型的变量。此时,我们需要在变量名前加上括号,并在括号内指定要转换的目标类型。例如,如果我们要把一个
double
类型的变量(假设这个变量叫d
)转换为int
类型的变量,此时表示变量d
在被转化类型后的结果的表达式为:(int) d
。需要注意的是,这个操作只能得到转换后的值,并不会改变原本变量的值,也就是说,此时变量d
的数据类型并没有发生改变,仍然为double
类型。
public class Main {
public static void main(String[] args) {
double a = 3.14;
int b = (int) a; // double 强制转 int(3.14 → 3,截断小数)
long c = 1000L;
short d = (short) c; // long 强制转 short
}
}
特殊的,在 Java 中,我们无法直接通过 (string) 整数类型变量名
的方法将整数类型变量转换为字符串类型变量,也无法直接通过 (int) 字符串类型变量名
的方法将字符串类型变量转换为整数类型变量。如果需要,可以尝试使用下面三个方法:
字符串 → 整型 | Integer.parseInt() |
int num = Integer.parseInt("123"); |
字符串 → 浮点型 | Double.parseDouble() |
double d = Double.parseDouble("3.14"); |
数值 → 字符串 | String.valueOf() 或 + "" |
String s = String.valueOf(42); |
下面是一个简单的例子:
public class Main {
public static void main(String[] args) {
// 字符串转数值
String str1 = "123";
int num1 = Integer.parseInt(str1); // 字符串转int
String str2 = "3.14";
double num2 = Double.parseDouble(str2); // 字符串转double
// 数值转字符串
String s1 = String.valueOf(42); // 方法1
String s2 = 3.14 + ""; // 方法2(隐式转换)
}
}
Python
Python 作为动态类型语言,类型转换更加灵活,主要通过内置函数实现。
- 隐式转换:我们可以通过将一种类型的变量直接赋值给另一种类型的变量,此时被赋值的变量就相当于是主动赋值变量由原本数据类型转化为新数据类型后的值。此时,解释器会自动将一种类型转换为另一种类型,无需额外的代码。例如:
a = 5 # int 类型
b = 3.14 # float 类型
c = a + b # int 自动转 float → 8.14
d = True # bool(True=1, False=0)
e = d + a # bool 自动转 int → 6
- 显式转换:我们也可以使用强制类型转换运算符来将一种类型的变量强制转换为另一种类型的变量。此时,我们需要在变量名前加上括号,并在括号前指定要转换的目标类型。例如,如果我们要把一个浮点数类型的变量(假设这个变量叫
d
)转换为整数类型的变量,此时表示变量d
在被转化类型后的结果的表达式为:int(d)
。需要注意的是,这个操作只能得到转换后的值,并不会改变原本变量的值,也就是说,此时变量d
的数据类型并没有发生改变,仍然为浮点数类型。
整型 | int() |
int(3.14) → 3 (截断小数) |
浮点型 | float() |
float(5) → 5.0 |
字符串 | str() |
str(42) → "42" |
布尔型 | bool() |
bool(0) → False (非零为True) |
下面是一个简单的例子:
# 显式转换示例
x = 3.14
y = int(x) # 3(截断)
z = float("3.14") # 3.14(字符串转float)
s = str(100) # "100"
b = bool(0) # False