数据类型简介
在 MATLAB 中,最基本的数据结构是 数组 (Array)。可以说,MATLAB 的核心设计哲学就是“一切皆为数组”。无论是单个数值、一段文本、还是复杂的数据集合,其底层都以多维数组的形式存在。本篇文档将从这一核心概念出发,详细介绍 MATLAB 中的各类数据。
动态类型语言
MATLAB 是一种动态类型语言,这意味着您通常无需在创建变量时显式声明其数据类型。MATLAB 会根据您赋给变量的值自动选择最合适的类型。例如,执行 x = 10 会自动创建一个 \(1 \times 1\) 的 double 类型数组。
MATLAB 数组:核心基石
一个 MATLAB 数组是一个由多个元素组成的集合,这些元素被组织在一个 N 维的网格中。
- 维度 (Dimension): 数组的维度是其最核心的属性。
- 示例:
s = 10; % 标量 (1x1 数组)
v = [1, 2, 3]; % 行向量 (1x3 数组)
m = [1, 2; 3, 4]; % 矩阵 (2x2 数组)
n_dim_array = rand(2, 2, 3); % 2x2x3 的三维数组
-
索引 (Indexing):
- 示例:
A = [10, 20, 30; 40, 50, 60; 70, 80, 90];
element = A(2, 3); % 获取第 2 行第 3 列的元素,结果为 60
row_vec = A(1, :); % 获取第一整行,结果为 [10, 20, 30]
col_vec = A(:, end); % 获取最后一整列,结果为 [30; 60; 90]
sub_matrix = A(1:2, 2:3); % 获取左上角的 2x2 子矩阵
-
同质性 vs 异构性:
- 同质数组 (Homogeneous): 数组中所有元素的数据类型完全相同。这是基础数据类型(如数值、逻辑)的特征。
- 异构数组 (Heterogeneous): 数组中的元素可以有不同的数据类型。这是通过元胞数组和结构体等容器实现的。
基础数据类型 (同质数组)
这些数组的所有元素都必须是同一种数据类型。
数值数组 (Numeric Array)
这是科学计算中最常用的数组类型,其浮点数表示遵循 IEEE 754 标准。
double (双精度):
- 示例:
a = 10.5; % 默认创建为 double
b = [1.2, 3.4; 5.6, 7.8]; % double 矩阵
c = 1 + 2i; % 复数,实部和虚部都是 double
% 使用 whos 查看变量信息
whos a b c
single (单精度):
- 示例:
% 必须使用 single() 函数进行显式转换
s = single(10.5);
% 创建一个大型单精度随机矩阵以节省内存
large_single_array = rand(1000, 1000, 'single');
% 比较 double 和 single 的内存占用
large_double_array = rand(1000, 1000);
whos large_single_array large_double_array
- 整数 (
int*, uint*):
- 示例:
% 图像像素通常使用 uint8
pixel_value = uint8(255);
% 计数器可以使用有符号整数
event_counter = int32(-10000);
% intmax/intmin 查看整数类型的范围
min_val = intmin('int16');
max_val = intmax('int16');
whos pixel_value event_counter
disp(['int16 的范围是 [', num2str(min_val), ', ', num2str(max_val), ']']);
逻辑数组 (Logical Array)
- 描述: 数组的所有元素都是逻辑值
true (1) 或 false (0)。
- 示例:
A = [10, 25, 5, 40, 15];
% 创建一个逻辑掩码 (mask)
L = A > 20; % L 的值为 [false, true, false, true, false]
% 使用逻辑索引提取所有大于 20 的元素
elements_greater_than_20 = A(L); % 结果为 [25, 40]
% 一步完成筛选和赋值
A(A <= 20) = 0; % 将所有不大于 20 的元素替换为 0
% A 现在是 [0, 25, 0, 40, 0]
文本数组 (Text Array)
- 示例:
% char 字符数组
char_array = 'hello'; % 1x5 char
char_matrix = ['row1'; 'row2']; % 2x4 char
% string 字符串数组
string_array = "hello";
string_vector = ["text1", "a much longer text2"];
% 推荐使用 string 进行操作
new_string = string_array + " world"; % 结果是 "hello world"
whos char_array string_array
复合数据类型 (异构容器)
这些类型也是数组,但它们的元素是“容器”,每个容器可以独立地存放不同类型的数据。
元胞数组 (Cell Array)
- 描述: 一种其元素为“元胞”的数组。每个元胞都可以存放任意类型的数据,如一个 \(N \times M\) 矩阵、一个字符串和一个函数句柄。
- 示例:
% 创建一个 1x3 的元胞数组
C = {[1, 2; 3, 4], "some text", true};
% 使用 {} 访问元胞内部的内容
matrix_data = C{1}; % 提取第一个元胞的内容,是一个 2x2 矩阵
text_data = C{2}; % 提取第二个元胞的内容,是一个 string
% 使用 () 访问元胞本身
sub_cell = C(1:2); % 提取前两个元胞,结果仍是一个 1x2 元胞数组
% 修改元胞内容
C{3} = 1:10;
disp(C);
结构体数组 (Structure Array)
- 描述: 一种其元素为“结构体”的数组。每个结构体通过命名的“字段”(Field)来组织数据。一个结构体数组 \(S\) 中的所有元素都必须拥有完全相同的字段名。
- 示例:
% 创建一个 1x2 的结构体数组
students(1).name = "Alice";
students(1).id = 101;
students(1).grades = [95, 89, 92];
students(2).name = "Bob";
students(2).id = 102;
students(2).grades = [78, 85, 80];
% 访问数据
bob_name = students(2).name;
alice_grades = students(1).grades;
% 提取所有学生的 name 字段到一个 string 数组中
all_names = [students.name];
disp(['第二个学生的名字是: ', bob_name]);
disp('所有学生的名字:');
disp(all_names);
表格 (Table)
- 描述: 专为列向数据设计的二维数据容器。每一列是一个变量(通常是同质向量),可以有不同的数据类型。非常适合进行数据清洗、筛选、分组等分析任务。
- 示例:
LastName = ["Smith"; "Jones"; "Williams"];
Age = [38; 39; 40];
Smoker = [true; false; true];
Height = [71; 69; 64];
% 创建 table,并指定行名和变量名
T = table(Age, Smoker, Height, 'RowNames', LastName);
% 访问数据
age_of_jones = T.Age('Jones'); % 使用行名和变量名访问
smoker_data = T(T.Smoker == true, :); % 筛选出所有吸烟者的数据
disp('完整的表格:');
disp(T);
disp('吸烟者的数据:');
disp(smoker_data);
其他专门类型
函数句柄 (Function Handle)
- 描述:
使用
@ 符号创建,它是一种特殊的数据类型,用于表示一个函数 \(f(x)\) 的引用或“指针”。
- 示例:
% 创建一个代表函数 f(x) = x^2 的句柄
f_square = @(x) x.^2;
% 使用句柄调用函数
result1 = f_square(5); % 结果是 25
% 将匿名函数句柄直接传递给其他函数
% 计算定积分 ∫(x*cos(x)) dx from 0 to pi
result2 = integral(@(x) x.*cos(x), 0, pi);
disp(['f_square(5) 的结果是: ', num2str(result1)]);
disp(['积分结果是: ', num2str(result2)]);
专业类型
- 示例:
% categorical 数组
sizes = ["medium"; "large"; "small"; "medium"];
cat_sizes = categorical(sizes);
% datetime 数组
t1 = datetime('now');
t2 = datetime(2025, 1, 1);
time_diff = t2 - t1;
disp('分类数组的类别:');
disp(categories(cat_sizes));
disp(['距离 2025 年元旦还有: ', char(time_diff)]);
常用类型检查函数
- 示例:
my_var = {1, 'text', true};
% 使用 class
disp(['my_var 的类型是: ', class(my_var)]); % 输出 'cell'
% 使用 isa
is_it_a_cell = isa(my_var, 'cell'); % 结果是 true
is_it_a_struct = isa(my_var, 'struct'); % 结果是 false
% 使用 whos (在命令行中效果最佳)
A = rand(10);
B = "hello";
whos A B my_var