学过C语言的伙伴都知道,曾经比较两个数,输出最大或最小的一个,或者是比较三个数,输出最大或者最小的那个,又或是两个数交换,又或是绝对值等等,其实这些算法在linux内核中通通都有实现,以下的代码是我从linux内核源码的kernel.c中抠出来的代码,我们来看看:

我们直接上代码:

#include <stdio.h>
#include <stdlib.h>
/*
 * min()/max() macros that also do
 * strict type-checking.. See the
 * "unnecessary" pointer comparison.
 */
//比较两个数,如果x>y,输出y,否则输出x
#define min(x,y) ({ \
	typeof(x) _x = (x);	\
	typeof(y) _y = (y);	\
	(void) (&_x == &_y);		\
	_x < _y ? _x : _y; })
//比较两个数,如果x>y,输出x,否则输出y
#define max(x,y) ({ \
	typeof(x) _x = (x);	\
	typeof(y) _y = (y);	\
	(void) (&_x == &_y);		\
	_x > _y ? _x : _y; })
//比较三个数的大小 ,输出最小的一项
#define min3(x,y,z) ({   \
	typeof(x)  _min1 = (x) ; \
	typeof(y)  _min2 = (y) ; \
	typeof(z)  _min3 = (z) ; \
	(void) (&_min1 == &_min2) ; \
	(void) (&_min1 == &_min3) ; \
	_min1 < _min2 ? (_min1 < min3 ? _min1 : _min3) ; \
		(_min2 < _min3 ? _min2 : _min3) ;} )
//比较三个数的大小 ,输出最大的一项
#define max3(x,y,z) ({   \
	typeof(x)  _max1 = (x) ; \
	typeof(y)  _max2 = (y) ; \
	typeof(z)  _max3 = (z) ; \
	(void) (&_max1 == &_max2) ; \
	(void) (&_max1 == &_max3) ; \
	_max1 > _max2 ? (_max1 > max3 ? _max1 : _max3) ; \
		(_max2 > _max3 ? _max2 : _max3) ;} )
//输出绝对值
#define abs(x) ({				\
		int __x = (x);			\
		(__x < 0) ? -__x : __x;		\
	})
//交换两个数
#define swap(a,b)  \
	do{typeof(a) __tmp = (a); (a) = (b) ; b = (__tmp) ;}while(0)
int main(void)
{
	int ret = 0 ;
	ret = max(1,2);
	printf("%d\n",ret);
	printf("%d\n",abs(-100));
	int a = 2 ;
	int b = 3 ;
	swap(a,b);
	printf("%d %d\n",a,b);

	return 0 ;
}

运行结果如图所示:

这些算法在内核中通常用宏的规格来实现,关于C语言很多算法,其实在linux内核中几乎都有,比如链表,树,图,排序,字符串,加密等等的算法和数组结构都有实现,能够深入的去理解linux内核,对学习C语言是非常有帮助的。

linux内核中的C语言常规算法(前提:你的编译器要支持typeof和type)的更多相关文章

  1. Linux内核中常用的数据结构和算法(转)

    知乎链接:https://zhuanlan.zhihu.com/p/58087261 Linux内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树. 链表 Linux内核代码大量使用了 ...

  2. 分析linux内核中的slub内存管理算法

    1. 分析的linux内核源码版本为4.18.0 2. 与slub相关的内核配置项为CONFIG_SLUB 3. 一切都从一个结构体数组kmalloc_caches开始,它的原型如下: ] __ro_ ...

  3. Linux内核中的有关Page的算法

    static inline int get_order(unsigned long size) { int order; size = (size-1) >> (PAGE_SHIFT-1) ...

  4. Linux内核中的算法和数据结构

    算法和数据结构纷繁复杂,但是对于Linux Kernel开发人员来说重点了解Linux内核中使用到的算法和数据结构很有必要. 在一个国外问答平台stackexchange.com的Theoretica ...

  5. 嵌入式C语言自我修养 01:Linux 内核中的GNU C语言语法扩展

    1.1 Linux 内核驱动中的奇怪语法 大家在看一些 GNU 开源软件,或者阅读 Linux 内核.驱动源码时会发现,在 Linux 内核源码中,有大量的 C 程序看起来“怪怪的”.说它是C语言吧, ...

  6. C语言在linux内核中do while(0)妙用之法

    为什么说do while(0) 妙?因为它的确就是妙,而且在linux内核中实现是相当的妙,我们来看看内核中的相关代码: #define db_error(fmt, ...) \ do { \ fpr ...

  7. Linux内核中双向链表的经典实现

    概要 前面一章"介绍双向链表并给出了C/C++/Java三种实现",本章继续对双向链表进行探讨,介绍的内容是Linux内核中双向链表的经典实现和用法.其中,也会涉及到Linux内核 ...

  8. Linux内核中的fastcall和asmlinkage宏

    代码中看见:#define _fastcall 所以了解下fastcall -------------------------------------------------------------- ...

  9. linux内核中的get_user和put_user

    linux内核中的get_user和put_user 在 内核空间和用户空间交换数据时,get_user和put_user是两个两用的函数.相对于copy_to_user和 copy_from_use ...

随机推荐

  1. Programming In Scala笔记-第十五章、Case Classes和模式匹配

    本章主要分析case classes和模式匹配(pattern matching). 一.简单例子 接下来首先以一个包含case classes和模式匹配的例子来展开本章内容. 下面的例子中将模拟实现 ...

  2. [OpenCV] GpuMat and Mat, compare cvtColor perforemence

    Introduction I am going to measure the performence of my two GT650M and compare GPU with CPU version ...

  3. Android底层开发经验

    最近看到一个博客,他的博文虽然是转载的,但源作者肯定对底层的理解可谓是非常透彻,一副思维导图就可以将整个重要体系建立起来,非常适合大家学习.学习不单单只要有代码,生动有趣更重要.在此推荐一波: htt ...

  4. Spark技术内幕: 如何解决Shuffle Write一定要落盘的问题?

    在Spark 0.6和0.7时,Shuffle的结果都需要先存储到内存中(有可能要写入磁盘),因此对于大数据量的情况下,发生GC和OOM的概率非常大.因此在Spark 0.8的时候,Shuffle的每 ...

  5. 一个都不能少: DevOps的3大核心基础架构

    DevOps的涵盖面非常广,因为这个概念的火热,又有很多文章和技术都在把DevOps的帽子扣在自己头上,让很多人迷惑不解.其实,DevOps的知识体系如果从顶层上来分解,只有2块:方法论和工具链.方法 ...

  6. SQL 数据库语言分析总结(三)

    这次介绍通过mysql-WorkBench这个工具来管理操作数据库. 创建和删除数据库 1.点击创建数据库按钮 2.选中后右键,出现drop schema一项,这个用来删除. 设置默认数据库 选中右键 ...

  7. Spark技术内幕:Executor分配详解

    当用户应用new SparkContext后,集群就会为在Worker上分配executor,那么这个过程是什么呢?本文以Standalone的Cluster为例,详细的阐述这个过程.序列图如下: 1 ...

  8. Java基础--Java---IO流------GUI(布局)、Frame、事件监听机制、窗体事件、Action事件、鼠标事件、对话框Dialog、键盘事件、菜单

     * 创建图形化界面  * 1.创建frame窗体  * 2.对窗体进行基本设置  *   比如大小.位置.布局  * 3.定义组件  * 4.将组件通过窗体的add方法添加到窗体  * 5.让窗体显 ...

  9. 【安卓中的缓存策略系列】安卓缓存策略之综合应用ImageLoader实现照片墙的效果

    在前面的[安卓缓存策略系列]安卓缓存之内存缓存LruCache和[安卓缓存策略系列]安卓缓存策略之磁盘缓存DiskLruCache这两篇博客中已经将安卓中的缓存策略的理论知识进行过详细讲解,还没看过这 ...

  10. SimpleAdapter和Baseadapter填充listActivity-android学习之旅()

    简介 SimpleAdapter的功能是能够为AbsListView提供复杂的数据,需要构造ListView 代码示例 package peng.liu.testview; import androi ...