Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355422
  • 博文数量: 53
  • 博客积分: 25
  • 博客等级: 民兵
  • 技术积分: 1548
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-27 07:54
个人简介

IT民工一枚,为学弟学妹造福是我一直写博文的动力!为媳妇提供技术支持是我学习新技术的动力!为自己脱离贫困线,买到心仪的摩托车,有饭吃,有床睡,有妹把,笔耕不辍~~

文章分类

全部博文(53)

文章存档

2013年(54)

分类: LINUX

2013-04-25 22:22:17

第二章 数据类型

第一节 双向链表


list_add

函数名 向链表添加一个新元素
用例 void list_add(struct list_head* new, struct list_head* head)
参数说明 new----被添加的元素指针
head---链表头指针
函数简介 使用头插法向链表添加一个新元素,添加到头指针的后边,易于实现栈结构

list_add_tail

函数名 向链表添加一个新元素
用例 void list_add_tail(struct list_head* new, struct list_head* head)
参数说明 new----被添加的元素指针
head---链表头指针
函数简介 使用尾插法向链表添加一个新元素,添加到头指针的前边,易于实现队列结构

list_del

函数名 从链表删掉一个元素
用例 void list_del(struct list_head* entry)
参数说明 entry-----从链表删除的元素指针
函数简介 删除元素以后,使用list_empty检查链表的时候返回假。此时调用被删元素是未定义行为,水平不够,请不要使用。

list_del_init

函数名 删掉链表中的元素以后,将链表重新初始化
用例 void list_del_init(strut list_head* enty)
参数说明 entry-----从链表删除的元素指针
函数简介 删掉链表中的元素以后,将链表重新初始化。调用列表初始化函数。

list_empty

函数名 判断链表是否为空
用例 void list_empty( struct list_head* head)
参数说明 head---链表头指针
函数简介 双向链表通过判断首尾指针的值判断是否为空,具体参见度娘“双向链表判空”

list_splice

函数名 将两个链表连接
用例 void list_add(struct list_head* list, struct list_head* head)
参数说明 list----要添加的链表表头指针
head---被添加的目标链表头指针
函数简介 将新的链表使用头插法加入目标链表表头之后,将目标链表剩余的元素添加到新添加的列表之后。

list_entry

函数名 列出目标元素的数据结构
用例 list_entry(ptr, type, member)
参数说明 ptr----链表指针,指向要提取的元素
type--带出嵌入的数据结构
member---在返回的结构体中的链表结构体名
函数简介 链表元素的反射函数,向使用者提供函数的内部构造

list_for_each

函数名 遍历列表的函数
用例 list_for_each(pos, head)
参数说明 pos----链表头指针类型的指针计数器
head--链表头指针,遍历的基址
函数简介 使用指针遍历整个链表

list_for_each_safe

函数名 遍历列表的函数
用例 list_for_each_safe(pos, n, head)
参数说明 pos---链表头指针类型的指针计数器
n------另外一个链表头指针类型的哨兵,用于缓存链表头指针
head---链表头指针
函数简介 使用指针遍历整个链表

list_for_each与list_for_each_safe的区别
http://blog.csdn.net/choice_jj/article/details/7496732

第三章 基本的C函数库

在做驱动开发的时候,不能大摇大摆的使用C库里的所有函数,下表中列出了一些可用的函数,这些函数的定义可能于ANSI定义不同,当然不同的地方我会标注出来。

第一节 字符串转换


simple_strtol

函数名 将一个字符串转换成符号长整形量
用例 long simple_strtol(const char* cp, char** endp, unsigned int base)
参数说明 cp----字符串的起始位置
endp--将被解析的字符串尾指针
base---要转换的数值基数
函数简介

simple_strtoll

函数名 把一个字符串转换为一个有符号长长整数
用例 long long simple_strtoll (const char * cp, char ** endp, unsigned int base)
参数说明 cp------指向字符串的开始
endp---为指向要分析的字符串末尾处的位置
base---为要用的基数。
函数简介

simple_strtoul

函数名 把一个字符串转换为一个无符号长整数
用例 long long simple_strtoul (const char * cp, char ** endp, unsigned int base)
参数说明 cp-----指向字符串的开始
endp-----为指向要分析的字符串末尾处的位置
base-----为要用的基数。
函数简介

simple_strtoull

函数名 把一个字符串转换为一个无符号长长整数
用例 long long simple_strtoull (const char * cp, char ** endp, unsigned int base)
参数说明 cp-----指向字符串的开始
endp-----为指向要分析的字符串末尾处的位置
base-----为要用的基数。
函数简介

