// ============================================================ // Rust 基础巩固练习 (变量类型 + 流程控制) // 在做完所有题目之前,建议先注释掉 main 函数中的代码, // 每题单独写一个函数来测试,然后在 main 中调用。 // ============================================================ fn main() { println!("Hello, world!"); // ex1_variables(); // ex2_scalar_types(); // ex3_compound_types(); // ex4_functions(); // ex5_control_flow(); // ex6_loops(); mini_guessing_game(); // ex8_stats(); } // ============================================================ // 练习1:变量与可变性 // ============================================================ // 1. 声明一个不可变变量 x = 10,尝试修改它为 20(看编译器报什么错), // 然后把报错的那行注释掉。 // 2. 声明一个可变变量 y = 5,然后将它修改为 15,打印修改前后的值。 // 3. 使用 let 遮蔽(shadowing):声明变量 z = "hello", // 然后用 let 再次声明 z,将其值改为 z.len()(即字符串长度), // 再用 let 声明 z,将其值改为 z * 2。打印每次遮蔽后的值。 #[allow(dead_code)] fn ex1_variables() { // TODO: 在这里写你的代码 let x = 10; // error: could not compile `part2` (bin "part2") due to 1 previous error; 10 warnings emitted // x = 20; let mut y = 5; println!("修改前:{}", y); y = 15; println!("修改后:{}", y); let z = "hello"; println!("z:{}", z); let z = z.len(); println!("z:{}", z); let z = z * 2; println!("z:{}", z); } // ============================================================ // 练习2:基本数据类型 // ============================================================ // 1. 声明 u8, i32, f64, bool, char 类型的变量各一个,赋予合理的值。 // 2. 使用 as 关键字将 u8 转换为 i32,将 f64 转换为 i32(观察小数部分被截断)。 // 3. 打印字符 char 的数值表示(用 as u32)。 // 4. 声明一个 usize 变量 = 5,让它减去 10(观察 underflow 的编译报错或用 wrapping_sub)。 #[allow(dead_code)] fn ex2_scalar_types() { // TODO: 在这里写你的代码 let u8_var: u8 = 42; let i32_var: i32 = 128; let f64_var: f64 = 3.14; let bool_var: bool = true; let char_var = '2'; println!("u8 as i32: {}", u8_var as i32); println!("f64 as i32: {}", f64_var as i32); println!("char as u32: {}", char_var as u32); let usize_var: usize = 5; // error: usize_var - 10: attempt to compute `5_usize - 10_usize`, which would overflow // usize_var.wrapping_sub(10): 18446744073709551611 println!("usize_var - 10: {}", usize_var.wrapping_sub(10)); } // ============================================================ // 练习3:复合类型 —— 元组 (Tuple) 和数组 (Array) // ============================================================ // 1. 声明一个元组 tup: (i32, f64, &str) = (42, 3.14, "rust"), // 分别用解构和 .索引 两种方式取出并打印三个元素。 // 2. 声明一个数组 arr: [i32; 5] = [1, 2, 3, 4, 5], // 用 for 循环遍历打印每个元素,打印数组长度。 // 3. 尝试访问 arr[10],观察编译报错 vs 运行时 panic 的区别—— // 先用常量索引(编译期检查),再用变量索引(运行期检查)。 #[allow(dead_code)] fn ex3_compound_types() { // TODO: 在这里写你的代码 let tup: (i32, f64, &str) = (42, 3.14, "rust"); let (a, b, c) = tup; println!("tup: {}, {}, {}", a, b, c); let a1 = tup.0; let b1 = tup.1; let c1 = tup.2; println!("tup: {}, {}, {}", a1, b1, c1); let arr: [i32; 5] = [1, 2, 3, 4, 5]; for i in 0..arr.len() { println!("arr[{}]: {}", i, arr[i]); } println!("arr length: {}", arr.len()); // arr[10]; error: index out of bounds: the len is 5 but the index is 10 } // ============================================================ // 练习4:函数定义与调用 // ============================================================ // 1. 写一个函数 add(a: i32, b: i32) -> i32,返回两数之和,在 main 中调它。 // 2. 写一个函数 factorial(n: u32) -> u32,用循环计算 n 的阶乘。 // 提示:n! = 1 × 2 × 3 × ... × n,0! = 1 // 3. 写一个函数 is_even(n: i32) -> bool,判断一个数是否为偶数。 // 4. 写一个无返回值的函数 greet(name: &str),打印 "你好,{name}!"。 #[allow(dead_code)] fn add(a: i32, b: i32) -> i32 { a + b } #[allow(dead_code)] fn factorial(n: u32) -> u32 { let mut result = 1; for i in 1..=n { result *= i; } result } #[allow(dead_code)] fn is_even(n: i32) -> bool { n % 2 == 0 } #[allow(dead_code)] fn greet(name: &str) { // TODO println!("你好,{}!", name) } fn ex4_functions() { // 在这里调用上面四个函数进行测试 println!("add(1, 2): {}", add(1, 2)); println!("factorial(5): {}", factorial(5)); println!("is_even(5): {}", is_even(5)); greet("Rust"); } // ============================================================ // 练习5:控制流 —— if / else if / else // ============================================================ // 1. 写一个函数 grade(score: u32) -> &'static str,根据分数返回等级: // 90-100 → "A", 80-89 → "B", 70-79 → "C", 60-69 → "D", 0-59 → "F" // 2. 写一个函数 fizzbuzz(n: u32),打印 1 到 n: // 能被 3 整除打印 "Fizz",能被 5 整除打印 "Buzz", // 能同时被 3 和 5 整除打印 "FizzBuzz",否则打印数字本身。 // 3. 使用 if 作为表达式(let x = if ... { ... } else { ... };), // 根据一个 bool 变量给另一个变量赋不同的值。 #[allow(dead_code)] fn grade(score: u32) -> &'static str { let mut x = ""; if score >= 90 && score <= 100 { x = "A"; } else if score >= 80 && score < 90 { x = "B"; } else if score >= 70 && score < 80 { x = "C"; } else if score >= 60 && score < 70 { x = "D"; } else { x = "F"; }; return x; } #[allow(dead_code)] fn fizzbuzz(n: u32) { for i in (1..=n) { if i % 3 == 0 && i % 5 == 0 { println!("FizzBuzz") } else if i % 3 == 0 { println!("Fizz") } else if i % 5 == 0 { println!("Buzz") } else { println!("{}", i) } } } fn ex5_control_flow() { // 在这里测试 let score = 89; let condition = true; let n = if condition { 100 } else { 50 }; println!("grade:{}", grade(score)); fizzbuzz(n); } // ============================================================ // 练习6:循环 —— loop / while / for // ============================================================ // 1. 用 loop 写一个无限循环,内部用计数器从 1 开始累加, // 当计数达到 100 时用 break 退出,并用 break 返回值打印最终结果。 // 2. 用 while 循环打印 10 到 1 的倒数。 // 3. 用 for 循环遍历一个数组 [10, 20, 30, 40, 50],打印每个元素及其索引。 // 提示:用 .iter().enumerate() // 4. 用 for 循环配合 Range:打印 1..=5 的每个数的平方。 #[allow(dead_code)] fn ex6_loops() { // TODO: 在这里写你的代码 let mut sum = 0; let mut i = 1; let result = loop { sum += i; if i == 100 { break sum; }; i += 1; }; println!("sum: {}", result); let mut i = 10; while i > 0 { println!("倒数: {}", i); i -= 1; } let arr = [10, 20, 30, 40, 50]; for (i, item) in arr.iter().enumerate() { println!("index: {}, value: {}", i, item); } for i in 1..=5 { println!("{} 的平方是 {}", i, i * i); } } // ============================================================ // 练习7(综合):猜数字游戏简化版 // ============================================================ // 写一个函数 mini_guessing_game(),模拟一个简化的猜数字游戏: // - 设定一个固定的秘密数字(比如 42) // - 用一个数组 [10, 50, 35, 60, 42] 模拟玩家的猜数字序列 // - 遍历数组,对每次猜测判断: // - 猜小了 → 打印 "{} 太小了!" // - 猜大了 → 打印 "{} 太大了!" // - 猜对了 → 打印 "{} 猜对了!" 并退出循环 // 提示:for + if/else + break #[allow(dead_code)] fn mini_guessing_game() { // TODO: 在这里写你的代码 let secret_number = 62; let guesses: [i32; 5] = [10, 50, 35, 60, 42]; for (i, guess) in guesses.iter().enumerate() { if guess < &secret_number { println!("第{}次猜测,{} 太小了!", i + 1, guess); } else if guess > &secret_number { println!("第{}次猜测,{} 太大了!", i + 1, guess); } else { println!("第{}次猜测,{} 猜对了!", i + 1, guess); break; }; } } // ============================================================ // 练习8(综合):统计字符串中的字母 // ============================================================ // 写一个函数 count_letters(s: &str) -> (u32, u32),接收一个字符串切片, // 统计其中大写字母和小写字母的数量,以元组形式返回。 // - 提示1:用 .chars() 获取字符迭代器 // - 提示2:用 char::is_uppercase() 和 char::is_lowercase() 判断 // - 提示3:在 ex8_stats 中调用这个函数,用两个不同的字符串测试 #[allow(dead_code)] fn count_letters(s: &str) -> (u32, u32) { // TODO let chars = s.chars(); let tup: (u32, u32) = (0, 0); let (mut upper, mut lower) = tup; for c in chars { if c.is_uppercase() { upper += 1; } else if c.is_lowercase() { lower += 1; } } (upper, lower) } fn ex8_stats() { // 在这里测试 count_letters let (upper, lower) = count_letters("Hello, World!"); println!("大写字母数量:{},小写字母数量:{}", upper, lower); }