当前位置:首页 >> 信息与通信 >>

Keil头文件简介


Keil 中 INTRINS.H 的作用

在 C51 单片机编程中,头文件 INTRINS.H 的函数使用起来,就会让你像在用汇编 时一样简便.

内部函数 描述 _crol_ 字符循环左移 _cror_ 字符循环右移 _irol_ 整数循环左移 _iror_ 整数循环右移 _lrol_ 长整数循环左移 _lror_ 长整数循环右移 _n

op_ 空操作 8051 NOP 指令 _testbit_ 测试并清零位 8051 JBC 指令

函数名: _crol_,_irol_,_lrol_ 原 型: unsigned char _crol_(unsigned char val,unsigned char n); unsigned int _irol_(unsigned int val,unsigned char n); unsigned int _lrol_(unsigned int val,unsigned char n);

举例:

_crol_,_cror_:将 char 型变量循环向左(右)移动指定位数后返回 _testbit_: 相当于 JBC bitvar 测试该位变量并跳转同时清除。 _chkfloat_: 测试并返回源点数状态。

就是汇编中的子函数。 _crol_,_cror_:如国二进制数为 01010101 那么_crol_(1) 左移 1 位后将高位 补低位。 结果 10101010。 功 能: _crol_, _irol_, _lrol_以位形式将 val 左移 n 位, 该函数与 8051“RLA” 指令相关,上面几个函数不同于参数类型。 例: #include <intrins.h> main() { unsigned int y;

C-5 1 程序设计 37 y=0x00ff; y=_irol_(y,4); }

函数名: _cror_,_iror_,_lror_ 原 型: unsigned char _cror_(unsigned char val,unsigned char n); unsigned int _iror_(unsigned int val,unsigned char n); unsigned int _lror_(unsigned int val,unsigned char n); 功 能: _cror_, _iror_, _lror_以位形式将 val 右移 n 位, 该函数与 8051“RRA” 指令相关,上面几个函数不同于参数类型。 例: #include <intrins.h> main() { unsigned int y; y=0x0ff00; y=_iror_(y,4); }

函数名: _nop_ 原 型: void _nop_(void); 功 能:_nop_产生一个 NOP 指令,该函数可用作 C 程序的时间比较。C51 编译器 在_nop_函数工作期间不产生函数调用,即在程序中直接执行了 NOP 指令。 例: P()=1; _nop_(); P()=0;

函数名: _testbit_ 原 型:bit _testbit_(bit x); 功 能:_testbit_产生一个 JBC 指令,该函数测试一个位,当置位时返回 1,否 则返回 0。 如果该位置为 1, 则将该位复位为 0。 8051 的 JBC 指令即用作此目的。 _testbit_只能用于可直接寻址的位;在表达式中使用是不允许的。

Math.h 库 函数:sin 功能:计算弧度的正弦值。 使用说明:sin(x),x 为传入的弧度值。 函数:cos 功能:计 算弧度的余弦值。 使用说明:cos(x),x 为传入的弧度值。 函数:tan 功能:计算弧度的正切值。 使用说 明:tan(x),x 为传入的弧度值。 函数:sinh 功能:计算弧度的双曲正弦值。 使用说明:sinh(x),x 为传入 的弧度值。 函数:cosh 功能:计算弧度的双曲余弦值。 使用说明:cosh(x),x 为传入的弧度值。 函 数:tanh 功能:计算弧度的双曲正切值。 使用说明:tanh(x),x 为传入的弧度值。 函数:asin 功能: 计算弧度的反正弦值。 使用说明:asin(x),x 为传入的弧度值。 函数:acos 功能:计算弧度的反余弦值。 使 用说明:acos(x),x 为传入的弧度值。 函数:atan 功能:计算弧度的反正切值。 使用说明:atan(x),x 为 传入的弧度值。 函数:atan2 功能:计算两个浮点数类型值之比的反正切值。 使用说明:atan2(x,y),该函数会 计算出 x/y 的反正切值。 函数:log 功能:计算浮点数的自然对数值。 使用说明:log(x),计算以 e 为底的对数。

