C#入门学习记录(三)C#中的隐式和显示转换

news2025/3/25 5:17:11

C#类型转换:隐式与显式转换的机制与应用

        在C#的强类型体系中,数据类型转换是实现数据交互和算法逻辑的基础操作。当数值类型范围存在包含关系,或对象类型存在继承层次时,系统通过预定义的转换规则实现类型兼容处理。隐式转换(Implicit Conversion)与显式转换(Explicit Conversion)构成了C#类型安全体系的核心机制,二者在编译器行为、数据安全性以及使用场景上存在本质差异。理解其工作原理对避免运行时异常、优化内存使用以及设计健壮的类型系统至关重要。

隐式转换:

        以下是在C#中的一些系统提供的可以直接进行隐式转换的情况:

一、数值类型隐式转换(Numeric Promotions)

        原则是要求数值隐式转换遵循精度不丢失。

// 整型提升
sbyte  a = 100;     short  b = a;    // sbyte → short
short  c = 200;     int    d = c;    // short → int
int    e = 300;     long   f = e;    // int → long

// 浮点提升
float  g = 3.14f;   double h = g;    // float → double

// 混合提升
decimal i = 123.45m; double j = (double)i; // 需要显式转换(decimal→double无隐式)

转换路径
sbyte → short → int → long → float → double
byte → short → ushort → int → uint → long → ulong → float → double
char → ushort → int → uint → long → ulong → float → double

Tips:大的数据范围装小的数据范围,浮点数装整型。

下面是各个类型的值的范围:

二、可空类型(Nullable)隐式转换

        什么是可空类型(Nullable Types)?

        在C#中,​可空类型允许值类型(如 intdoubleDateTime 等)表示为“有值”或“无值”(即 null)。这是为了解决值类型默认不能为 null 的限制,尤其在处理数据库字段、可选参数或未知数据时非常有用。就把值类型变成了一个引用类型。


为什么需要可空类型?
  1. 表示缺失值
    值类型(如 int)默认必须有值,无法直接表示“无数据”状态。例如,数据库中的某个数字字段可能允许为 NULL,此时需要用可空类型来映射这种场景。

  2. 避免魔数(Magic Numbers)​
    不再需要用特殊值(如 -1 或 int.MinValue)表示“无数据”,代码更清晰。

  3. 与数据库交互
    数据库中的 NULL 字段可以直接映射到C#的可空类型变量。

可空类型的语法:

1.利用结构体进行声明:

Nullable<int> number = null;

2.T? 简写形式

int? number = null;   // 等价于 Nullable<int>
double? price = 9.99;
bool? isActive = true;

可空类型的关键特性:

        1. 判断是否有值:HasValue 属性

这个函数返回的是一个bool值

int? age = 25;
if (age.HasValue)
{
    Console.WriteLine($"年龄是:{age.Value}"); // 输出:年龄是:25
}
else
{
    Console.WriteLine("年龄未填写");
}

        2. 安全获取值:GetValueOrDefault()

int? score = null;
int actualScore = score.GetValueOrDefault(); // 无值时返回默认值(0)
Console.WriteLine(actualScore); // 输出:0

int safeScore = score.GetValueOrDefault(60); // 指定默认值
Console.WriteLine(safeScore); // 输出:60

        3. 直接取值:Value 属性(需谨慎)

int? count = 10;
int total = count.Value; // 有值时正常获取

int? invalid = null;
int error = invalid.Value; // 抛出 InvalidOperationException

可空类型的转换与运算:

在C#的可空类型(Nullable<T>)运算中,​任何涉及 null 的算术操作都会导致结果为 null。这是由可空类型的特殊设计规则决定的,具体原理如下:


关键原因:可空类型的"空值传播"特性

当可空类型(如 int?)参与运算时:

  1. 操作数全为有效值 → 执行常规计算

  2. 任一操作数为 null → ​整个表达式结果自动为 null

1. 与非可空类型的转换

int? a = 10;
int b = 20;

int? sum = a + b;    // ✅ 结果为 30(int?)
int? invalid = a + null; // ✅ 结果为 null

2. 合并运算符 ??(提供默认值)

为空的话就返回??右边的值

int? nullableNumber = null;
int actualNumber = nullableNumber ?? 100; // 若为null,返回100

3. 条件访问 ?.

判空处理,如果不为空才会使用这个对象,一般是用于委托,事件

