当前位置: 首页 > article >正文

C# 零基础到精通教程 - 第五章:数组——批量管理同一类型的数据

5.1 为什么需要数组5.1.1 没有数组的困境csharp// 如果要存储5个学生的成绩没有数组的话 int score1 85; int score2 92; int score3 78; int score4 90; int score5 88; // 如果要计算平均分 double average (score1 score2 score3 score4 score5) / 5.0; // 如果要找出最高分 int max score1; if (score2 max) max score2; if (score3 max) max score3; if (score4 max) max score4; if (score5 max) max score5; // 问题 // 1. 如果有100个学生代码会非常冗长 // 2. 无法用循环来处理 // 3. 代码难以维护5.1.2 有数组的解决方案csharp// 用数组存储5个学生的成绩 int[] scores { 85, 92, 78, 90, 88 }; // 用循环计算平均分 int sum 0; for (int i 0; i scores.Length; i) { sum scores[i]; } double average (double)sum / scores.Length; // 用循环找出最高分 int max scores[0]; for (int i 1; i scores.Length; i) { if (scores[i] max) max scores[i]; }5.1.3 数组的本质数组 一组相同类型的数据的有序集合text内存示意图 scores 数组 ┌─────┬─────┬─────┬─────┬─────┐ │ 85 │ 92 │ 78 │ 90 │ 88 │ └─────┴─────┴─────┴─────┴─────┘ 索引: 0 1 2 3 4 特点 1. 所有元素类型相同都是 int 2. 在内存中连续存储 3. 通过索引下标访问元素 4. 索引从 0 开始到 Length-1 结束5.2 数组的声明和创建5.2.1 声明数组变量csharp// 语法类型[] 数组名; int[] scores; // 声明一个 int 类型的数组名字叫 scores string[] names; // 声明一个 string 类型的数组 double[] prices; // 声明一个 double 类型的数组 bool[] flags; // 声明一个 bool 类型的数组注意声明数组时[]放在类型后面不是变量名后面。csharpint[] arr1; // ✅ 正确 int arr2[]; // ❌ 错误这是 C/C 的写法5.2.2 创建数组分配内存声明只是告诉编译器我要一个数组但还没有实际分配内存。创建才是真正在内存中开辟空间。csharp// 语法数组名 new 类型[长度]; int[] scores; // 声明 scores new int[5]; // 创建可以存放 5 个 int 的数组 // 声明 创建 合并写法 int[] scores new int[5];5.2.3 创建时的默认值csharpint[] intArray new int[5]; // intArray 中的元素默认值都是 0 string[] stringArray new string[5]; // stringArray 中的元素默认值都是 null bool[] boolArray new bool[5]; // boolArray 中的元素默认值都是 false double[] doubleArray new double[5]; // doubleArray 中的元素默认值都是 0.0 // 输出验证 int[] nums new int[3]; Console.WriteLine(nums[0]); // 输出0 Console.WriteLine(nums[1]); // 输出0 Console.WriteLine(nums[2]); // 输出05.2.4 数组的初始化赋初值csharp// 方式1创建时逐个赋值 int[] scores new int[5]; scores[0] 85; scores[1] 92; scores[2] 78; scores[3] 90; scores[4] 88; // 方式2创建时直接初始化最常用 int[] scores new int[] { 85, 92, 78, 90, 88 }; // 方式3简化写法C# 的语法糖 int[] scores { 85, 92, 78, 90, 88 }; // 方式4指定长度并初始化 int[] scores new int[5] { 85, 92, 78, 90, 88 };5.3 访问数组元素5.3.1 通过索引访问数组元素通过索引下标访问索引从 0 开始csharpint[] scores { 85, 92, 78, 90, 88 }; // 读取元素 int firstScore scores[0]; // 85 int secondScore scores[1]; // 92 int thirdScore scores[2]; // 78 int lastScore scores[4]; // 88 // 修改元素 scores[0] 100; // 把第一个元素改成 100 scores[2] 85; // 把第三个元素改成 85 // 输出所有元素 Console.WriteLine(scores[0]); Console.WriteLine(scores[1]); Console.WriteLine(scores[2]); Console.WriteLine(scores[3]); Console.WriteLine(scores[4]);5.3.2 数组长度——Length 属性csharpint[] scores { 85, 92, 78, 90, 88 }; int length scores.Length; // 5 Console.WriteLine($数组长度{length}); // 最后一个元素的索引是 Length - 1 int lastValue scores[scores.Length - 1]; // 885.3.3 索引越界错误常见错误csharpint[] scores new int[5]; // 有效索引0, 1, 2, 3, 4 scores[5] 100; // ❌ 错误索引 5 超出范围 scores[-1] 100; // ❌ 错误索引不能为负数 // 运行时会抛出 IndexOutOfRangeException如何避免越界csharpint[] scores { 85, 92, 78, 90, 88 }; for (int i 0; i scores.Length; i) // 使用 Length 控制范围 { Console.WriteLine(scores[i]); }5.4 遍历数组5.4.1 使用 for 循环遍历csharpint[] scores { 85, 92, 78, 90, 88 }; // 正向遍历 for (int i 0; i scores.Length; i) { Console.WriteLine($scores[{i}] {scores[i]}); } // 反向遍历 for (int i scores.Length - 1; i 0; i--) { Console.WriteLine($scores[{i}] {scores[i]}); }5.4.2 使用 foreach 遍历更简洁csharpint[] scores { 85, 92, 78, 90, 88 }; // foreach 语法foreach (类型 变量名 in 数组名) foreach (int score in scores) { Console.WriteLine(score); } // 特点 // 1. 不需要索引 // 2. 不能修改数组元素只读 // 3. 代码更简洁for vs foreach 对比特点forforeach需要索引是否可以修改元素是否只能读取可以反向遍历是否可以跳步遍历是i2否代码简洁度较繁琐简洁性能略快略慢可忽略csharp// for 可以修改元素 for (int i 0; i scores.Length; i) { scores[i] 10; // 每个成绩加10分 ✅ } // foreach 不能修改 foreach (int score in scores) { score 10; // ❌ 编译错误不能修改 }5.4.3 数组遍历的常见操作csharpint[] scores { 85, 92, 78, 90, 88 }; // 1. 求和 int sum 0; for (int i 0; i scores.Length; i) { sum scores[i]; } Console.WriteLine($总分{sum}); // 2. 求平均值 double average (double)sum / scores.Length; Console.WriteLine($平均分{average:F2}); // 3. 找最大值 int max scores[0]; for (int i 1; i scores.Length; i) { if (scores[i] max) max scores[i]; } Console.WriteLine($最高分{max}); // 4. 找最小值 int min scores[0]; for (int i 1; i scores.Length; i) { if (scores[i] min) min scores[i]; } Console.WriteLine($最低分{min}); // 5. 统计满足条件的个数及格人数 int passCount 0; foreach (int score in scores) { if (score 60) passCount; } Console.WriteLine($及格人数{passCount});5.5 数组的更多操作5.5.1 数组的复制csharpint[] source { 1, 2, 3, 4, 5 }; // 方法1手动复制 int[] target1 new int[source.Length]; for (int i 0; i source.Length; i) { target1[i] source[i]; } // 方法2CopyTo 方法 int[] target2 new int[source.Length]; source.CopyTo(target2, 0); // 从索引0开始复制 // 方法3Array.Copy 方法 int[] target3 new int[source.Length]; Array.Copy(source, target3, source.Length); // 方法4Clone 方法 int[] target4 (int[])source.Clone(); // 方法5LINQ需要 using System.Linq int[] target5 source.ToArray();5.5.2 数组的排序csharpint[] numbers { 5, 2, 8, 1, 9, 3 }; // 升序排序 Array.Sort(numbers); // 结果{ 1, 2, 3, 5, 8, 9 } // 降序排序先升序再反转 Array.Sort(numbers); Array.Reverse(numbers); // 结果{ 9, 8, 5, 3, 2, 1 } // 字符串排序按字母顺序 string[] names { 张三, 李四, 王五, 赵六 }; Array.Sort(names); // 结果{ 张三, 李四, 王五, 赵六 }按拼音/Unicode顺序5.5.3 数组的查找csharpint[] numbers { 10, 20, 30, 40, 50 }; // IndexOf查找元素第一次出现的位置 int index Array.IndexOf(numbers, 30); // 2 int notFound Array.IndexOf(numbers, 99); // -1未找到 // LastIndexOf查找元素最后一次出现的位置 int[] numbers2 { 10, 20, 30, 20, 40 }; int lastIndex Array.LastIndexOf(numbers2, 20); // 3 // BinarySearch二分查找前提数组已排序 Array.Sort(numbers); int searchIndex Array.BinarySearch(numbers, 30); // 25.5.4 数组的清空和重置csharpint[] numbers { 1, 2, 3, 4, 5 }; // Clear将指定范围的元素设为默认值 Array.Clear(numbers, 0, numbers.Length); // numbers 变成 { 0, 0, 0, 0, 0 } // 只清除部分 int[] numbers2 { 1, 2, 3, 4, 5 }; Array.Clear(numbers2, 1, 3); // 结果{ 1, 0, 0, 0, 5 }5.5.5 数组的扩容数组一旦创建长度不能改变。如果需要更大的数组只能创建新数组并复制。csharpint[] scores { 85, 92, 78 }; Console.WriteLine($原数组长度{scores.Length}); // 3 // 需要添加第4个元素但数组长度固定 // 解决方法创建新数组 int[] newScores new int[scores.Length 1]; // 复制原数组元素 for (int i 0; i scores.Length; i) { newScores[i] scores[i]; } // 添加新元素 newScores[newScores.Length - 1] 90; // 重新指向新数组 scores newScores; Console.WriteLine($新数组长度{scores.Length}); // 4 Console.WriteLine($新数组{string.Join(, , scores)}); // 85, 92, 78, 90实际开发中如果频繁需要扩容建议使用 ListT第九章会讲。5.6 多维数组5.6.1 二维数组表格数据二维数组可以看作是一个表格有行和列csharp// 声明和创建 // 语法类型[,] 数组名 new 类型[行数, 列数]; // 创建一个 3 行 4 列的二维数组 int[,] matrix new int[3, 4]; // 访问元素 matrix[0, 0] 1; // 第1行第1列 matrix[0, 1] 2; // 第1行第2列 matrix[1, 0] 3; // 第2行第1列 matrix[2, 3] 4; // 第3行第4列 // 初始化方式1 int[,] matrix2 new int[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; // 初始化方式2简化 int[,] matrix3 { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };5.6.2 遍历二维数组csharpint[,] scores { { 85, 90, 88 }, // 学生0的成绩语文、数学、英语 { 92, 86, 94 }, // 学生1的成绩 { 78, 88, 80 }, // 学生2的成绩 { 95, 92, 91 } // 学生3的成绩 }; // 获取维度长度 int rows scores.GetLength(0); // 行数4 int cols scores.GetLength(1); // 列数3 // 使用嵌套 for 循环遍历 for (int i 0; i rows; i) { Console.Write($学生{i}的成绩); for (int j 0; j cols; j) { Console.Write(${scores[i, j]} ); } Console.WriteLine(); } // 使用 foreach 遍历会按行优先顺序输出所有元素 foreach (int score in scores) { Console.Write(${score} ); }5.6.3 二维数组的实际应用csharp// 应用1学生成绩统计 int[,] studentScores { { 85, 90, 88 }, // 语文、数学、英语 { 92, 86, 94 }, { 78, 88, 80 }, { 95, 92, 91 } }; string[] subjects { 语文, 数学, 英语 }; // 计算每个学生的总分和平均分 for (int i 0; i studentScores.GetLength(0); i) { int sum 0; for (int j 0; j studentScores.GetLength(1); j) { sum studentScores[i, j]; } double avg (double)sum / studentScores.GetLength(1); Console.WriteLine($学生{i}总分{sum}平均分{avg:F2}); } Console.WriteLine(); // 计算每门课的平均分 for (int j 0; j studentScores.GetLength(1); j) { int sum 0; for (int i 0; i studentScores.GetLength(0); i) { sum studentScores[i, j]; } double avg (double)sum / studentScores.GetLength(0); Console.WriteLine(${subjects[j]}平均分{avg:F2}); }csharp// 应用2矩阵乘法 int[,] A { { 1, 2 }, { 3, 4 } }; int[,] B { { 2, 0 }, { 1, 2 } }; int[,] C new int[2, 2]; // 矩阵乘法C A × B for (int i 0; i 2; i) { for (int j 0; j 2; j) { for (int k 0; k 2; k) { C[i, j] A[i, k] * B[k, j]; } } } // 输出结果 Console.WriteLine(矩阵乘法结果); for (int i 0; i 2; i) { for (int j 0; j 2; j) { Console.Write(${C[i, j]} ); } Console.WriteLine(); }5.6.4 多维数组三维及以上csharp// 三维数组立体数据 int[,,] cube new int[2, 3, 4]; // 2层3行4列 // 初始化 int[,,] cube2 { { // 第0层 { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }, { // 第1层 { 13, 14, 15, 16 }, { 17, 18, 19, 20 }, { 21, 22, 23, 24 } } }; // 访问 int value cube2[1, 2, 3]; // 第2层第3行第4列 245.7 锯齿数组数组的数组锯齿数组是数组的数组每个子数组的长度可以不同csharp// 锯齿数组 vs 二维数组 // 二维数组矩形每一行长度相同 int[,] rectangular new int[3, 4]; // 3行4列每行都是4列 // 锯齿数组每行可以有不同的长度 int[][] jagged new int[3][]; // 声明有3行的锯齿数组 // 为每一行创建不同长度的数组 jagged[0] new int[3]; // 第1行有3个元素 jagged[1] new int[5]; // 第2行有5个元素 jagged[2] new int[2]; // 第3行有2个元素 // 初始化锯齿数组 int[][] jagged2 new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5 }, new int[] { 6, 7, 8, 9 } }; // 简化写法 int[][] jagged3 { new int[] { 1, 2, 3 }, new int[] { 4, 5 }, new int[] { 6, 7, 8, 9 } }; // 遍历锯齿数组 for (int i 0; i jagged3.Length; i) { Console.Write($第{i}行长度{jagged3[i].Length}); for (int j 0; j jagged3[i].Length; j) { Console.Write(${jagged3[i][j]} ); } Console.WriteLine(); }5.8 数组与方法的交互5.8.1 数组作为方法参数csharp// 计算数组的平均值 double CalculateAverage(int[] numbers) { if (numbers null || numbers.Length 0) return 0; int sum 0; foreach (int num in numbers) { sum num; } return (double)sum / numbers.Length; } // 使用 int[] scores { 85, 92, 78, 90, 88 }; double avg CalculateAverage(scores); Console.WriteLine($平均分{avg});5.8.2 方法返回数组csharp// 生成一个指定长度的随机数组 int[] GenerateRandomArray(int length, int minValue, int maxValue) { Random random new Random(); int[] array new int[length]; for (int i 0; i length; i) { array[i] random.Next(minValue, maxValue); } return array; } // 使用 int[] randomNumbers GenerateRandomArray(10, 1, 100); Console.WriteLine($随机数组{string.Join(, , randomNumbers)});5.8.3 数组参数传递的特性数组是引用类型传递的是引用地址所以方法内修改会影响原数组csharpvoid AddTenToEach(int[] numbers) { for (int i 0; i numbers.Length; i) { numbers[i] 10; // 修改会影响原数组 } } int[] scores { 85, 92, 78 }; AddTenToEach(scores); Console.WriteLine(string.Join(, , scores)); // 95, 102, 885.9 params 关键字可变参数params 允许方法接受可变数量的参数自动打包成数组csharp// 定义一个可以接受任意数量整数的方法 int Sum(params int[] numbers) { int sum 0; foreach (int num in numbers) { sum num; } return sum; } // 使用方式 int result1 Sum(1, 2, 3); // 6 int result2 Sum(10, 20); // 30 int result3 Sum(1, 2, 3, 4, 5); // 15 int result4 Sum(); // 0可以传0个参数 // 也可以直接传数组 int[] arr { 1, 2, 3 }; int result5 Sum(arr); // 6 Console.WriteLine($Sum(1,2,3) {result1}); Console.WriteLine($Sum(10,20) {result2}); Console.WriteLine($Sum(1,2,3,4,5) {result3});params 的限制一个方法只能有一个params参数params参数必须是方法的最后一个参数csharp// ✅ 正确params 在最后 void Print(string title, params int[] numbers) { Console.Write(title : ); foreach (int n in numbers) Console.Write(n ); Console.WriteLine(); } // 使用 Print(成绩, 85, 92, 78, 90, 88); // 输出成绩: 85 92 78 90 885.10 综合示例示例1学生成绩管理系统csharpusing System; class Program { static void Main() { Console.WriteLine( 学生成绩管理系统 ); Console.Write(请输入学生人数); int studentCount Convert.ToInt32(Console.ReadLine()); string[] names new string[studentCount]; int[] scores new int[studentCount]; // 输入学生信息 for (int i 0; i studentCount; i) { Console.WriteLine($\n第{i 1}个学生); Console.Write( 姓名); names[i] Console.ReadLine(); Console.Write( 成绩); scores[i] Convert.ToInt32(Console.ReadLine()); } // 统计 int sum 0, max scores[0], min scores[0]; int maxIndex 0, minIndex 0; int passCount 0, failCount 0; for (int i 0; i studentCount; i) { sum scores[i]; if (scores[i] max) { max scores[i]; maxIndex i; } if (scores[i] min) { min scores[i]; minIndex i; } if (scores[i] 60) passCount; else failCount; } double average (double)sum / studentCount; // 排序按成绩降序 Array.Sort(scores, names); Array.Reverse(scores); Array.Reverse(names); // 输出结果 Console.WriteLine(\n 统计结果 ); Console.WriteLine($总人数{studentCount}); Console.WriteLine($总分{sum}); Console.WriteLine($平均分{average:F2}); Console.WriteLine($最高分{max}{names[maxIndex]}); Console.WriteLine($最低分{min}{names[minIndex]}); Console.WriteLine($及格人数{passCount}及格率{(double)passCount / studentCount * 100:F1}%); Console.WriteLine($不及格人数{failCount}不及格率{(double)failCount / studentCount * 100:F1}%); // 成绩排名 Console.WriteLine(\n 成绩排名从高到低); for (int i 0; i studentCount; i) { Console.WriteLine(${i 1}. {names[i]}{scores[i]}分); } } }示例2冒泡排序理解排序原理csharpusing System; class Program { static void Main() { int[] numbers { 64, 34, 25, 12, 22, 11, 90 }; Console.WriteLine(原始数组 string.Join(, , numbers)); BubbleSort(numbers); Console.WriteLine(排序后 string.Join(, , numbers)); } static void BubbleSort(int[] arr) { int n arr.Length; for (int i 0; i n - 1; i) { // 每轮把最大的元素冒泡到最后 for (int j 0; j n - i - 1; j) { if (arr[j] arr[j 1]) { // 交换两个元素 int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } // 打印每一轮的结果 Console.WriteLine($第{i 1}轮{string.Join(, , arr)}); } } } // 输出 // 原始数组64, 34, 25, 12, 22, 11, 90 // 第1轮34, 25, 12, 22, 11, 64, 90 // 第2轮25, 12, 22, 11, 34, 64, 90 // 第3轮12, 22, 11, 25, 34, 64, 90 // 第4轮12, 11, 22, 25, 34, 64, 90 // 第5轮11, 12, 22, 25, 34, 64, 90 // 第6轮11, 12, 22, 25, 34, 64, 90 // 排序后11, 12, 22, 25, 34, 64, 90示例3约瑟夫环问题经典数组应用csharpusing System; class Program { static void Main() { // 约瑟夫环n个人围成一圈每数到m的人出局求最后剩下的人 Console.Write(请输入总人数); int n Convert.ToInt32(Console.ReadLine()); Console.Write(请输入步长每数到几出局); int m Convert.ToInt32(Console.ReadLine()); // 创建数组true表示还在圈中 bool[] people new bool[n]; for (int i 0; i n; i) { people[i] true; } int remainCount n; // 剩余人数 int currentIndex -1; // 当前位置 int count 0; // 计数器 Console.Write(\n出局顺序); while (remainCount 1) { count 0; // 数m个人 while (count m) { currentIndex (currentIndex 1) % n; if (people[currentIndex]) { count; } } // 当前数到的人出局 people[currentIndex] false; Console.Write(${(currentIndex 1)} ); remainCount--; } // 找出最后剩下的人 for (int i 0; i n; i) { if (people[i]) { Console.WriteLine($\n最后剩下的人编号{i 1}); break; } } } }5.11 常见错误与陷阱错误1数组索引越界csharpint[] arr new int[5]; arr[5] 10; // ❌ 索引 5 超出范围有效是 0-4 arr[-1] 10; // ❌ 索引不能为负数错误2数组未初始化就使用csharpint[] arr; Console.WriteLine(arr[0]); // ❌ 编译错误使用了未赋值的局部变量错误3混淆 Length 和 Length()csharpint[] arr { 1, 2, 3 }; int len arr.Length; // ✅ 属性不是方法 int len2 arr.Length(); // ❌ 错误不能当方法用错误4foreach 中修改元素csharpint[] scores { 85, 92, 78 }; foreach (int score in scores) { score 10; // ❌ 编译错误不能修改 foreach 变量 } // ✅ 改用 for for (int i 0; i scores.Length; i) { scores[i] 10; }错误5数组比较的错误方式csharpint[] arr1 { 1, 2, 3 }; int[] arr2 { 1, 2, 3 }; if (arr1 arr2) // 比较的是引用不是内容 { Console.WriteLine(相等); // 不会输出 } // 正确方式使用 SequenceEqual if (arr1.SequenceEqual(arr2)) { Console.WriteLine(相等); // 输出 }错误6多维数组索引语法错误csharpint[,] matrix new int[3, 4]; matrix[1, 2] 10; // ✅ 正确 matrix[1][2] 10; // ❌ 错误这是锯齿数组的语法5.12 本章总结核心知识点导图text数组 ├── 一维数组 │ ├── 声明int[] arr; │ ├── 创建new int[5]; │ ├── 初始化{1,2,3,4,5} │ ├── 访问arr[0] │ ├── 遍历for / foreach │ └── 属性Length │ ├── 二维数组 │ ├── 声明int[,] arr; │ ├── 创建new int[3,4]; │ ├── 访问arr[0,1] │ └── 维度GetLength(0), GetLength(1) │ ├── 锯齿数组 │ ├── 声明int[][] arr; │ ├── 创建new int[3][]; │ └── 特点子数组长度可不同 │ └── 常用操作 ├── Sort排序 ├── IndexOf查找 ├── Copy复制 ├── Clear清空 └── Reverse反转数组 vs 普通变量特点普通变量数组存储数据量1个多个命名方式每个变量独立命名一个名字 索引访问方式变量名变量名[索引]循环处理不能可以内存位置可能不连续连续存储5.13 练习题基础题声明一个包含10个整数的数组用循环给每个元素赋值为索引的平方0,1,4,9...然后输出所有元素。从键盘输入5个整数存入数组输出数组的最大值、最小值、总和、平均值。创建一个包含10个随机数1-100的数组输出所有大于50的数。写一个方法接收一个整数数组返回数组中所有元素的乘积。应用题数组去重给定一个数组{1, 2, 3, 2, 4, 3, 5, 1, 6}输出去

相关文章:

C# 零基础到精通教程 - 第五章:数组——批量管理同一类型的数据

5.1 为什么需要数组?5.1.1 没有数组的困境csharp// 如果要存储5个学生的成绩,没有数组的话: int score1 85; int score2 92; int score3 78; int score4 90; int score5 88;// 如果要计算平均分: double average (score1 s…...

深入解析RoboMaster电机数据包:从CAN原始字节到速度、角度、电流的转换全流程

深入解析RoboMaster电机数据包:从CAN原始字节到速度、角度、电流的转换全流程 在机器人竞赛和工业控制领域,CAN总线通信因其高可靠性和实时性成为电机控制的黄金标准。大疆RoboMaster系列电机通过CAN协议传递的8字节数据包,就像一串精心设计的…...

在MMDetection 3.x中手把手复现EfficientDet的BiFPN模块(附代码逐行解读)

在MMDetection 3.x中手把手复现EfficientDet的BiFPN模块(附代码逐行解读) 当目标检测任务遇到多尺度物体时,传统特征金字塔网络(FPN)往往力不从心。EfficientDet提出的BiFPN(加权双向特征金字塔网络&#x…...

告别手动配置!用Matlab+LUA脚本自动化DCA1000雷达数据采集(附1843配置实例)

雷达数据采集自动化:Matlab与LUA脚本的高效协作方案 在毫米波雷达研发领域,数据采集是每个工程师日常工作中不可或缺的环节。传统的手动配置方式不仅耗时耗力,还容易因人为操作失误导致数据质量不稳定。本文将介绍如何通过Matlab与LUA脚本的协…...

OpenAI Codex 安装部署指南:从零到跑通,2026最新版

⏱️ 阅读时间:8分钟 | 📌 难度:入门级 | 🔧 适用系统:macOS / Linux / Windows(WSL2) 前言 距离上次写 Codex 测评已经有一段时间了,这期间 Codex 又经历了好几轮大更新:Computer Use 能力、内…...

手语数字人技术详解:3D 动画生成、动作自然度优化与实时渲染工程实践

一、前言:手语数字人是 AI 手语翻译的 “最后一公里”在国家信息无障碍政策推动下,AI 手语翻译已从技术实验走向大规模落地。但手语不是文字替换,而是身体动作、手部姿态、面部表情、口型同步的综合表达。传统手语生成普遍存在三大问题&#…...

手把手教你用C#搞定海康机器人扫码枪的TCP通信(附完整Socket代码)

工业级条码采集实战:C#与海康扫码枪的TCP通信深度解析 在自动化仓储和智能制造场景中,海康威视工业扫码枪凭借其卓越的解码性能和稳定的通信机制,已成为产线数据采集的首选设备之一。不同于消费级扫码器的即插即用特性,工业级设备…...

C# 零基础到精通教程 - 第六章:方法——让代码“模块化“

6.1 为什么需要方法?6.1.1 没有方法的问题csharp// 没有方法:代码重复、臃肿、难以维护 static void Main() {// 第一次计算两个数的和int a1 10, b1 20;int sum1 a1 b1;Console.WriteLine($"{a1} {b1} {sum1}");// 第二次计算两个数的和…...

单词拆分----dp

思路:刚开始看的时候没有思路,但我看给的样例,可以多次遍历wordDict看。。。好像不太对准备看看题解。首先需要知道这道题的dp的公式代表这什么,dp[i]表示 字符串s从起始位置到位置i,能否被被拆分成字典中的单词&#…...

Jetson Nano避坑指南:从CUDA到YOLOv5,我踩过的那些坑和最终解决方案

Jetson Nano深度排雷手册:CUDA到YOLOv5实战问题全解析 当这块信用卡大小的开发板第一次出现在我的工作台上时,我完全没预料到接下来两周会经历怎样的"技术炼狱"。从CUDA环境变量配置的幽灵报错,到PyTorch的非法指令崩溃&#xff0c…...

Datasheet学习4(Audio)(TODO)

(TODO)...

SaySo 语音识别相关技术解析,从语音输入到可用文本

摘要语音识别正在从一个独立功能,变成越来越多桌面应用里的基础交互能力。对于 SaySo 这类 PC 端语音工具来说,语音识别不仅仅是把声音转成文字,更关键的是如何在桌面工作流中做到识别准确、响应及时、体验稳定。本文将围绕 SaySo 的语音识别…...

我的Type-C串口板又烧了?一个CH340N电路设计中的隐藏坑点与补救方案

我的Type-C串口板又烧了?CH340N电路设计中的隐藏坑点与补救方案 最近在调试一块自制的Type-C转串口板时,连续烧毁了三片CH340N芯片。每次都是刚插上Type-C线缆时工作正常,但一旦给目标板供电,CH340N就会莫名其妙地停止响应&#x…...

STM32F030硬件I2C避坑指南:Timing值、滤波器配置与NBYTES重加载模式详解

STM32F030硬件I2C避坑指南:Timing值、滤波器配置与NBYTES重加载模式详解 1. 深入理解I2C_Timing寄存器的计算逻辑 许多开发者在使用STM32F030硬件I2C时,往往直接套用CubeMX生成的默认值或网络上的示例代码,却对I2C_Timing寄存器的底层计算原理…...

告别黑框!树莓派4B远程桌面完整指南:从VNC配置到RealVNC/XRDP方案选择与优化

树莓派4B远程桌面终极方案:告别黑框与卡顿的实战指南 对于许多树莓派开发者而言,那个令人沮丧的黑色方框已经成为远程连接体验的代名词。当你满怀期待地输入IP地址,等待的却是一个无法操作的空白界面,这种挫败感足以让任何人抓狂。…...

手持式雷达车辆测速仪:基于多普勒效应的移动测速工具

手持式雷达车辆测速仪是一种基于多普勒效应原理的速度测量设备。它通过向目标发射24GHz无线电波,接收反射回来的信号,根据频率变化计算出目标的运动速度。设备重量约504g,内置3600mAh电池,续航可达10小时以上,支持手持…...

优惠电影票API接口,7折电影起步

请求参数说明store_idint是1店铺idshowIdstring是没下划线那个showid场次ID返回参数说明codestring00000000代表成功msgstring获取成功获取成功timestring1639640142时间戳dataobject[]infoobject[]影片信息idstring2film_idstring...

减 10 斤 vs 瘦 10 斤,别再被体重秤骗了!

外行看体重,内行看体脂。 减重 10 斤,你掉的可能只是水分、肌肉、肠道废物,身材看着没变化。 瘦 10 斤(减脂),才是真正减掉脂肪组织,身材会明显小一圈,腰围、腿围肉眼可见地缩小。 这…...

Rerank:为什么它是 RAG 效果的分水岭?

在一个典型 RAG 流程中: 很多 Demo 系统会省略中间这一步: 直接把 Top-K 丢给模型 看起来能跑,但一旦进入真实场景,很快就会出现: 命中了,但排在后面噪声太多,污染上下文模型“理解错重点” 本…...

Android 开发问题:TextView 内容超过宽度时,默认不会换行

在 Android 开发&#xff0c;TextView 内容超过宽度时&#xff0c;默认不会换行&#xff0c;如下例 <TextViewandroid:layout_width"200dp"android:layout_height"wrap_content"android:text"这是一段很长的文本&#xff0c;这是一段很长的文本&am…...

全息三维空间孪生,全域无感精准智位系列:UWB:多路径干扰精度失稳|镜像:多源时空误差融合

在全域空间数字化、实景虚实融合与空间智能快速演进的产业周期中&#xff0c;镜像视界&#xff08;浙江&#xff09;科技有限公司持续深耕视频原生三维重构、时空AI像素解算、全域无感精准定位、跨镜轨迹智能推演底层核心领域&#xff0c;依托八大自主可控核心引擎构筑全栈技术…...

搞懂专业代剪辑,才能看懂好视频背后的逻辑

为什么你拍的素材总剪不出‘电影感’&#xff1f; 你是否也经历过这样的困扰&#xff1a;婚礼当天拍了上百G的高清素材&#xff0c;回家却剪不出那支朋友圈点赞破百的高光快剪&#xff1b;或是为新品拍摄了完整开箱视频&#xff0c;上传后播放量寥寥&#xff1f;问题往往不在拍…...

全息三维空间孪生,全域无感精准智位:数字孪生·视频孪生·无感定位 行业地位核心优势

在全域空间数字化、实景虚实融合与空间智能快速演进的产业周期中&#xff0c;镜像视界&#xff08;浙江&#xff09;科技有限公司持续深耕视频原生三维重构、时空AI像素解算、全域无感精准定位、跨镜轨迹智能推演底层核心领域&#xff0c;依托八大自主可控核心引擎构筑全栈技术…...

告别手动描图!用AutoCAD Civil 3D 2024快速搞定两期土方横断面对比(附模板)

告别手动描图&#xff01;用AutoCAD Civil 3D 2024快速搞定两期土方横断面对比&#xff08;附模板&#xff09; 在土木工程领域&#xff0c;土方量计算是项目成本控制与进度管理的关键环节。传统CAD手动绘制横断面的方式不仅耗时费力&#xff0c;更难以应对设计变更带来的反复修…...

Linux内核安全模块深入剖析【1.9】

7.3.1 基本定义1.客体类别和操作这部分策略是内核代码逻辑的重复。按照机制和策略分离的原则&#xff0c;内核代码实现机制&#xff0c;用户编写策略。但是 SELinux 策略语言中偏偏有一部分是在重复内核代码的逻辑。这部分重新定义了客体类别和操作&#xff0c;有些不伦不类&am…...

SPEC CPU 2017基准测试深度解析:从原理到实战调优

1. 项目概述&#xff1a;一次性能基准测试的巅峰对决最近在服务器和芯片圈子里&#xff0c;一个消息炸开了锅&#xff1a;曙光服务器在SPEC CPU 2017基准测试中&#xff0c;一口气刷新了四项世界纪录。对于圈外人来说&#xff0c;这可能只是一条普通的科技新闻&#xff0c;但对…...

通过curl命令快速测试Taotoken API为大赛创意生成提供灵感

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 通过curl命令快速测试Taotoken API为大赛创意生成提供灵感 对于赛事组织者而言&#xff0c;快速验证技术方案、获取创意灵感是日常…...

(最新版)GitGitHub实操图文详解教程(10)—SSH

版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 1. 应用场景 前面几课已经完成了本地Git基础操作:先通过git init初始化仓库,再用git status查看状态,用git add把修改加入暂存区,用git commit创建本地提交,最后用git log查看提交历史。到…...

Python+AI智能体(Agent)零基础入门全攻略:原理、架构、手搓代码与实战落地

PythonAI智能体(Agent)零基础入门全攻略&#xff1a;原理、架构、手搓代码与实战落地 文章目录&#xff1a; 【前言】 一、前言&#xff1a;为什么现在必须学PythonAI Agent智能体二、核心概念&#xff1a;彻底搞懂什么是AI Agent智能体 2.1 官方工程定义2.2 普通大模型LLM V…...

(最新版)GitGitHub实操图文详解教程(09)—git log命令

版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 1. 应用场景 git log用于查看项目的提交历史。前面我们已经学习了git add和git commit,其中git commit会将暂存区中的内容保存为一次正式提交。随着项目不断开发,本地仓库中会逐渐产生多次提交…...