函数:log10 功能:以 10 为底来计算对数值。 使用说明:log10(x),计算以 10 为底的对数。 函 数:pow 功能:计算出某数的某次方值。 使用说明:pow(x,y),计算 x 的 y 次方。 函数:exp 功能:计算 浮点为数的指数函数值。 使用说明:exp(x),计算 e 的 x 次方。 函数:frexp 功能:调整浮点变量,将原变量的数值 部分调整到介于 0.5 和 1 之间。 使用说明:double y = frexp(double x, int *expptr),函数 frexp 将 double x 的数值部分调整成介于 0.5 和 1 之间,将调整好的新数值部分回传给 y,而指 数部分将传给指针 expptr 所指的位置,使 x=y*(2^expptr)。 如 x=10.5428,y 将为 0.658925,*expptr 将为 4,有算式 10.5428=0.658925*(2^4)。 函 数:ldexp 功能:根据所给予的数值部分 x 和指数部分 y 计算出浮点数 x*(2^y)的值。 使用说明:ldexp(double x, int y),将返回 x*(2^y)的值。 函数:_cabs 功能:取得复数结构的绝对值。 使用说明:double y = _cabs(struct _complex x),设复数 x 的实数部分为 a, 虚数部分为 b,则 cabs 将会计算 x.a 的平方加 x.b 的平方的和开根号的值。 函数:fabs 功 能:计算浮点数变量的绝对值。 使用说明:fabs(x),计算 x 的绝对值。 函数:hypot 功能:计算已知两边的直角三 角形的斜边长。 使用说明:hypot(x,y),计算 x 与 y 的平方和,再开根号后的值。 函数:ceil 功能:计算不小于 某浮点数的最小整数。 使用说明:ceil(x)。 函数:floor 功能:计算不大于某浮点数的最大整数。 使用说 明:floor(y)。

函数:modf 功能:求浮点数的小数部分。 使用说明:double z = modf(double x, double *y),x 的整数部分会写入*y, 返回小数部分。如 x 为 99.5,z 将为 0.5,*y 将为 99。 函 数:fmod 功能:求两浮点数相除后的余数。 使用说明:double z = fmod(double x, double y),z 等于 x 除以 y 后的余数。 函数:sqrt 功能:求某非负浮点数的平方根。 使用说明:sqrt(x)。 注: 以上函数均在 mingw gcc 4.5.0 下用小例程测试通过。在 gcc 4.5.0 中, 求整数绝对值的 abs 函数是在 stdlib.h 头文件中提供。

assert 的用法
assert(<expression>); 当 expression 结果为“假”时,会在 stderr 中输出这条语句所在的文件名和行号,以及这条 表达式。这只在调试版本中起作用,在 Release 版本中不会产生任何代码。 通常当我们使用 assert 时,都在强烈说明一个含义:在这里必然如此。它通常用于一个函 数的先验条件和后验条件的检查。比如我写一个 C 风格复制字符串的函数,并且认为调用 者不应该传入 NULL 指针: char * clone_string(const char * source) { char * result; assert(source != NULL); result = (char *)malloc(strlen(source) + 1); if (result != NULL) { strcpy(result, source); assert(strcmp(result, source) == 0); } return result; } 注意到我对 source 是否为 NULL 是用 assert 检查的, 但对 result 是不是为 NULL 是用 if 语 句判断的,这是因为在调用代码正确的情况下 source 必然不为 NULL,如果断言失败,说明 调用代码中有错误,需要修改;但 result 作为 malloc 的返回值则不一定,在 malloc 代码无 误的情况下仍然可能返回 NULL——当内存块不足时。最后又用 assert 对 strcpy 的结果进行 检查,因为只要代码正确,无论什么情况 strcpy 应该正常完成复制,它没有 malloc 那种异 常情况存在。 在《编程精粹》第二章(自己设计并使用断言)开始的一段话把 assert 的用途说的很清楚: 利用编译程序自动查错固然好,但我敢说只要你观察一下项目中那些比较明显的错误,就 会发现编译程序所查出的只是其中的一小部分。 我还敢说, 如果排除掉了程序中的所有错误 那么在大部分时间内程序都会正确工作。 还记得第 1 章中的下面代码吗? strCopy = memcpy(malloc(length), str, length);

该语句在多数情况下都会工作得很好,除非 malloc 的调用产生失败。当 malloc 失败时, 就会给 memcpy 返回一个 NULL 指针。由于 memcpy 处理不了 NULL 指针,所以出现了错 误。如果你很走运,在交付之前这个错误导致程序的瘫痪,从而暴露出来。但是如果你不走 运,没有及时地发现这个错误,那某位顾客就一定会“走运”了。

编译程序查不出这种或其他类似的错误。同样,编译程序也查不出算法的错误,无法验证 程序员所作的假定。或者更一般地,编译程序也查不出所传递的参数是否有效。 寻找这种错误非常艰苦,只有技术非常高的程序员或者测试者才能将它们根除并且不会引 起其他的问题。 然而假如你知道应该怎样去做的话,自动寻找这种错误就变得很容易了。

两个版本的故事 让我们直接进入 memcpy,看看怎样才能查出上面的错误。最初的解决办法是使 memcpy 对 NULL 指针进行检查, 如果指针为 NULL, 就给出一条错误信息, 并中止 memcpy 的执行。 下面是这种解法对应的程序。

