裸指针操作
学习目标
- 掌握裸指针的创建和操作
- 理解裸指针与引用的区别
- 掌握指针算术
核心概念
创建裸指针
fn main() {
let mut num = 5;
let r1 = &num as *const i32;
let r2 = &mut num as *mut i32;
let r3 = 0x12345usize as *const i32;
let null: *const i32 = std::ptr::null();
}
解引用
fn main() {
let mut value = 42;
let ptr = &mut value as *mut i32;
unsafe {
println!("值: {}", *ptr);
*ptr = 100;
println!("修改后: {}", *ptr);
}
}
指针算术
fn main() {
let arr = [1, 2, 3, 4, 5];
let ptr = arr.as_ptr();
unsafe {
for i in 0..arr.len() {
println!("arr[{}] = {}", i, *ptr.add(i));
}
}
}
指针与引用转换
fn main() {
let mut value = 42;
let ptr = &mut value as *mut i32;
unsafe {
let r = &mut *ptr;
*r = 100;
}
println!("value = {}", value);
}
std::ptr 方法
fn main() {
let mut a = 1;
let mut b = 2;
let ptr_a = &mut a as *mut i32;
let ptr_b = &mut b as *mut i32;
unsafe {
std::ptr::copy_nonoverlapping(ptr_a, ptr_b, 1);
println!("b = {}", b);
std::ptr::swap(ptr_a, ptr_b);
std::ptr::write(ptr_a, 99);
println!("a = {}", a);
}
}
实践练习
练习 1:手动 memcpy
fn my_copy<T: Copy>(src: *const T, dst: *mut T, count: usize) {
unsafe {
for i in 0..count {
dst.add(i).write(src.add(i).read());
}
}
}
fn main() {
let src = [1, 2, 3, 4, 5];
let mut dst = [0i32; 5];
my_copy(src.as_ptr(), dst.as_mut_ptr(), 5);
println!("{:?}", dst);
}
小结
| 操作 | 语法 |
|---|
创建 *const | &x as *const T |
创建 *mut | &mut x as *mut T |
| 解引用 | unsafe { *ptr } |
| 指针算术 | ptr.add(n) |
| 写入 | ptr.write(value) |
| 复制 | std::ptr::copy |