C标准库-1

目录

第一章:<assert.h>

第二章:<ctype.h>

第三章:<errno.h>

第四章:<float.h>

第五章:<limits.h>

第六章:<locale.h>

第七章:<math.h>

第八章:<setjmp.h>

第九章:<signal.h>

第十章:<stdarg.h>

第十一章:<stddef.h>





第一章:<assert.h>

#ifdef NDEBUG
    #define assert(test)    ((viod)0)
#else
    #define assert(test)    ((test)?(void)0:_ASSERT{__FILE__":"__STR(__LINE__)""#test})
#endif

宏assert向程序中加入诊断,当它执行的时候,如果表达式为假(也就是说和0相等),assert宏就按照实现定义的格式向标准错误文件写入特定调用的失败信息(包括参数文本,源文件名字__FILE__,源文件行数__LINE__),然后它调用abort函数

打开断言:
#undef NDEBUG
#include <assert.h>
assert(signal(SIGANRT, &field_abort) != SIG_ERR);
关闭断言:
#define NDEBUG

第二章:<ctype.h>

宏带来的意外:C程序员更喜欢宏,因为ie宏可以让程序员编写出和函数调用一样可读但效率更高的代码,注意
宏比函数调用快,但展开代码比函数调用大。
宏可能会展开为一个子表达式,可以用圆括号消除这种弊端。
宏展开后,某些参数可能执行不止一次(++操作),或根本不执行。

转换表:以islower()为例
#define _LO    0x10
extern const short *Ctype;
#define islower(c)    (_Ctype[(int)(c)] & _LO)
假设传进来的c='a'
#define islower('a')    (_Ctype[(int)('a')] & 0x10)
(_Ctype[97] & 0x10)
查_Ctype表的 _Ctype[97] == 0x10
islower('a') = (0x10 & 0x10) = 1

ctype.h中的函数

 int isalnum (int c) 测试字符是否为英文或数字,在标准c中相当于使用“isalpha(c) || isdigit(c);”
 int isalpha (int c) 检查参数c是否为英文字母 ,在标准c中相当于使用“isupper(c)||islower(c);”
 int isascii(int c);  检查参数c是否为ASCII码字符,也就是判断c的范围是否在0到127之间。
 int iscntrl(int c);  检查参数c是否为ASCII控制码,也就是判断c的范围是否在0到30之间。
 int isdigit(int c);  检查参数c是否为阿拉伯数字0到9。
 int isgraph (int c); 检查参数c是否为可打印字符,若c所对映的ASCII码可打印,且非空格字符则返回TRUE。
 int islower(int c);  检查参数c是否为小写英文字母。
 int isprint(int c);  检查参数c是否为可打印字符,若c所对映的ASCII码可打印,其中包含空格字符,则返回TRUE。
 int isspace(int c);  检查参数c是否为空格字符,也就是判断是否为空格('')、定位字符('\t')、CR('\r')、换行('\n')、垂直定位字符('\v')或翻页('\f')的情况。
 int ispunct(int c);  检查参数c是否为标点符号或特殊符号。返回TRUE也就是代表参数c为非空格、非数字和非英文字母。
 int isupper(int c);  检查参数c是否为大写英文字母。
 int isxdigit (int c);检查参数c是否为16进制数字,只要c为下列其中一个情况则返回TRUE。16进制数字:0123456789ABCDEF。

int tolower(int c); //把大写字母转换为小写字母
int toupper(int c); //把小写字母转换为大写字母

第三章:<errno.h>

define errno (*__errno_location ())
宏errno可以被扩展为一个可更改的左值,可以扩展像_Erfun()这样的表达式,检查错误的时候,它会调用一个函数告诉程序去哪里找
errno测试
perror("NO error reported as");
assert(errno == ERANGE)


每次在使用系统调用(如ioctl())之后,检查一下全局变量errno是一种很好的做法,它隶属于ANSI C标准
#define EPERM 1
#define ENOENT 2
#define ENOFILE ENOENT
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
#define EDOM 33
#define EDEADLK 36
#define ENAMETOOLONG 38
#define ENOLCK 39
#define ENOSYS 40
#define ENOTEMPTY 41

 


 


第四章:<float.h>

定义double, float, long double类型的宏

#define DBL_EPSILON      2.2204460492503131E-16 
#define FLT_EPSILON     1.19209290E-07F 
#define LDBL_EPSILON     1.084202172485504E-19 

第五章:<limits.h>

定义数据类型的上限值和下限值的宏,例:

#define CHAR_BIT    8

#define SHRT_MIN	(-32768)
#define SHRT_MAX	32767

#if __WORDSIZE == 64
#define LONG_MAX	9223372036854775807L
#else
#define LONG_MAX	2147483647L
#endif
#define LONG_MIN	(-LONG_MAX - 1L)

#define INT_MAX    2147483647
#define INT_MIN    (-INT_MAX - 1)

第六章:<locale.h>

不同国家书写格式不一样,如:月-日-年。区域设置定义了区域环境,主要有以下几类
#define LC_CTYPE    __LC_CTYPE    (字符分类)
#define LC_NUMERIC    __LC_NUMERIC    (其他数字格式)
#define LC_TIME    __LC_TIME    (时间)
#define LC_COLLATE    __LC_COLLATE    (控制整理顺序)
#define LC_MONETARY    __LC_MONETARY    (货币格式)
区域设置控制
char *setlocale(int category, const char *locale);
数字格式习惯查询
struct lconv *localeconv(void);

 


第七章:<math.h>

HUGE_VAL ——这个宏通常会展开一个非常大的double常量,在那些对无穷大(Inf)不提供特殊编码的机器上,这是警告值域错误的最好方式。
1、 三角函数
double sin (double);正弦
double cos (double);余弦
double tan (double);正切
2、反三角函数
double asin (double); 结果介于[-PI/2, PI/2]
double acos (double); 结果介于[0, PI]
double atan (double); 反正切(主值), 结果介于[-PI/2, PI/2]
double atan2 (double, double); 反正切(整圆值), 结果介于[-PI, PI]
3、双曲三角函数
double sinh (double);
double cosh (double);
double tanh (double);
4、指数与对数
double frexp(double value,int *exp);这是一个将value值拆分成小数部分f和(以2为底的)指数部分exp,并返回小数部分f,即f*2^exp。其中f取值在0.5~1.0范围或者0。
double ldexp(double x,int exp);这个函数刚好跟上面那个frexp函数功能相反,它的返回值是x*2^exp
double modf(double value,double *iptr);拆分value值,返回它的小数部分,iptr指向整数部分。
double log (double); 以e为底的对数
double log10 (double);以10为底的对数
double pow(double x, double y);计算以x为底数的y次幂
float powf(float x, float y); 功能与pow一致,只是输入与输出皆为浮点数
double exp (double);求取自然数e的幂
double sqrt (double);开平方
5、取整
double ceil (double); 取上整,返回比x大的最小整数
double floor (double); 取下整,返回比x小的最大整数,即高斯函数 [x]
6、绝对值
int abs(int i); 求整型的绝对值
double fabs (double);求实型的绝对值
double cabs(struct complex znum) ;求复数的绝对值
7、标准化浮点数
double frexp (double f, int *p); 标准化浮点数, f = x * 2^p, 已知f求x, p ( x介于[0.5, 1] )
double ldexp (double x, int p); 与frexp相反, 已知x, p求f
8、取整与取余
double modf (double, double*); 将参数的整数部分通过指针回传, 返回小数部分
double fmod (double, double); 返回两参数相除的余数
9、其他
int rand(void) 这是随机函数,产生的是从-90到32767的随机值
double hypot(double x, double y);已知直角三角形两个直角边长度,求斜边长度
double ldexp(double x, int exponent);计算x*(2的exponent次幂)
double poly(double x, int degree, double coeffs [] );计算多项式
int matherr(struct exception *e);数学错误计算处理程序

 


第八章:<setjmp.h>

goto语句不能进行非本地跳转,C库用setjmp实现

typedef int jmp_buf[_NSETJMP],    可以把它当成标号数据对象类型看待
#define setjmp(env)    _Setjmp(env),    把当前调用的上下文信息存储到一个jmp_buf类型数据对象中,并在你想把控制权传递给相应的longjmp调用的地方作标记
void longjmp(jmp_buf env, int val),    实现非本地跳转

setjmp的两个危险

  • 包含宏setjmp的表达式
  • 在执行setjmp的函数中声明动态存储空间
/*测试*/
static jmp_buf b0;
static void jmpto(int n)
{
    longjmp(b0, n);
}
static int tryit(void)
{
    switch(setjmp(b0)){
    case 0:
        ....
        jmpto(0);
        break;
    case 1:
        ....    
    }
}

 


第九章:<signal.h>

#define SIGHUP           1
#define SIGINT           2
#define SIGQUIT          3
#define SIGILL           4
#define SIGTRAP          5
#define SIGABRT          6
#define SIGIOT           6
#define SIGSTKFLT        7
#define SIGFPE           8
#define SIGKILL          9
#define SIGBUS          10
#define SIGSEGV         11
#define SIGXCPU         12
#define SIGPIPE         13
#define SIGALRM         14
#define SIGTERM         15
#define SIGUSR1         16
#define SIGUSR2         17
#define SIGCHLD         18
#define SIGPWR          19
#define SIGVTALRM       20
#define SIGPROF         21
#define SIGIO           22
#define SIGPOLL         SIGIO
#define SIGWINCH        23
#define SIGSTOP         24
#define SIGTSTP         25
#define SIGCONT         26
#define SIGTTIN         27
#define SIGTTOU         28
#define SIGURG          29
#define SIGXFSZ         30
#define SIGUNUSED       31
#define SIGSYS          31 /* Linux doesn't use this */

指定信号处理

void (*signal(int sig, void (*func)(int)))(int);

发送信号

int raise(int sig);

发送信号到进程

int kill(pid_t pid, int sig);       

测试

static void field_fpe(int sig)
{
    assert(sig == SIGFPE);
    puts("SUCCESS testing <signal.h>");
    exit(EXIT_SUCCESS);
}
int main()
{
    assert(signal(SIGFPE, &field_fpe) == SIG_DEL);
    raise(SIGFPE);
    puts("FAILURE testing <signal.h>");
}

 


第十章:<stdarg.h>

va_list 是一个适合保存宏va_start、va_arg、va_end所需要信息的类型。
//一个可变参数函数至少声明一个固定参数,宏va_start引用最后一个固定参数,所以它能够对可变参数表进行定位。
void va_start(va_list ap, parmN);
//一个函数在返回它的调用者之前一定要调用va_end。
void va_end(va_list ap);
type va_arg(va_list ap, type);

测试

static int tryit(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    for(; *fmt; ++fmt){
        switch(*fmt){
        case 'd':
            va_arg(ap, int);
            break;
        case 'c':
            ....
        }
    }
    va_end(ap);    
}

 


第十一章:<stddef.h>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值