void {

memcpy(void*

pvTo,

void*

pvFrom,

size_t

size)

void* void* if(pvTo {

pbTo pbFrom ==

= =

(byte*)pvTo; (byte*)pvFrom; | | pvFrom == NULL)

NULL

fprintf(stderr, abort(); } while(size-->0) *pbTo++ return(pvTo); } ==

“Bad

args

in

memcpy\n”);

*pbFrom++;

只要调用时错用了 NULL 指针,这个函数就会查出来。所存在的唯一问题是其中的测试代 码使整个函数的大小增加了一倍, 并且降低了该函数的执行速度。 如果说这是“越治病越糟”, 确实有理,因为它一点不实用。要解决这个问题需要利用 C 的预处理程序。 如果保存两个版本怎么样?一个整洁快速用于程序的交付;另一个臃肿缓慢件(因为包括 了额外的检查) ,用于调试。这样就得同时维护同一程序的两个版本,并利用 C 的预处理程 序有条件地包含或不包含相应的检查部分。 void { void* void* #ifdef if(pvTo { fprintf(stderr, abort(); } #endif while(size-->0) *pbTo++ return(pvTo); } 这种想法是同时维护调试和非调试(即交付)两个版本。在程序的编写过程中,编译其调 试版本,利用它提供的测试部分在增加程序功能时自动地查错。在程序编完之后,编译其交 付版本,封装之后交给经销商。 当然,你不会傻到直到交付的最后一刻才想到要运行打算交付的程序,但在整个的开发工 == *pbFrom++; “Bad args in memcpy\n”); pbTo pbFrom DEBUG == NULL | | pvFrom == NULL) = = (byte*)pvTo; (byte*)pvFrom; memcpy(void* pvTo, void* pvFrom, size_t size)

程中,都应该使用程序的调试版本。正如在这一章和下一章所建,这样要求的主要原因是它 可以显著地减少程序的开发时间。 读者可以设想一下: 如果程序中的每个函数都进行一些最 低限度的错误检查, 并对一些绝不应该出现的条件进行测试的活, 相应的应用程序会有多么 健壮。 这种方法的关键是要保证调试代码不在最终产品中出现。 利用断言进行补救 说老实话 memcpy 中的调试码编得非常蹩脚,且颇有点喧宾夺主的意味。因此尽管它能产 生很好的结果, 多数程序员也不会容忍它的存在, 这就是聪明的程序员决定将所有的调试代 码隐藏在断言 assert 中的缘故。assert 是个宏,它定义在头文件 assert.h 中。assert 虽然不过 是对前面所见#ifdef 部分代码的替换,但利用这个宏,原来的代码从 7 行变成了 1 行。 void { void* void* pbTo pbFrom != = = (byte*)pvTo; (byte*)pvFrom; && pvFrom != NULL); memcpy(void* pvTo, void* pvFrom, size_t size)

assert(pvTo

NULL

while(size-->0) *pbTo++ return(pvTo); } aasert 是个只有定义了 DEBUG 才起作用的宏,如果其参数的计算结果为假,就中止调用 程序的执行。因此在上面的程序中任何一个指针为 NULL 都会引发 assert。 assert 并不是一个仓促拼凑起来的宏,为了不在程序的交付版本和调试版本之间引起重要 的差别,需要对其进行仔细的定义。宏 assert 不应该弄乱内存,不应该对未初始化的数据进 行初始化, 即它不应该产主其他的副作用。 正是因为要求程序的调试版本和交付版本行为完 全相同,所以才不把 assert 作为函数,而把它作为宏。如果把 assert 作为函数的话,其调用 就会引起不期望的内存或代码的兑换。要记住,使用 assert 的程序员是把它看成一个在任何 系统状态下都可以安全使用的无害检测手段 == *pbFrom++;

ctype.h
概述: ctype.h 为我们提供了很多了与字符相关的判断或处理函数,方便地对字符做判断和转 换大小写等处理。

下面以函数为单位进行学习。

isalnum 功能: 测试传入参数其对应的 ASCII 符号是否为数字或英文字母,当传入参数为 A~Z、a~z、 0~9,则函数返回非零值,否则返回零。 返回非零值的状况:传入字符 A~Z、a~z、0~9 或数 65~90、97~122、48~57。

isalpha 功能: 测试传入参数其对应的 ASCII 符号是否为英文字母,当传入参数为 A~Z、a~z,则函数 返回非零值,否则返回零。 返回非零值的状况:传入字符 A~Z、a~z 或数 65~90、97~122。

isdigit 功能: 测试传入参数其对应的 ASCII 符号是否为阿拉伯数字,当传入参数为 0~9,则函数返回 非零值,否则返回零。 返回非零值的状况:传入字符 0~9,或数 48~57。

isxdigit 功能: 测试传入参数是否为十六进制数字字符,当传入参数为 0~9、A~F、a~f,则函数返回非 零值,否则返回零。 返回非零值的状况:传入字符 0~9、a~f、A~F 或数 48~57、65~70、97~102。

isupper 功能: 测试传入参数是否为大写英文字母,当传入参数为 A~Z,则函数返回非零值,否则返 回零。 返回非零值的状况:传入字符 A~Z 或数 97~122。

islower 功能: 测试传入参数是否为小写英文字母,当传入参数为 a~z,则函数返回非零值,否则返回 零。 返回非零值的状况:传入字符 a~z 或数 97~122。

isascii 功能: 测试传入参数是否为有效的 ASCII 字符,当传入参数为有效的 ASCII 标准字符时,函 数返回非零值,否则返回零。 返回非零值的状况:传入对应 ASCII 码为 0~127 的字符或者传入数 0~127。

isgraph 功能: 测试传入参数是否为除空格外的可输出字符,是则返回非零值,否则返回零。 返回非零值的状况:传入对应 ASCII 码为 33~126 的字符或者传入数 33~126。

isprint

功能: 测试传入参数是否为可输出字符,是则返回非零值,否则返回零。 返回非零值的状况:传入对应 ASCII 码为 32~126 的字符或者传入数 32~126。

isspace 功能: 测试传入参数是否为空字符,是则返回非零值,否则返回零。 返回非零值的状况:传入对应 ASCII 码为 9、10、11、12、13、32 的字符或者这几个 数。

iscntrl

功能: 测试传入参数是否为控制字符,当传入参数为控制字符时,函数返回非零值,否则返回 零。 返回非零值的状况:传入对应 ASCII 码为 0~31、127 的字符或者这些数。

ispunct 功能: 测试传入参数是否为标点符号,是则函数返回非零值,否则返回零。 返回非零值的状况:传入对应 ASCII 码为 33~47、58~64、91~96、123~126 的字符或这 些数。

iscsym

功能: 测试传入参数是否为英文字母、 下划线或者数字, 若是则函数返回非零值, 否则返回零。 返回非零值的状况:传入字符 0~9、A~Z、_、a~z 或数 48~57、65~90、95、97~122。

toupper

功能: 将输入的小写英文字母转换为大写英文字母, 若传入的不为小写英文字母, 则返回原字 符。 注:_toupper 与其处理方式不同,是均返回 (原字符-32) 。

tolower 功能: 将输入的大写英文字母转换为小写英文字母, 若传入的不为大写英文字母, 则返回原字

符。 注:_tolower 与其处理方式不同,是均返回 (原字符+32) 。

另: 以上函数均适用于标准 ASCII 码的相关处理,即 0~127 范围,该头文件中也提供了处 理宽字符时相应的函数版本,即形如 iswalnum、iswalpha 等,功能与此类似,在此就不一一 列举,对以上大部分函数可以使用以下程序来做一个简单的测试:

view sourceprint?#include <iostream> #include <cctype>

int main() { int i; for(i=0; i<128; i++) { int j = 要测试的函数名(i); char c = i; if(0!=j) std::cout << i << '\t' << c << std::endl; } return 0; }

?

一、errno 的由来 在 C 编程中,errno 是个不可缺少的变量,特别是在网络编程中。如果你没有用过 errno, 那只能说明你的程序不够健壮。当然,如果你是 WIN32 平台的 GetLastError(),效果也是一 样的。 为什么会使用 errno 呢?个人认为,这是系统库设计中的一个无奈之举,他更多的是个技 巧,而不是架构上的需要。我们观察下函数结构,可以发现,函数的参数返回值只有一个, 这个返回值一般可以携带错误信息,比如负数表示错误,而正数表述正确的返回值,比如 recv 函数。 但是对于一些返回指针的函数, char *get_str(); 如: 这个方法显然没有用的。 NULL 可以表示发生错误,但是发生什么错误却毫无办法。于是,errno 就诞生了。全局变量 errno 可以存放错误原因,当错误发生时,函数的返回值是可以通过非法值来提示错误的发生。 二、errno 的线程安全 errno 是全局变量,但是在多线程环境下,就会变得很恐怖。当你调用一个函数时,发现 这个函数发生了错误,但当你使用错误原因时,他却变成了另外一个线程的错误提示。想想 就会觉得是件可怕的事情。 将 errno 设置为线程局部变量是个不错的主意,事实上,GCC 中就是这么干的。他保证 了线程之间的错误原因不会互相串改, 当你在一个线程中串行执行一系列过程, 那么得到的 errno 仍然是正确的。 看下,bits/errno.h 的定义: # ifndef __ASSEMBLER__ /* Function to get address of global `errno' variable. */ extern int *__errno_location (void) __THROW __attribute__ ((__const__)); # if !defined _LIBC || defined _LIBC_REENTRANT /* When using threads, errno is a per-thread value. */ # define errno (*__errno_location ()) # endif # endif /* !__ASSEMBLER__ */ 而 errno.h 中是这样定义的: /* Declare the `errno' variable, unless it's defined as a macro by bits/errno.h. This is the case in GNU, where it is a per-thread variable. This redeclaration using the macro still works, but it will be a function declaration without a prototype and may trigger a -Wstrict-prototypes warning. */ #ifndef errno extern int errno; #endif 显然,errno 实际上,并不是我们通常认为的是个整型数值,而是通过整型指针来获取值的。 这个整型就是线程安全的。

?

三、errno 的实现 static pthread_key_t key; static pthread_once_t key_once = PTHREAD_ONCE_INIT; static void make_key() { (void) pthread_key_create(&key, NULL); } int *_errno() { int *ptr ; (void) pthread_once(&key_once, make_key); if ((ptr = pthread_getspecific(key)) == NULL) { ptr = malloc(sizeof(int)); (void) pthread_setspecific(key, ptr); } return ptr ; }

四、errno 的应用 errno 在库中得到广泛的应用,但是,错误编码实际上不止那么多。我们需要在自己的系 统中增加更多的错误编码。一种方式就是直接利用 errno,另外一种方式就是定义自己的 user_errno。 使用 errno,strerror 可能无法解析,这需要自己解决。但 errno 使用线程变量的方式值得 借鉴。 errno .h errno.h- 查看错误代码 errno 是调试程序的一个重要方法。当 linuc C api 函数发生异常时,一般会将 errno 变量(需 include errno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推 测出错的原因。 在实际编程中用这一招解决了不少原本看来莫名其妙的问题。 比较麻烦的是 每次都要去 linux 源代码里面查找错误代码的含义,现在把它贴出来,以后需要查时就来这 里看了。 以下来自 linux 2.4.20-18 的内核代码中的/usr/include/asm/errno.h #ifndef _I386_ERRNO_H #define _I386_ERRNO_H #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */

?

#define EIO 5 /* I/O error */ #define ENXIO 6 /* No such device or address */ #define E2BIG 7 /* Arg list too long */ #define ENOEXEC 8 /* Exec format error */ #define EBADF 9 /* Bad file number */ #define ECHILD 10 /* No child processes */ #define EAGAIN 11 /* Try again */ #define ENOMEM 12 /* Out of memory */ #define EACCES 13 /* Permission denied */ #define EFAULT 14 /* Bad address */ #define ENOTBLK 15 /* Block device required */ #define EBUSY 16 /* Device or resource busy */ #define EEXIST 17 /* File exists */ #define EXDEV 18 /* Cross-device link */ #define ENODEV 19 /* No such device */ #define ENOTDIR 20 /* Not a directory */ #define EISDIR 21 /* Is a directory */ #define EINVAL 22 /* Invalid argument */ #define ENFILE 23 /* File table overflow */ #define EMFILE 24 /* Too many open files */ #define ENOTTY 25 /* Not a typewriter */ #define ETXTBSY 26 /* Text file busy */ #define EFBIG 27 /* File too large */ #define ENOSPC 28 /* No space left on device */ #define ESPIPE 29 /* Illegal seek */ #define EROFS 30 /* Read-only file system */ #define EMLINK 31 /* Too many links */ #define EPIPE 32 /* Broken pipe */ #define EDOM 33 /* Math argument out of domain of func */ #define ERANGE 34 /* Math result not representable */ #define EDEADLK 35 /* Resource deadlock would occur */ #define ENAMETOOLONG 36 /* File name too long */ #define ENOLCK 37 /* No record locks available */ #define ENOSYS 38 /* Function not implemented */ #define ENOTEMPTY 39 /* Directory not empty */ #define ELOOP 40 /* Too many symbolic links encountered */ #define EWOULDBLOCK EAGAIN /* Operation would block */ #define ENOMSG 42 /* No message of desired type */ #define EIDRM 43 /* Identifier removed */ #define ECHRNG 44 /* Channel number out of range */ #define EL2NSYNC 45 /* Level 2 not synchronized */ #define EL3HLT 46 /* Level 3 halted */ #define EL3RST 47 /* Level 3 reset */ #define ELNRNG 48 /* Link number out of range */

?

#define EUNATCH 49 /* Protocol driver not attached */ #define ENOCSI 50 /* No CSI structure available */ #define EL2HLT 51 /* Level 2 halted */ #define EBADE 52 /* Invalid exchange */ #define EBADR 53 /* Invalid request descriptor */ #define EXFULL 54 /* Exchange full */ #define ENOANO 55 /* No anode */ #define EBADRQC 56 /* Invalid request code */ #define EBADSLT 57 /* Invalid slot */ #define EDEADLOCK EDEADLK #define EBFONT 59 /* Bad font file format */ #define ENOSTR 60 /* Device not a stream */ #define ENODATA 61 /* No data available */ #define ETIME 62 /* Timer expired */ #define ENOSR 63 /* Out of streams resources */ #define ENONET 64 /* Machine is not on the network */ #define ENOPKG 65 /* Package not installed */ #define EREMOTE 66 /* Object is remote */ #define ENOLINK 67 /* Link has been severed */ #define EADV 68 /* Advertise error */ #define ESRMNT 69 /* Srmount error */ #define ECOMM 70 /* Communication error on send */ #define EPROTO 71 /* Protocol error */ #define EMULTIHOP 72 /* Multihop attempted */ #define EDOTDOT 73 /* RFS specific error */ #define EBADMSG 74 /* Not a data message */ #define EOVERFLOW 75 /* Value too large for defined data type */ #define ENOTUNIQ 76 /* Name not unique on network */ #define EBADFD 77 /* File descriptor in bad state */ #define EREMCHG 78 /* Remote address changed */ #define ELIBACC 79 /* Can not access a needed shared library */ #define ELIBBAD 80 /* Accessing a corrupted shared library */ #define ELIBSCN 81 /* .lib section in a.out corrupted */ #define ELIBMAX 82 /* Attempting to link in too many shared libraries */ #define ELIBEXEC 83 /* Cannot exec a shared library directly */ #define EILSEQ 84 /* Illegal byte sequence */ #define ERESTART 85 /* Interrupted system call should be restarted */ #define ESTRPIPE 86 /* Streams pipe error */ #define EUSERS 87 /* Too many users */ #define ENOTSOCK 88 /* Socket operation on non-socket */ #define EDESTADDRREQ 89 /* Destination address required */ #define EMSGSIZE 90 /* Message too long */ #define EPROTOTYPE 91 /* Protocol wrong type for socket */ #define ENOPROTOOPT 92 /* Protocol not available */

?

#define EPROTONOSUPPORT 93 /* Protocol not supported */ #define ESOCKTNOSUPPORT 94 /* Socket type not supported */ #define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ #define EPFNOSUPPORT 96 /* Protocol family not supported */ #define EAFNOSUPPORT 97 /* Address family not supported by protocol */ #define EADDRINUSE 98 /* Address already in use */ #define EADDRNOTAVAIL 99 /* Cannot assign requested address */ #define ENETDOWN 100 /* Network is down */ #define ENETUNREACH 101 /* Network is unreachable */ #define ENETRESET 102 /* Network dropped connection because of reset */ #define ECONNABORTED 103 /* Software caused connection abort */ #define ECONNRESET 104 /* Connection reset by peer */ #define ENOBUFS 105 /* No buffer space available */ #define EISCONN 106 /* Transport endpoint is already connected */ #define ENOTCONN 107 /* Transport endpoint is not connected */ #define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ #define ETOOMANYREFS 109 /* Too many references: cannot splice */ #define ETIMEDOUT 110 /* Connection timed out */ #define ECONNREFUSED 111 /* Connection refused */ #define EHOSTDOWN 112 /* Host is down */ #define EHOSTUNREACH 113 /* No route to host */ #define EALREADY 114 /* Operation already in progress */ #define EINPROGRESS 115 /* Operation now in progress */ #define ESTALE 116 /* Stale NFS file handle */ #define EUCLEAN 117 /* Structure needs cleaning */ #define ENOTNAM 118 /* Not a XENIX named type file */ #define ENAVAIL 119 /* No XENIX semaphores available */ #define EISNAM 120 /* Is a named type file */ #define EREMOTEIO 121 /* Remote I/O error */ #define EDQUOT 122 /* Quota exceeded */ #define ENOMEDIUM 123 /* No medium found */ #define EMEDIUMTYPE 124 /* Wrong medium type */ #endif?

stdarg.h
stdarg.h stdarg.h 是 C 语言中 C 标准函式库的标头档, stdarg 是由 standard(标 准) arguments(参数)简化而来,主要目的为让函式能够接收不定量参数。 [1] C++的 cstdarg 标头档中也提供这样的机能;虽然与 C 的标头档是相容 的,但是也有冲突存在。 不定参数函式(Variadic functions)是 stdarg.h 内容典型的应用,虽 然也可以使用在其他由不定参数函式呼叫的函式(例如,vprintf)。 宣告不定参数函式 不定参数函式的参数数量是可变动的,它使用省略号来忽略之后的参 数。例如 printf 函式一般。代表性的宣告为: int check(int a, double b, ...); 不定参数函式最少要有一个命名的参数,所以 char *wrong(...); 在 C 是不被允许的(在 C++中,这样的宣告是合理的)。在 C,省略符号 之前必须要有逗号;在 C++,则没有这种强制要求。 定义不定参数函式 使用相同的语法来定义: long func(char, double, int, ...); long func(char a, double b, int c, ...) { /* ... */ } 在旧形式可能会出现较省略的函式定义: long func(); long func(a, b, c, ...) char a; double b; { /* ... */ } stdarg.h 型态名称 描述 相容 va_list 用来指向参数 C89 stdarg.h 巨集名称 描述 相容 va_start 使 va_list 指向起始的参数 C89

va_arg 检索参数 C89 va_end 释放 va_list C89 va_copy 拷贝 va_list 的内容 C99 存取参数 存取未命名的参数,首先必须在不定参数函式中宣告 va_list 型态的 变数。 呼叫 va_start 并传入两个参数: 第一个参数为 va_list 型态的变数, 第二个为函式最后一个参数的名称,接着每一呼叫 va_arg 就会回传下一个 参数,va_arg 的第一个参数为 va_list,第二个参数为回传的型态。最后 va_end 必须在函式回传前被 va_list 呼叫(当作参数)。 (没有要求要读取完 所有参数) C99 提供额外的巨集, va_copy, 它能够复制 va_list。 va_copy(va2, 而 va1)意思为拷贝 va1 到 va2。 没有机制定义该怎么判别传递到函式的参数量或者型态。函式通常需 要知道或确定它们变化的方法。共通的惯例包含: 使用 printf 或 scanf 类的格式化字串来嵌入明确指定的型态。 在不定参数最后的标兵值(sentinel value)。 总数变数来指明不定参数的数量。 型别安全性 有些 C 工具将 C 扩充允许编译器检查适当格式化字串及标兵 (sentinels)的使用。如果没有这个扩充,编译器通常无从检查传入函式的 未命名参数是否为所预期的型态。 因此, 必须对点做出谨慎的正确性确认, 型态没有吻合为未定义行为(Undefined behavior)。 举个例, 如果传入 NULL 指标,首先就是不能写入对应到适当指标型态但纯粹 NULL 的指标。再者考 虑预设参数应用到未命名参数。float 将会自动的被转换成 double?同样的 比 int(整数)更小容量的参数型态将会被转换成 int 或者 unsigned int?函 式所接收到的未命名参数必须预期到会被转换型态。 例子 #include <stdio.h> #include <stdarg.h> void printargs(int arg1, ...) /* 输出所有 int 型态的参数,直到 -1 结束 */ { va_list ap; int i; va_start(ap, arg1); for (i = arg1; i != -1; i = va_arg(ap, int)) printf("%d ", i); va_end(ap);

putchar('\n'); } int main(void) { printargs(5, 2, 14, 84, 97, 15, 24, 48, -1); printargs(84, 51, -1); printargs(-1); printargs(1, -1); return 0; } 这个程式产生输出: 5 2 14 84 97 15 24 48 84 51 1 varargs.h POSIX 定义所遗留下的标头档 varargs.h,它早在 C 标准化前就已经开 始使用了且提供类似 stdarg.h 的机能。 这个标头档不属于 ISO C 的一部分。 档案定义在单使用者 UNIX 系统规范(Single UNIX Specification)的第二 个版本中,简单的包含所有 C89 stdarg.h 的机能,除了:不能使用在标准 C 较新的形式定义;你可以不给予参数(标准 C 需要最少一个参数);与标准 C 运作的方法不同,其中一个写成: #include <stdarg.h> int summate(int n, ...) { va_list ap; int i = 0; va_start(ap, n); for (; n; n--) i += va_arg(ap, int); va_end(ap); return i; } 或比较旧式的定义: #include <stdarg.h> int summate(n, ...) int n; { /* ... */

} 以此呼叫 summate(0); summate(1, 2); summate(4, 9, 2, 3, 2); 使用 varargs.h 的函式为: #include <varargs.h> summate(n, va_alist) va_dcl /* 这里没有分号! */ { va_list ap; int i = 0; va_start(ap); for (; n; n--) i += va_arg(ap, int); va_end(ap); return i; } 以及相同的呼叫方法。 varargs.h 因为运作的模式需要旧型态的函式定义。[2] 参考 ^ IEEE Std 1003.1 stdarg.h.于 2009 年 7 月 4 日查阅. ^ 单使用者 UNIX 系统规范(Single UNIX Specification) varargs.h.于 2007 年 8 月 1 日查阅. 1 个分类: C 标准函式库
?

