
C语言&嵌入式
Dave888Zhou
大处着眼,小处着手;群居守口,独居守心。
展开
-
我的C实践(1):宏的应用
1、为了调用宏时能得到正确结果,在宏体中建议对宏的每个参数用括号括起来,并且当宏体是一个表达式时整个宏体也用括号括起来。/* c1.c:将两个数相乘 */#define product(x,y) ((x)*(y))#include int main(){ int a=1,b=2,c=3,d=4,x=0; x=product(a+3,b)+product(c,d原创 2009-09-24 18:19:00 · 1662 阅读 · 1 评论 -
C标准库源码解剖(12):浮点数环境fenv.h
为了编写高精度浮点数的运算,编程人员需要控制浮点数环境的各个方面:结果如何舍入,浮点数表达式如何简化与变换,如何处理浮点数异常(如下溢之类的浮点数异常是忽略还是产生错误),等等。C99引入了fenv.h来控制浮点数环境。 1、fenv.h:定义了浮点数环境控制函数、异常控制函数、舍入方式控制函数、浮点数异常码和舍入方式等。注意浮点数环境的实现是依赖于体系结构的,因为不同的体原创 2009-10-21 19:43:00 · 14869 阅读 · 0 评论 -
C标准库源码解剖(10):区域设置函数locale.h
国家、文化和语言规则集称为区域设置,locale.h头文件中定义了区域设置相关的函数。setlocale函数用于设置或返回当前的区域特性,localeconv用于返回当前区域中的数字和货币信息(保存在struct lconv结构实例中)。setlocale的第一个实参指定要改变的区域行为类别,预定义的setlocale类别有: LC_ALL:所有行为。 LC_COLLA原创 2009-10-19 23:45:00 · 2593 阅读 · 1 评论 -
C标准库源码解剖(13):输入输出函数stdio.h
C标准中的I/O库是一个比较庞大的库,实现也比较复杂。显然I/O库的实现是依赖于操作系统的,不同的系统上I/O库的实现机理是不一样的。glibc中,I/O库的核心实现在libio目录下。有4个头文件libio.h, iolibio.h, libioP.h, strfile.h, stdio.h,其中stdio.h是导出的标准C头文件,其余都是内部实现。这里并不打算解剖整个I/O库的源代码(原创 2009-10-22 22:43:00 · 3690 阅读 · 0 评论 -
C标准库源码解剖(14):通用函数stdlib.h
通用函数库在头文件stdlib.h中声明,比较庞大,主要分为以下几大类:存储分配、随机数生成、数字转换与整型运算、程序退出与环境通信、搜索与排序、多字节与宽字符的转换。由于汲及到存储分配、环境通信等,因此它们的大多数也依赖于操作系统。glibc中,通用函数库的核心实现在stdlib和malloc两个目录下。 stdlib.h中导出的所有标准接口如下: 1、m原创 2009-10-23 22:33:00 · 2846 阅读 · 0 评论 -
C标准库源码解剖(15):数学函数库math.h, tgmath.h和complex.h
数学库是一个庞大的库,而且数学函数的实现一般要涉及到特有的数值算法,因此这里也是作一个概述性的介绍。标准C中的数学库有3个头文件math.h, tgmath.h和complex.h,其中tgmath.h和complex.h是C99中引入的。标准C中定义的数学函数主要是初等函数,包括绝对值函数、高斯函数(即求最近整数)、指数函数、对数函数、幂函数、三角函数与反三角函数、双曲函数与反双曲函数等原创 2009-10-23 22:36:00 · 13839 阅读 · 1 评论 -
我的C实践(4):基本操作的位运算实现
下面使用位运算来实现一些基本的操作和基本的函数,这些实现全部都是宏,这是高效率的关键。/* base.h:基本操作的位运算实现 */#ifndef BASE_H#define BASE_H#define word int#define uword unsigned int/* 将最右侧的1位改成0位 */#define right1to0(x) ((x)&((x原创 2010-03-28 21:20:00 · 1723 阅读 · 0 评论 -
我的C实践(5):舍入到2的幂
我们经常会遇到需要把一个数舍入到2的幂的情况,下面用位运算来实现。/* pow2round.c:舍入到2的幂 */#include /* 下面的舍入函数宏既适用于无符号整数,也适用于带符号整数 *//* 下舍入到8的倍数:注意-8为0xfffffff8 */#define downround8(x) ((x)&-8)/* 上舍入到8的倍数:也可用x+(-x&7) */原创 2010-03-28 21:28:00 · 1327 阅读 · 0 评论 -
我的C实践(6):算术边界的检查
在计算机上进行算术运算时,经常会遇到结果溢出的情况,这就需要对运算的结果进行边界检查,判断其是否溢出,如果溢出,则要修正结果。下面用位运算来实现边界的检查。/* arithbound.c:算术边界检测 */#include /* 下面的整数边界检测宏既适用于有符号整数,也适用于无符号整数 *//* 判断是否有a<=x<=b */#define lesseq_lessqe(x原创 2010-03-28 21:42:00 · 1774 阅读 · 0 评论 -
我的C实践(8):字搜索
字搜索就搜索一个数中具有某些特征的位。实现如下:/* wsearch.c:字搜索 *//* 从左边寻找第一个0字节:第0(1,2,3)个字节是0时,返回0(1,2,3),否则返回4 */int zbytel(unsigned x){ if((x>>24)==0) return 0; else if((x & 0x00ff0000)==0) return 1; els原创 2010-04-11 21:23:00 · 1057 阅读 · 0 评论 -
我的C实践(9):位和字节的重排
位和字节的重排在密码学算法中有广泛的应用。/* rearran.c:位和字节的重排 *//* 位反转:以字的中心为对称点进行位反射 例如: abcd efgh ijkl mnop ABCD EFGH IJKL MNOP 位反转:PONM LKJI HGFE DCBA ponm lkji hgfe dcba */unsigned rev(unsigned x){原创 2010-04-11 21:27:00 · 1559 阅读 · 0 评论 -
C标准库源码解剖(9):控制函数assert.h, setjmp.h和signal.h
控制函数用于对C语言程序的标准控制流(如if/else、switch、for等)提供扩展,在头文件assert.h、setjmp.h和signal.h中提供,分别提供表达式断言功能、非本地跳转功能、信号处理功能。 1、assert.h:提供用于断言的assert宏。程序中若没有定义NDEBUG,则asset(exp)对表达式exp进行断言,若断言为假(即为0),则会调用__a原创 2009-10-19 23:14:00 · 3729 阅读 · 2 评论 -
C标准库源码解剖(11):扩展整数类型stdint.h和inttypes.h
C语言的基本精神是让实现选择标准类型的长度,但是这种指导思想使可移植代码难以编写。C99中引入了stdint.h和inttypes.h,对整数类型的定义和格式转换进行了规范。这种扩展整数类型的定义非常清晰,从类型名字上就可以看出它的长度,这有利于编写可移植的代码。stint.h对整数类型进行定义,inttypes.h包含了stdint.h并增加了可移植的格式控制串和转换函数。 1原创 2009-10-20 18:06:00 · 6363 阅读 · 0 评论 -
我的C实践(3):用宏和位运算来实现整数集合
整数集合用一个位向量来表示。这里是无符号整数的集合,它适合存放范围在0~N-1之内的小整数,N是位向量的位数(这里为32位的unsigned int)。每个整数用集合中的一个位来表示,第i位为1(i=0~N-1),当且仅当整数i属于集合。 1、头文件set.h:整数集合的接口。/* * set.h:整数集合,是一个位向量。适合存放范围在0~N-1之内的小整数,N是uns原创 2009-09-30 12:34:00 · 1472 阅读 · 0 评论 -
C标准库源码解剖(1):类型相关的定义
说明:整个C标准库解剖系列环境为Ubuntu 8.04,编译器为gcc 4.2.4,由于linux系统中只有C标准库的头文件(在/usr/include下),函数库被编译成了程序库,没有源代码,因此对源代码的解剖用的是glibc 2.9,可从GNU的官方站点上下载。 类型相关定义包括limits.h、float.h、stddef.h、stdbool.h、stdarg.h、iso6原创 2009-09-30 13:53:00 · 4541 阅读 · 1 评论 -
我的C实践(2):联合的妙用
在C语言中,联合类型是一种比较特殊的类型,其多个成员共享一个存储区(为最大成员的长度),一次只能包含一个成员值,会进行内存对齐。对联合类型进行sizeof运算会包括所有成员所需要的存储空间量,还包括成员间和成员后面的填充空间。联合类似于其他语言中的“变体记录”,如果联合的长度很大或者有大量的联合,则可以大大节省存储空间。 1、联合只能一次赋值一个成员,并使用它,但C语言没有提供查原创 2009-09-26 09:52:00 · 1390 阅读 · 0 评论 -
C标准库源码解剖(2):错误报告errno.h
errno.h在/usr/include下,定义了存放错误码的全局变量errno,及错误码EDOM,ERANGE,EILSEQ。它包含了/usr/include/bits下的bits/errno.h头文件。bits/errno.h不是标准C库中的头文件,在Linux中它为错误码提供数值定义,对标准C中指定的错误码EDOM,ERANGE,EILSEQ定义具体的数值。 bits/er原创 2009-10-04 19:19:00 · 4395 阅读 · 2 评论 -
C标准库源码解剖(4):字符串处理函数string.h和wchar.h
string.h中包含了所有的字符串处理函数,也包含了内存处理函数,因为这些内存处理函数(如比如、复制、搜索)的功能与字符串处理函数功能类似。我们是用通用指针来指向内存块的,通用指针可以用char*类型(传统C语言),也可以用void*类型(标准C语言)。每个函数都有对应的宽字符版本,在wchar.h中。 string.h中包含的标准库函数:strcat,strncat,strc原创 2009-10-08 12:39:00 · 6059 阅读 · 1 评论 -
C标准库源码解剖(3):字符处理函数ctype.h和wctype.h
字符处理包括分类(即属性判断)和转换函数。ASCII字符主要可分类为控制字符、空白字符、可打印字符、数字字符、字母字符(大写和小写)、标点符号等。 1、ctype.h:标准的属性判断函数有isalnum,isalpha,iscntrl,isdigit,isxdigit,isgraph,isprint,ispunct,islower,isupper,isspace, isbla原创 2009-10-05 18:47:00 · 7211 阅读 · 2 评论 -
C标准库源码解剖(5):字符串处理函数string.h和wchar.h(续)
3、字符串复制strcpy,strncpy,wcscpy,wcsncpy:将字符串src(或其前n个字符)复制到dest中,覆盖dest的内容。实现中先检查指针是否越界,计算指针dest到src的偏移,然后开始做复制操作,复制到dest的开始位置处,以覆盖dest的内容。对strncpy,也采用了每4个字符作为一组来进行复制的方法,以加快复制速度。/* strcpy.c:strcpy函原创 2009-10-08 12:46:00 · 2772 阅读 · 0 评论 -
C标准库源码解剖(6):字符串处理函数string.h和wchar.h(续)
8、特定区域的字符串比较和转换strcoll,strxfrm,wcscoll,wcsxfrm:strcoll使用当前的区域设置来比较字符串,strxfrm使用当前的区域设置来转换字符串。当前区域设置由LL_COLLATE宏指定。它们均调用带有区域设置参数的内部版本strcoll_l和strxfrm_l来完成实际的工作。/* strcoll.c:strcoll函数的实现 */#inc原创 2009-10-08 12:56:00 · 3415 阅读 · 0 评论 -
C标准库源码解剖(7):日期与时间函数time.h
日期与时间函数在time.h中,主要表示处理器时钟的clock_t类型、表示时间的time_t类型、时钟每秒滴答数CLOCKS_PER_SEC、描述日历时间的struct tm结构、函数clock、time、asctime、ctime、gmtime、localtime、mktime、difftime、strftime、wcsftime(宽字符版本),其他的都是非标准扩展。 1、t原创 2009-10-09 19:27:00 · 6441 阅读 · 5 评论 -
C标准库源码解剖(8):日期与时间函数time.h(续)
4、difftime函数:从日历时间t1中减去日历时间t0,返回double类型的差值(秒数)。/* difftime.c:difftime函数的实现 */#include #include #include #include #define TYPE_BITS(type) (sizeof (type) * CHAR_BIT)#define TYPE_FLOAT原创 2009-10-09 19:32:00 · 5360 阅读 · 1 评论 -
我的C实践(7):位计数
位计数就是对一个数中具有某些特征的位进行计数。看下面实现:/* bitscount.c:位计数 *//* 计算x中1位的数目:方案1,采用分治策略 */inline int pop(unsigned x){ /* 对每个2位字段,先析出其右端的1位,再析出其左端的1位,然后让这两个位相加 */ x=(x & 0x55555555)+((x>>1) & 0x55555555)原创 2010-04-11 21:16:00 · 1191 阅读 · 1 评论