DateTime? birthDate = GetBirthDate();
int? year = birthDate?.Year; // 若birthDate为null,year也为null

好了扯了这么多该回归主线了!

所以int是可以隐式转换为空的,对应其他基础类型也可以这样

int? nullableInt = 42;        // int → int? 隐式
double? nullableDouble = nullableInt; // int? → double?(基础类型支持隐式转换)

三、常量表达式隐式转换

const int max = int.MaxValue;
long bigNumber = max;         // 编译时确定值不会溢出

byte magic = 255;            // 字面量255在byte范围内
// byte invalid = 256;       // 编译错误(超出范围)

        这里说明bigNumber可以装下int 类型的常量,还是和前面是一样的,大的数据类型可以直接装小的数据类型。

四、数组协变(Array Covariance)

        数组协变是C#中一种特殊的类型转换机制,允许将派生类的数组隐式转换为基类的数组。但是!请注意,只能将引用类型的数组转换为基类,而不能将值类型的数组转换,而且!不可逆转。其实还有个泛型协变,我们后面再聊。

        核心规则

​1、仅支持引用类型数组

// 值类型数组不支持协变
int[] ints = { 1, 2 };
// object[] objArr = ints; // ❌ 编译错误

2、协变方向不可逆

object[] objs = new object[2];
// string[] strs = objs; // ❌ 编译错误(逆变不允许)

3、 运行时类型不变

        这个是什么意思呢,我认为是只是换了个父类进行存储,但本身自己是什么还是不会改变。就像你是你老汉生的,但是你始终只是你!

Console.WriteLine(objects.GetType()); // 输出:System.String[]
string[] strings = { "a", "b" };
object[] objects = strings;   // string[] → object[] 隐式转换(协变)
// 仅支持引用类型数组

隐式转换示例:

string[] strings = { "a", "b" };
object[] objects = strings;   // string[] → object[] 隐式转换(协变)
// 仅支持引用类型数组

小结:

            //有符号 long->int->short->sbyte //大范围装小范围
            //无符号 ulong->uint->ushort->byte 同上

            //浮点数 decimal double float
            //decimal这个类型 没有办法用隐式转换的形式 去储存 double和float

            //特殊类型 bool char string
            //他们之间不存在隐式转换

            //1.无符号 不能够 装 有符号
            //有符号的变量不能隐式转换为无符号的变量
            //2.有符号的变量不能装范围和自己相等的或者大的变量 只能装比自己小(范围)的变量

            //3.浮点数可以装任意整数 包括decimal
            //double->float->所有整型
            //4.整数不能隐式装载浮点数

            //bool没有办法和其他类型 相互隐式转换

            //char 没有办法隐式存储 其他类型的变量

            // char 类型可以隐式转换成整型和浮点型(ASCII码)

            //string 无法和其它类型相互转换

显示转换:

大体上有三种方式进行转换

一、括号强制转换(显式类型转换)

        适用场景:已知类型兼容的转换
// 1. 数值类型收缩转换
double d = 3.1415;
int i = (int)d; // 结果为3(截断小数)

// 2. 引用类型向下转型
object obj = "Hello";
string str = (string)obj;

// 3. 可空类型转换
int? nullableInt = 42;
int normalInt = (int)nullableInt;

二、Parse系列方法 将字符串转换为整型

            //作用:把字符串类型 转换为对应的类型
            //语法:变量类型.Parse("字符串")
            //注意:转换的字符串必须是能够转换的

        一、基本数值类型 Parse 方法
1. ​整数类型
string intStr = "123";
int numInt = int.Parse(intStr); // 输出:123

string longStr = "9876543210";
long numLong = long.Parse(longStr);
2. ​浮点数类型
string floatStr = "3.14";
float numFloat = float.Parse(floatStr); // 输出:3.14

string doubleStr = "2.71828";
double numDouble = double.Parse(doubleStr);
3. ​十进制类型

decimal就是能够存数据存的很准确,28位呢

string decimalStr = "12345.67";
decimal numDecimal = decimal.Parse(decimalStr); // ✅ 精确存储为十进制数
Console.WriteLine(numDecimal); // 输出:12345.67(完全一致)
二、布尔类型 Parse
string trueStr = "True";
bool isTrue = bool.Parse(trueStr); // 输出:True

string falseStr = "False";
bool isFalse = bool.Parse(falseStr);
三、日期和时间
1. ​DateTime.Parse
string dateStr = "2025-3-01";
DateTime date = DateTime.Parse(dateStr); // 输出:2023/3/1 0:00:00
2. ​DateTimeOffset.Parse
string offsetStr = "2023-10-01T12:00:00+08:00";
DateTimeOffset offset = DateTimeOffset.Parse(offsetStr); // 带时区信息
四、枚举类型 Enum.Parse 
enum Color { Red, Green, Blue }

string colorStr = "Green";
Color color = (Color)Enum.Parse(typeof(Color), colorStr); // 输出:Color.Green

这里就比较麻烦,先记住吧

五、特殊类型 Parse 方法

1. ​Guid.Parse

string guidStr = "a0a0a0a0-1234-5678-9012-abcdefabcdef";
Guid guid = Guid.Parse(guidStr); // 转换为全局唯一标识符

2. ​TimeSpan.Parse

string timeSpanStr = "12:34:56";
TimeSpan duration = TimeSpan.Parse(timeSpanStr); // 输出:12小时34分56秒
六、其他 Parse 方法

1. ​IPAddress.Parse

string ipStr = "192.168.1.1";
IPAddress ip = IPAddress.Parse(ipStr); // 转换为IP地址对象

2. ​Version.Parse

string versionStr = "2.3.4.5";
Version ver = Version.Parse(versionStr); // 输出:主版本2,次版本3
七、Parse 方法的重载参数
// 标准格式:Parse(string)
int.Parse("123");

// 带格式控制:Parse(string, NumberStyles)
int.Parse("(123)", NumberStyles.AllowParentheses);
关键参数 NumberStyles:
//AllowLeadingWhite:允许前导空格
//AllowTrailingWhite:允许后置空格
//AllowParentheses:允许括号表示负数(如 (123))
//AllowThousands:允许千位分隔符(如 1,234)
//AllowCurrencySymbol:允许货币符号(如 $、¥)

// 允许括号表示负数
int negative = int.Parse("(123)", NumberStyles.AllowParentheses); // 输出:-123

// 允许千位分隔符
int bigNumber = int.Parse("1,234", NumberStyles.AllowThousands); // 输出:1234

// 组合多个格式
decimal money = decimal.Parse("$1,234.56", 
    NumberStyles.AllowCurrencySymbol | NumberStyles.AllowThousands);
// 带格式和文化信息:Parse(string, NumberStyles, IFormatProvider)
double.Parse("$1,234.56", NumberStyles.Currency, CultureInfo.InvariantCulture);
//关键参数 IFormatProvider:
//CultureInfo.InvariantCulture:通用文化规则(常用于数据存储)
//CultureInfo.CurrentCulture:系统当前文化规则
//new CultureInfo("fr-FR"):指定法语文化规则

// 解析美元金额(使用通用文化规则)
double usd = double.Parse("$1,234.56", 
    NumberStyles.Currency, 
    CultureInfo.InvariantCulture); // 输出:1234.56

// 解析法语格式数字(逗号作小数点)
double frenchNumber = double.Parse("1 234,56", 
    NumberStyles.Number, // 允许千位分隔符和小数点
    new CultureInfo("fr-FR")); // 输出:1234.56

// 解析德语负数(括号和逗号分隔符)
int germanNegative = int.Parse("(1.234)", 
    NumberStyles.AllowParentheses | NumberStyles.AllowThousands,
    new CultureInfo("de-DE")); // 输出:-1234
八、Parse 方法的异常处理

所有 Parse 方法在转换失败时会抛出以下异常:

        ​FormatException:输入字符串格式无效        

        ​OverflowException:数值超出目标类型范围

优先使用 TryParse 方法避免异常:

if (int.TryParse("abc", out int result)) {
    // 转换成功
} else {
    Console.WriteLine("转换失败");
}

  TryParse 方法是一种 ​安全且高效的类型转换机制,用于将字符串或其他数据格式尝试转换为目标类型,同时避免因转换失败而抛出异常。

        核心作用:

  1. 避免异常:不抛出 FormatException 或 OverflowException,提升代码健壮性。
  2. 简化逻辑:通过返回布尔值明确指示转换成功与否。
  3. 性能优化:减少 try-catch 块的开销,适合高频调用场景。
方法签名解析
public static bool TryParse(string s, out int result)
  • 输入参数s 是待转换的字符串。
  • 输出参数result 存储转换成功后的值(需用 out 关键字)。
  • 返回值true 表示转换成功,false 表示失败

注意必须使用out进行处理 parse能用的参数 TryParse都能使用

特性ParseTryParse
异常风险高(转换失败时抛出)无异常(返回布尔值)
性能低(需异常处理开销)高(无异常处理)
适用场景确定输入合法的内部逻辑用户输入、外部数据解析
代码简洁性需 try-catch 包裹直接条件判断
  1. 始终优先使用 TryParse:处理用户输入、文件数据或网络请求等不可信来源。
  2. 明确指定文化规则:避免因系统区域设置不同导致解析错误。
  3. 组合格式控制:通过 NumberStyles 精确匹配输入格式。
  4. 验证结果后再使用:检查返回的布尔值后再操作 out 参数。

几乎所有基础类型都提供 TryParse 方法:

  • int.TryParse
  • double.TryParse
  • DateTime.TryParse
  • bool.TryParse
  • Guid.TryParse
  • Enum.TryParse<T>
九、当然你也可以自己定义相关逻辑,然后使用parse
public struct Temperature {
    public double Celsius { get; }

    public static Temperature Parse(string input) {
        if (input.EndsWith("°C")) {
            double value = double.Parse(input.Replace("°C", ""));
            return new Temperature { Celsius = value };
        }
        throw new FormatException("无效的温度格式");
    }
}

Temperature temp = Temperature.Parse("25°C"); // 自定义解析逻辑

三、使用Convert法

            // 作用:更准确的将 各个类型之间进行相互转换
            // 语法:Convert.To目标类型(变量或常量)

Convert的作用:

  Convert 类是 System 命名空间下的静态工具类,用于 ​在不同基础类型之间进行安全转换,相比强制转换 ((type)value) 和 Parse 方法,它具备以下优势:

  1. 处理 null 值:将 null 转换为目标类型的默认值。
  2. 支持更多类型转换:如 bool ↔ intDateTime ↔ string 等。
  3. 兼容 DBNull:常用于数据库操作,处理 DBNull.Value
  4. 格式化控制:提供四舍五入、进制转换等功能。

示例:

1. 基本类型转换
// 字符串 → 整数
int num = Convert.ToInt32("123");       // 123

// 字符串 → 浮点数
double d = Convert.ToDouble("3.14");    // 3.14

// 布尔值 → 整数
int flag = Convert.ToInt32(true);        // 1(false → 0)

// 整数 → 布尔值(非零为 true)
bool isTrue = Convert.ToBoolean(1);      // true
2. 处理 null 和 DBNull
// 转换 null 值
int nullToInt = Convert.ToInt32(null);   // 0(不会抛异常)

// 处理数据库中的 DBNull
object dbValue = DBNull.Value;
int dbNullResult = Convert.ToInt32(dbValue); // 0(而不是抛异常)
3. 四舍五入与精度控制
// 四舍五入为整数
double pi = 3.14159;
int rounded = Convert.ToInt32(pi);       // 3(直接截断)
rounded = Convert.ToInt32(Math.Round(pi)); // 3(推荐手动四舍五入)

// 指定小数位数
decimal money = 123.4567m;
decimal truncated = Math.Round(money, 2); // 123.46
4.进制转换
// 十进制 → 二进制字符串
string binary = Convert.ToString(42, 2); // "101010"

// 二进制字符串 → 十进制
int fromBinary = Convert.ToInt32("101010", 2); // 42

// 十六进制 → 十进制
int fromHex = Convert.ToInt32("FF", 16);       // 255
5. 日期与时间转换
// 字符串 → DateTime
DateTime dt = Convert.ToDateTime("2023-10-01"); 

// DateTime → 字符串
string dateStr = dt.ToString("yyyy-MM-dd");   // "2023-10-01"

// 时间戳(Unix时间)转换
long timestamp = 1696147200; // 2023-10-01 00:00:00 UTC
DateTime fromTimestamp = DateTimeOffset.FromUnixTimeSeconds(timestamp).UtcDateTime;

四、类型转字符串方法

1. ToString() 基础方法
// 值类型转字符串
int num = 42;
string s1 = num.ToString(); // "42"

// 引用类型转字符串
DateTime now = DateTime.Now;
string s2 = now.ToString("yyyy-MM-dd"); // "2023-10-01"
2. 字符串插值
double price = 19.99;
string msg = $"价格:{price:C2}"; // "价格:¥19.99"
3. 格式化方法
// 数值格式化
string hex = 255.ToString("X4");       // "00FF"
string percent = 0.85.ToString("P1"); // "85.0%"

// 自定义格式
string custom = 123.456.ToString("#,##0.00"); // "123.46"

总结:

方法优点缺点适用场景
括号强转执行效率高类型不安全易抛异常确定类型兼容的数值转换
Parse精确控制格式必须处理异常严格格式的字符串解析
TryParse安全无异常需要out参数用户输入等不确定数据
Convert统一接口、支持null部分转换有隐式规则数据库交互、通用转换
ToString灵活性高可能返回类型名称(如对象未重写)需要定制格式的输出
字符串插值代码简洁无法处理null快速构建格式化字符串

本文最后需要讲述的是try catch语法

            // 必备部分
            try 
            {
            //希望进行异常捕获的代码块 放到 try 中
            // 若出错 会执行 catch 中的代码 捕获异常
            
            }
            catch 
            {
            
            
            }
            //可选部分
            finally 
            {
            // 最后执行的代码 不管有无出错 都会执行 
            }

示例:

try {
    string content = File.ReadAllText("missing.txt");
} 
catch (FileNotFoundException) {
    Console.WriteLine("文件不存在,请检查路径");
} 
catch (IOException ex) {
    Console.WriteLine($"读取文件失败: {ex.Message}");
} 
catch (Exception ex) {
    Console.WriteLine($"未知错误: {ex.GetType().Name}");
}

这个比较消耗性能,注意不要在反复的循环中调用!

try {
    // 代码
} 
catch (Exception ex) when (ex.Message.Contains("network")) {
    Console.WriteLine("网络相关错误");
} 
catch (Exception ex) when (ex is SocketException || ex is HttpRequestException) {
    Console.WriteLine("通信错误");
}

场景推荐方法原因
用户输入验证TryParse避免异常开销,直接返回状态码
文件/网络操作try-catch必须处理不可预测的 I/O 错误
数学运算检查预防性条件检查如 if (divisor != 0) 避免异常

附:异常表格

异常类型(Type)命名空间触发场景示例代码
System.ExceptionSystem所有异常的基类throw new Exception("通用错误");
System.SystemExceptionSystem系统级异常的基类(如 NullReferenceException通常不直接使用,由其子类继承
System.ArgumentExceptionSystem方法接收到无效参数void SetAge(int age) { if (age < 0) throw new ArgumentException("年龄不能为负"); }
ArgumentNullExceptionSystem参数为 nullvoid Print(string text) { if (text == null) throw new ArgumentNullException(nameof(text)); }
ArgumentOutOfRangeExceptionSystem参数超出有效范围List<int> list = new List<int>(); list[0] = 1; // 列表为空,索引越界
FormatExceptionSystem字符串格式不符合目标类型要求int.Parse("12A3"); // 包含非数字字符
OverflowExceptionSystem数值运算或转换导致溢出checked { int max = int.MaxValue; int x = max + 1; }
InvalidCastExceptionSystem无效的类型转换object obj = "hello"; int num = (int)obj;
NullReferenceExceptionSystem访问 null 对象的成员string s = null; int len = s.Length;
IndexOutOfRangeExceptionSystem数组/集合索引越界int[] arr = new int[3]; arr[5] = 10;
DivideByZeroExceptionSystem整数除法中除数为零int x = 5 / 0;
NotImplementedExceptionSystem未实现的方法或功能public override void Execute() { throw new NotImplementedException(); }
NotSupportedExceptionSystem调用不支持的操作ReadOnlyCollection<int>.Add(1); // 只读集合尝试添加元素
InvalidOperationExceptionSystem对象状态不适合执行操作Queue<int> queue = new Queue<int>(); queue.Dequeue(); // 队列为空时出队
KeyNotFoundExceptionSystem.Collections.Generic在字典中访问不存在的键Dictionary<string, int> dict = new Dictionary<string, int>(); int val = dict["missing"];
FileNotFoundExceptionSystem.IO访问不存在的文件File.ReadAllText("missing.txt");
DirectoryNotFoundExceptionSystem.IO访问不存在的目录Directory.GetFiles("C:\\InvalidPath");
IOExceptionSystem.IO广义的 I/O 错误(如文件被占用)File.Move("file.txt", "locked_file.txt"); // 目标文件被其他进程锁定
UnauthorizedAccessExceptionSystem.IO无权限访问文件/目录File.WriteAllText("C:\\System\\file.txt", "test"); // 无管理员权限
SqlExceptionSystem.Data.SqlClientSQL Server 数据库操作错误sqlConnection.Open(); // 数据库连接失败
TimeoutExceptionSystem操作超时HttpClient().GetAsync(url).Wait(TimeSpan.FromSeconds(1));
TaskCanceledExceptionSystem.Threading.Tasks异步任务被取消await Task.Delay(1000, cancellationToken); // 若 cancellationToken 被取消
TypeInitializationExceptionSystem类的静态构造函数抛出异常class MyClass { static MyClass() { throw new Exception(); } } // 首次访问时触发
OutOfMemoryExceptionSystem内存不足(如创建超大数组)byte[] hugeArray = new byte[int.MaxValue];
StackOverflowExceptionSystem无限递归导致堆栈溢出(无法捕获)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2319071.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rk3568驱动开发_设备树_9

什么是设备树&#xff1f; 以我目前的理解&#xff0c;设备树更像日常生活中用的地图&#xff0c;用户能根据地图去寻找到相应位置 设备树也是如此它描述了硬件设备的连接关系和配置信息&#xff0c;供 CPU&#xff08;或者更准确地说&#xff0c;是操作系统内核&#xff09;…

深度学习:从零开始的DeepSeek-R1-Distill有监督微调训练实战(SFT)

原文链接&#xff1a;从零开始的DeepSeek微调训练实战&#xff08;SFT&#xff09; 微调参考示例&#xff1a;由unsloth官方提供https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen2.5_(7B)-Alpaca.ipynbhttps://colab.research.google.com/git…

【AI News | 20250320】每日AI进展

AI Repos 1、servers 该仓库提供详细入门指南&#xff0c;用户可通过简单步骤连接Claude客户端&#xff0c;快速使用所有服务器功能。此项目由Anthropic管理&#xff0c;展示MCP的多样性与扩展性&#xff0c;助力开发者为大语言模型提供安全、可控的工具与数据访问。 2、awe…

从零开始实现 C++ TinyWebServer 阻塞队列 BlockQueue类详解

文章目录 阻塞队列是什么&#xff1f;为什么需要阻塞队列&#xff1f;BlockQueue 成员变量实现 push() 函数实现 pop() 函数实现 close() 函数BlockQueue 代码BlockQueue 测试 从零开始实现 C TinyWebServer 项目总览 项目源码 阻塞队列是什么&#xff1f; 阻塞队列是一种线程…

Linux驱动开发基础(can)

目录 1.can的介绍 2.can的硬件连接 2.1 CPU自带can控制器 2.2 CPU没有can控制器 3.电气属性 4.can的特点 5.can协议 5.1 can的种类 5.2 数据帧 5.2.1 标准数据帧格式 5.3.1 扩展数据帧格式 5.3 遥控帧 5.4 错误帧 5.5 过载帧 5.6 帧间隔 5.7 位填充 5.8 位时…

leetcode热题100道——字母异位词分组

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat", &…

MCU-芯片时钟与总线和定时器关系,举例QSPI

时钟源&#xff1a; 时钟源为系统时钟提供原始频率信号&#xff0c;系统时钟则通过&#xff08;分频、倍频、选择器&#xff09;成为整个芯片的“主时钟”&#xff0c;驱动 CPU 内核、总线&#xff08;AHB、APB&#xff09;及外设的运行。 内部时钟源&#xff1a; HSI&#x…

技术分享 | MySQL内存使用率高问题排查

本文为墨天轮数据库管理服务团队第51期技术分享&#xff0c;内容原创&#xff0c;如需转载请联系小墨&#xff08;VX&#xff1a;modb666&#xff09;并注明来源。 一、问题现象 问题实例mysql进程实际内存使用率过高 二、问题排查 2.1 参数检查 mysql版本 &#xff1a;8.0.…

分享一个精灵图生成和拆分的实现

概述 精灵图&#xff08;Sprite&#xff09;是一种将多个小图像合并到单个图像文件中的技术&#xff0c;广泛应用于网页开发、游戏开发和UI设计中。在MapboxGL中&#xff0c;跟之配套的还有一个json文件用来记录图标的大小和位置。本文分享基于Node和sharp库实现精灵图的合并与…

函数:形参和实参

在函数的使用过程中分为实参和形参&#xff0c;实参是主函数实际调用的值而形参则是给实参调用的值&#xff0c;如果函数没被调用则函式不会向内存申请空间&#xff0c;先用一段代码演示 形参&#xff1a; int test(int x ,int y ) {int z 0;z x y;return z; } 为何会叫做…

【C#知识点详解】ExcelDataReader介绍

今天来给大家介绍一下ExcelDataReader&#xff0c;ExcelDataReader是一个轻量级的可快速读取Excel文件中数据的工具。话不多说直接开始。 ExcelDataReader简介 ExcelDataReader支持.xlsx、.xlsb、.xls、.csv格式文件的读取&#xff0c;版本基本在2007及以上版本&#xff0c;支…

《视觉SLAM十四讲》ch13 设计SLAM系统 相机轨迹实现

前言 相信大家在slam学习中&#xff0c;一定会遇到slam系统的性能评估问题。虽然有EVO这样的开源评估工具&#xff0c;我们也需要自己了解系统生成的trajectory.txt的含义&#xff0c;方便我们更好的理解相机的运行跟踪过程。 项目配置如下&#xff1a; 数据解读&#xff1a; …

在类Unix终端中如何实现快速进入新建目录

&#x1f6aa; 前言 相信喜欢使用终端工作的小伙伴或多或少会被一个小地方给膈应&#xff0c;那就是每次想要新建一个文件夹并且进入之&#xff0c;那么就需要两条指令&#xff1a;mkdir DIR和cd DIR&#xff0c;有些人可能要杠了&#xff0c;我一条指令也能&#xff0c;mkdir…

TG电报群管理机器人定制开发的重要性

在Telegram&#xff08;电报&#xff09;用户突破20亿、中文社群规模持续扩张的背景下&#xff0c;定制化群管理机器人的开发已成为社群运营的战略刚需。这种技术工具不仅解决了海量用户管理的效率难题&#xff0c;更通过智能化功能重构了数字社群的治理范式。本文从管理效能、…

VNA操作使用学习-01 界面说明

以我手里面的liteVNA为例。也可以参考其他的nanoVNA的操作说明。我先了解一下具体的菜单意思。 今天我想做一个天调&#xff0c;居然发现我连一颗基本的50欧姆插件电阻和50欧姆的smt电阻的幅频特性都没有去测试过&#xff0c;那买来这个nva有什么用途呢&#xff0c;束之高阁求…

耘想Docker版Linux NAS的安装说明

耘想LinNAS&#xff08;Linux NAS&#xff09;可以通过Docker部署&#xff0c;支持x86和arm64两种硬件架构。下面讲解LinNAS的部署过程。 1. 安装Docker CentOS系统&#xff1a;yum install docker –y Ubuntu系统&#xff1a;apt install docker.io –y 2. 下载LinNas镜像…

OpenCV图像拼接(4)图像拼接模块的一个匹配器类cv::detail::BestOf2NearestRangeMatcher

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::detail::BestOf2NearestRangeMatcher 是 OpenCV 库中用于图像拼接模块的一个匹配器类&#xff0c;专门用于寻找两幅图像之间的最佳特征点匹配…

不用 Tomcat?SpringBoot 项目用啥代替?

在SpringBoot框架中&#xff0c;我们使用最多的是Tomcat&#xff0c;这是SpringBoot默认的容器技术&#xff0c;而且是内嵌式的Tomcat。 同时&#xff0c;SpringBoot也支持Undertow容器&#xff0c;我们可以很方便的用Undertow替换Tomcat&#xff0c;而Undertow的性能和内存使…

Zabbix安装(保姆级教程)

Zabbix 是一款开源的企业级监控解决方案&#xff0c;能够监控网络的多个参数以及服务器、虚拟机、应用程序、服务、数据库、网站和云的健康状况和完整性。它提供了灵活的通知机制&#xff0c;允许用户为几乎任何事件配置基于电子邮件的告警&#xff0c;从而能够快速响应服务器问…

鸿蒙开发真机调试:无线调试和USB调试

前言 在鸿蒙开发的旅程中&#xff0c;真机调试堪称至关重要的环节&#xff0c;其意义不容小觑。虽说模拟器能够为我们提供初步的测试环境&#xff0c;方便我们在开发过程中快速预览应用的基本效果&#xff0c;但它与真机环境相比&#xff0c;仍存在诸多差异。就好比在模拟器中…