stddef.h
C 语言头文件。 作用:定义/声明了一些经常使用的常数,类型和变量 VC 中 stddef.h 的内容: /*** *stddef.h - definitions/declarations for common constants, types, variables * * Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. * *Purpose: * This file contains definitions and declarations for some commonly * used constants, types, and variables. * [ANSI] * * [Public] * ****/ #if _MSC_VER > 1000 #pragma once #endif #ifndef _INC_STDDEF #define _INC_STDDEF #if !defined(_WIN32) && !defined(_MAC) #error ERROR: Only Mac or Win32 targets supported! #endif #ifdef __cplusplus extern "C" { #endif /* Define _CRTIMP */ #ifndef _CRTIMP #ifdef _DLL #define _CRTIMP __declspec(dllimport) #else /* ndef _DLL */

#define _CRTIMP #endif /* _DLL */ #endif /* _CRTIMP */ /* Define __cdecl for non-Microsoft compilers */ #if ( !defined(_MSC_VER) && !defined(__cdecl) ) #define __cdecl #endif /* Define _CRTAPI1 (for compatibility with the NT SDK) */ #ifndef _CRTAPI1 #if _MSC_VER >= 800 && _M_IX86 >= 300 #define _CRTAPI1 __cdecl #else #define _CRTAPI1 #endif #endif /* Define NULL pointer value and the offset() macro */ #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif #define offsetof(s,m) (size_t)&(((s *)0)->m) /* Declare reference to errno */ #if (defined(_MT) || defined(_DLL)) && !defined(_MAC) _CRTIMP extern int * __cdecl _errno(void); #define errno (*_errno()) #else /* ndef _MT && ndef _DLL */ _CRTIMP extern int errno; #endif /* _MT || _DLL */ /* define the implementation dependent size types */ #ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; #define _PTRDIFF_T_DEFINED #endif #ifndef _SIZE_T_DEFINED typedef unsigned int size_t;

