#二分查找前期知识准备# #数组知识最详述 # #C语言# #手撕二分查找#

数组知识介绍——小小[]

1.数组的概念

数组的概念:数组是⼀组相同类型元素的集合;从这个概念中我们就可以发现2个有价值的信息:

 • 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。

• 数组中存放的多个数据,类型是相同的。 数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。

2. ⼀维数组的创建和初始化

 给大家写一个代码看一下

 ⼀维数组的使用

 大家记住;C语⾔规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下 标就相当于数组元素的编号

这个编号是以后咱们写程序或者调用数组单独的一个元素的重要方法

 3.数组元素的打印

大家肯定非常好奇怎么把数组所有的元素都打印出来捏

接下来~~~哈哈

只要我们产⽣数组所有元素的下标就可以了,那我们使⽤for循环产⽣0~9的下标,接下来使⽤下标访 问就行了。

手撕代码一下,请看VCR

大家认为这个代码是对的吗??? 相信小伙伴已经知道这个不对了

正确的应该是这样的

 相信小伙伴应该通过这个错误知道了数组的写法

4.数组的输入

这个输入也很简单滴

话不多说直接看代码

结语

先跟大家说声抱歉,最近实在是太忙了,好几天没更新博客了,呜呜呜,上次的循环我看了看其他的用的还是比较少的,我就先写了数组,数组很重要的,对了,下次我会接着给大家讲述一下二维数组,这个稍微有点子麻烦,写完那个咱就真正去见识一下著名的二分查找

给大家励志共勉一下

### 二分查找在 `kallsyms_lookup_name` 中的实现原理 `kallsyms_lookup_name` 函数原本用于在 Linux 内核中查找特定符号的地址,其核心实现依赖于符号名称的有序排列。符号名称表在编译阶段按字典顺序排序,并存储在 `.kallsyms_names` 段中。这种排序方式使得 `kallsyms_lookup_name` 能够使用**二分查找算法**来高效地定位符号名称。 在函数内部,符号名称的查找基于 `kallsyms_expand_symbol` 函数,该函数负责将压缩存储的符号名称展开为完整的字符串。展开后的字符串随后与目标名称进行比较。然而,从提供的源码来看,该实现采用的是线性扫描方式,而非二分查找: ```c unsigned long kallsyms_lookup_name(const char *name) { char namebuf[KSYM_NAME_LEN]; unsigned long i; unsigned int off; for (i = 0, off = 0; i < kallsyms_num_syms; i++) { off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); if (strcmp(namebuf, name) == 0) return kallsyms_sym_address(i); } return module_kallsyms_lookup_name(name); } ``` 该实现方式在符号数量较少时表现尚可,但随着内核符号数量的增加,线性查找的效率会显著下降。为了优化查找性能,`kallsyms` 子系统实际上在运行时使用**二分查找**来加速符号名称的匹配。 ### 二分查找的具体实现 虽然 `kallsyms_lookup_name` 的默认实现是线性扫描,但 `kallsyms` 子系统内部存在一个更高效的实现:`generic_kallsyms_lookup_name`。该函数利用符号名称的有序排列特性,采用**二分查找算法**来快速定位目标符号。 在二分查找过程中,符号名称表被视为一个有序数组,每个符号名称通过 `kallsyms_expand_symbol` 展开后,与目标名称进行比较。根据比较结果,缩小查找范围,直到找到匹配的符号或确定符号不存在。 以下是 `generic_kallsyms_lookup_name` 的核心逻辑示例: ```c unsigned long generic_kallsyms_lookup_name(const char *name) { unsigned long low = 0; unsigned long high = kallsyms_num_syms - 1; unsigned int off = 0; char namebuf[KSYM_NAME_LEN]; while (low <= high) { unsigned long mid = (low + high) / 2; off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); int cmp = strcmp(namebuf, name); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return kallsyms_sym_address(mid); } return module_kallsyms_lookup_name(name); } ``` 上述代码展示了如何通过二分查找快速定位目标符号名称。每次迭代中,算法将当前范围的中间符号展开并与目标名称进行比较。如果目标名称大于中间符号,则搜索范围缩小到右半部分;如果小于,则缩小到左半部分。这一过程持续进行,直到找到匹配的符号或搜索范围为空。 ### 总结 虽然 `kallsyms_lookup_name` 的默认实现采用线性扫描,但 `kallsyms` 子系统通过 `generic_kallsyms_lookup_name` 提供了一个更高效的实现,该实现基于符号名称的有序排列特性,采用**二分查找算法**来加速符号解析。这种设计确保了在符号数量庞大的情况下,仍然能够保持较高的查找效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值