vsnprintf

函数名 格式化一个字符串,并把它放在缓存中。
用例 int vsnprintf (char * buf, size_t size, const char * fmt, va_list args)
参数说明 buf-----为存放结果的缓冲区
size-----
为缓冲区的大小
fmt-----为要使用的格式化字符串
args-----为格式化字符串的参数。
函数简介

snprintf

函数名 格式化一个字符串,并把它放在缓存中。
用例 int snprintf (char * buf, size_t size, const char * fmt, ... ...)
参数说明 buf-----为存放结果的缓冲区
size-----
为缓冲区的大小
fmt-----为格式化字符串,使用@…来对格式化字符串进行格式化
-----为可变参数。
函数简介

vsprintf

函数名 格式化一个字符串,并把它放在缓存中。
用例 int vsprintf (char * buf, const char * fmt, va_list args)
参数说明 buf-----为存放结果的缓冲区
size-----
为缓冲区的大小
fmt-----为要使用的格式化字符串
args-----为格式化字符串的参数。
函数简介

sprintf

函数名 格式化一个字符串,并把它放在缓存中。
用例 int sprintf (char * buf, const char * fmt, ... ...)
参数说明 buf-----为存放结果的缓冲区
size-----
为缓冲区的大小
fmt-----为格式化字符串,使用@…来对格式化字符串进行格式化
-----为可变参数。
函数简介

几个打印函数的区别:

http://blog.sina.com.cn/s/blog_674b5aae0100prv3.html

第二节 字符串操作


strcpy

函数名 拷贝一个以NUL结束的字符串
用例 char * strcpy (char * dest, const char * src)
参数说明 dest-----为目的字符串的位置
src-----
为源字符串的位置。
函数简介

strncpy

函数名 拷贝一个定长的、以NUL结束的字符串
用例 char * strncpy (char * dest, const char * src, size_t count)
参数说明 dest-----为目的字符串的位置
src-----
为源字符串的位置
count-----为要拷贝的最大字节数
函数简介 与用户空间的strncpy不同,这个函数并不用NUL填充缓冲区,如果与源串超过count,则结果以非NUL结束

strcat

函数名 把一个以NUL结束的字符串添加到另一个串的末尾
用例 char * strcat (char * dest, const char * src)
参数说明 dest-----为要添加的字符串
src-----
为源字符串。
函数简介 连接两个字符串,将新字符串添加到源字符串的末尾

strncat

函数名 把一个定长的、以NUL结束的字符串添加到另一个串的末尾
用例 char * strncat (char * dest, const char * src, size_t count)
参数说明 dest-----为要添加的字符串
src-----
为源字符串
count-----为要拷贝的最大字节数
函数简介 注意,与strncpy,形成对照,strncat必须正常结束。

strcmp

函数名 比较两个字符串
用例 int strcmp(const char* cs, const char* ct)
参数说明 cs----待比较的源字符串
ct----待比较的目标字符串
函数简介 返回两个字符串的不同的位置

strncmp

函数名 比较两个特定长度的字符串
用例 int strncmp(const char*cs, const char* ct, size_t count)
参数说明 cs----待比较的源字符串
ct----待比较的目标字符串
count---最多比较的字符串长度,超过后就不比了
函数简介 使用头插法向链表添加一个新元素,易于实现栈结构

strchr

函数名 在一个字符串中查找第一次出现的某个字符
用例 char * strchr (const char * s, int c)
参数说明 s-----为被搜索的字符串
c-----为待搜索的字符。
函数简介

strrchr

函数名 在一个字符串中查找最后一次出现的某个字符
用例 char * strrchr (const char * s, int c)
参数说明 s-----为被搜索的字符串
c-----为待搜索的字符。
函数简介

strlen

函数名 给出一个字符串的长度
用例 size_t strlen (const char * s)
参数说明 s-----为给定的字符串
函数简介 返回指定字符串的 长度

strnlen

函数名 给出给定长度字符串的长度
用例 size_t strnlen (const char * s, size_t count)
参数说明 s-----为给定的字符串
函数简介  返回指定的特定长度的字符串的 长度

strpbrk

函数名 在一个字符串中查找第一次出现的一组字符
用例 char * strpbrk (const char * cs, const char * ct)
参数说明 cs-----为被搜索的字符串
ct-----为待搜索的一组字符
函数简介  
在源字符串(source-string)中找出最先含有搜索字符串(searching-string)中的任一字符的位置并返回,若找不到则返回空指针。注意:返回值是指向源字符串的指针,所以在使用返回结果的时候,请确保源字符串的有效性。

strtok

函数名 把一个字符串分割为令牌符
用例 char * strtok (char * s, const char * ct)
参数说明 s-----为被搜索的字符串
ct-----为待搜索的子串
函数简介 注意,一般不提倡用这个函数,而应当用strsep

memset

函数名 用给定的值填充内存区
用例 void * memset (void * s, int c, size_t count)
参数说明 s-----为指向内存区起始的指针
c----- 要填充的内容
count-----为内存区的大小
函数简介 I/O空间的访问不能使用memset,而应当使用memset_io

bcopy

函数名 把内存的一个区域拷贝到另一个区域
用例 char * bcopy (const char * src, char * dest, int count)
参数说明 src-----为源字符串
dest-----为目的字符串
count-----为内存区的大小
函数简介 注意,这个函数的功能与memcpy相同,这是从BSD遗留下来的,其对参数进行了逆转,对I/O空间的访问应当用memcpy_toiomemcpy_fromio

memcpy

函数名 把内存的一个区域拷贝到另一个区域
用例 void * memcpy (void * dest, const void * src, size_t count)
参数说明 des-----t为目的字符串
Src-----为源字符串
count-----为内存区的大小
函数简介

I/O空间的访问应当用memcpy_toiomemcpy_fromio

memmove

函数名 把内存的一个区域拷贝到另一个区域
用例 void * memmove (void * dest, const void * src, size_t count)
参数说明 dest-----为目的字符串
Src-----为源字符串
count-----为内存区的大小
函数简介 与memcpy不同,memmove处理重叠的区域

memcmp

函数名 比较内存的两个区域
用例 int memcmp (const void * cs, const void * ct, size_t count)
参数说明 cs-----为一个内存区
ct-----为另一个内存区
count-----为内存区的大小
函数简介  比对两个内存区的不同,返回不同的字位置

memscan

函数名 在一个内存区中查找一个字符
用例 void * memscan (void * addr, int c, size_t size)
参数说明 addr-----为内存区
c-----为要搜索的字符
size-----为内存区的大小
函数简介 返回c第一次出现的地址,如果没有找到c,则指向内存区的下一个字节。

strstr

函数名 在以NUL结束的串中查找第一个出现的子串
用例 char * strstr (const char * s1, const char * s2)
参数说明 s1-----为被搜索的串
s2-----为待搜索的串。
函数简介 比对两个字符串,返回查到的字符串的位置

memchr

函数名 在一个内存区中查找一个字符
用例 void * memchr (const void * s, int c, size_t n)
参数说明 s-----为内存区
c-----为待搜索的字符
n-----为内存的大小
函数简介 使返回c第一次出现的位置,如果没有找到c,则返回空。

第三节 位操作


set_bit

函数名 在位图中原子地设置某一位
用例 void set_bit (int nr, volatile void * addr)
参数说明 nr-----为要设置的位
addr-----为位图的起始地址
函数简介 这个函数是原子操作,如果不需要原子操作,则调用__set_bit函数,nr可以任意大,位图的大小不限于一个字。

__set_bit

函数名 在位图中设置某一位
用例 void __set_bit (int nr, volatile void * addr)
参数说明 nr-----为要设置的位
addr-----为位图的起始地址
函数简介 该函数不是原子操作

clear_bit

函数名 在位图中清某一位
用例 void clear_bit (int nr, volatile void * addr)
参数说明 nr-----为要清的位
addr-----为位图的起始地址
函数简介 该函数是原子操作,但不具有加锁功能,如果要用于加锁目的,应当调用smp_mb__before_clear_bitsmp_mb__after_clear_bit函数,以确保任何改变在其他的处理器上是可见的。

__change_bit

函数名 在位图中改变某一位
用例 void __change_bit (int nr, volatile void * addr)
参数说明 nr-----为要设置的位
addr-----为位图的起始地址。
函数简介 change_bit不同,该函数是非原子操作。

change_bit

函数名 在位图中改变某一位
用例 void change_bit (int nr, volatile void * addr)
参数说明 nr-----为要设置的位
addr-----为位图的起始地址。
函数简介 本函数是原子操作,nr可能会太大,导致更改越界。

test_and_set_bit

函数名 设置某一位并返回该位原来的值
用例 int test_and_set_bit (int nr, volatile void * addr)
参数说明 nr-----为要设置的位
addr-----为位图的起始地址。
函数简介 该函数是原子操作

__test_and_set_bit

函数名 设置某一位并返回该位原来的值
用例 int __test_and_set_bit (int nr, volatile void * addr)
参数说明 nr-----为要设置的位
addr-----为位图的起始地址
函数简介 该函数是非原子操作,如果这个操作的两个实例发生竞争,则一个成功而另一个失败,因此应当用一个锁来保护对某一位的多个访问。

test_and_clear_bit

函数名 清某一位,并返回原来的值
用例 int test_and_clear_bit (int nr, volatile void * addr);
参数说明 nr-----为要设置的位
addr-----为位图的起始地址。
函数简介 该函数是原子操作

__test_and_clear_bit

函数名 清某一位,并返回原来的值
用例 int __test_and_clear_bit (int nr, volatile void * addr);
参数说明 nr-----为要设置的位
addr-----为位图的起始地址。
函数简介 该函数为非原子操作,若要用于加锁目的,应当调用smp_mb__before_clear_bit 或smp_mb__after_clear_bit函数,以确保任何改变在其他的处理器上是可见的。

test_and_change_bit

函数名 改变某一位并返回该位的新值
用例 int test_and_change_bit (int nr, volatile void * addr)
参数说明 nr-----为要设置的位
addr-----为位图的起始地址。
函数简介 该函数为原子操作,同时操作可以被记录。成为内存访问的一道屏障

test_bit

函数名 确定某位是否被设置
用例 int test_bit (int nr, const volatile void * addr)
参数说明 nr-----为要测试的第几位
addr-----为位图的起始地址。
函数简介 检测*addr的第nr位是否为1(*addr右起最低位为第0位)

find_first_zero_bit

函数名 在内存区中查找第一个值为0的位
用例 int find_first_zero_bit (void * addr, unsigned size)
参数说明 addr-----为内存区的起始地址
size-----为要查找的最大长度
函数简介

返回第一个位为0的位号,最低位从0开始offset最小值为0,最大值为sizeof(unsigned long)*8 - 1

find_next_zero_bit

函数名 在内存区中查找第一个值为0的位
用例 int find_next_zero_bit (void * addr, int size, int offset)
参数说明 addr---为内存区的起始地址
size-----为要查找的最大长度
offset-----开始搜索的起始位号。
函数简介 本函数用汇编写成,效率更高些

从源码级别,说明几个关于位操作的函数:

http://blog.csdn.net/iamonlyme/article/details/7081082

ffz

函数名 在字中查找第一个0
用例 unsigned long ffz (unsigned long word);
参数说明 word---要搜索的字。
函数简介 如果这个字没有0位,这个函数调用就成为未定义行为,所以使用之前先测试整个字是否为非0

ffs

函数名 查找第一个已设置的位(1)
用例 int ffs (int x)
参数说明 x---要搜索的字。
函数简介 这个函数的定义方式与Libc中的一样,编译器内建了这个方法。因此从本质上与ffz不同。

hweight32

函数名 返回一个N位字的加权平衡值
用例 hweight32 ( x)
参数说明 x----要加权的字
函数简介 个数的加权平衡是这个数所有位的总和。

小结


这次貌似做的多了一点。。。做IT就是这样,一旦来了感觉就停不下。。。话说本周的作业还没写完呢。。。我大操作系统,让我欢喜让我悲啊!整天提心吊胆的,睡觉都会想自己还没做完高操的作业,然后垂死病中惊坐起。。。
话说,写了这么多,一定要总结一下:
1. 链表部分,想要使用这些函数,必须明白链表的数据结构,如果不懂,问度娘。这些操作都是链表的基本函数;
2. 字符串操作部分,一定要注意以下几点:否需要加锁;是否读取合法区域;是否越界;未定义行为只有高手才配玩,我等码工还是好好写规范的代码吧。
3. 位操作部分,涉及到的函数都是很常规的一些,如果你对置位和清零不太清楚,可以查看一下组成原理的存储器部分,这里理解了硬件的实现过程对函数的使用有很大的帮助。
4. 剩下的一些周边函数,可以在使用到的时候来这里CTRLF搜一下,大概知道怎么用就好了。当然,推荐你MARK一下本文。本屌水平一般,但是本文是站在众巨人肩膀上写成的。此处也谢过各位活着和死去的大牛了。

明儿更内存管理,敬请关注:)
阅读(3602) | 评论(2) | 转发(8) |
给主人留下些什么吧!~~

fuchao20122013-04-26 20:32:27

jerryhua_cu:总结的相当不错,如果能把函数所在头文件列出来就更好了

多谢支持,分析源码的工作正在进行中,很快就会发布出来了。敬请关注

回复 | 举报

jerryhua_cu2013-04-26 17:20:16

总结的相当不错,如果能把函数所在头文件列出来就更好了