#define _SIZE_T_DEFINED #endif #ifndef _WCHAR_T_DEFINED typedef unsigned short wchar_t; #define _WCHAR_T_DEFINED #endif #ifdef _MT _CRTIMP extern unsigned long __cdecl __threadid(void); #define _threadid (__threadid()) _CRTIMP extern unsigned long __cdecl __threadhandle(void); #endif #ifdef __cplusplus } #endif #endif /* _INC_STDDEF */
?


相关文章:
keil软件之如何引入不同文件夹里面的头文件
keil软件之如何引入不同文件夹里面的头文件_电脑基础知识_IT/计算机_专业资料。在学习单片机时会用到写大型的工程之类的还有别的软件项目都会用到把不同的文件夹里...
keil C51 基本头文件
keil C51 基本头文件_IT/计算机_专业资料。#include<reg51> #include<reg52>...Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc. All...
KEIL中头文件INTRINS.H的作用
KEIL 中 头文件 INTRINS.H 的作用 【内部函数 _crol_ 字符循环左移 _cror_...Keil头文件简介 26页 免费 Keil头文件_intrins.h详... 2页 免费 添加头文件...
KEIL下如何实现文件关联
KEIL下如何实现文件关联_计算机软件及应用_IT/计算机_专业资料。KEIL下多个C文件...重要注意: 1.如果调用的 .h 文件和 c 文件在同一个文件夹下,那么头文件...
keil软件数据类型
keil软件是一款十分强大的开发软件,这里介绍了其主要的数据类型数据类型 在标准 ...sfr16 的用法,它们通常用在 51 单片机的系统自带头文件中,一般情况下无需用户...
KEIL C51 编译器简介
KEIL C51 编译器简介 第一部分 8051 开发工具 KEILC51 标准 C 编译器为 8051...如今,一个单一头 文件可被应用到 X 程序和汇编程序中。 第六部分 RTX51 ...
Keil4基本用法
Keil4基本用法_计算机软件及应用_IT/计算机_专业资料。在 Keil4.11 中打开一...6、设置头文件搜索路径: 在 Target Options 对话框的 C/C++页面中: 2 采用...
Keil C51语言的用法介绍
Keil C51语言的用法介绍_信息与通信_工程科技_专业资料。Keil C51语言的用法介绍...说明被调函数的定义在同一项目的不同文件之上,其 实库函数的头文件也是如此...
keil中生成个人库文件及调用方法
如何在 keil 中生成个人库文件及调用方法 在网上找了些资料 Keil 中如何使用...我最初的办法是把常用的函数放到一个个.C 文 件里头,要用的时候就把一个...
第一课 建立你的第一个KeilC51项目
·头文件中定义宏、 说明复杂数据类型和函数原型,有利于程序的移植和支 持单片机的系列化产品的开发; 以上简单介绍KEILC51 软件,要使用 KEILC51 软件,必需先...
更多相关标签: