C语言编程常见问题解答之标准库函数(1)

来源:互联网 发布:java员工管理系统菜单 编辑:程序博客网 时间:2024/04/30 11:57

第12章  标准库函数

    使用C语言的一半价值在于使用其标准库函数。当然,灵活的for循环以及数组和指针之间的相似性也是C语言的重要价值。在解决实际问题时,能方便地操作字符串和文件等对象是最重要的,有些语言能出色地完成其中的一部分工作,另一些语言能出色地完成其中的另一部分工作,然而,没有几种语言能象C语言那样能出色地完成全部工作。

  c标准库中还缺少很多函数,例如投有图形函数,甚至没有全屏幕文本操作函数,signal机制也相当弱(见12.10),并且根本没有对多任务或使用常规内存以外的内存提供支持。尽管C标准库存在上述缺陷,但它毕竟为所有的程序都提供了一套基本功能,不管这些程序是运行在多任务、多窗口的环境下,还是运行在简单的终端上,或者是运行在一台昂贵的烤面包机上。

C标准库中所缺的函数可以从其它途径获得,例如编译程序开发商和第三方的函数库都会提供一些函数,这些函数都是事实上的标准函数。然而,标准库中的函数已经为程序设计提供了一个非常坚实的基础。

    12.1  为什么应该使用标准库函数而不要自己编写函数?

    标准库函数有三点好处:准确性、高效性和可移植性。

    准确性:编译程序的开发商通常会保证标准库函数的准确性。更重要的是。至少开发商做了全面的检测来证实其准确性,这比你所能做到的更加全面(有些昂贵的测试工具能使这项工作更加容易)。

    高效性:优秀的C程序员会大量使用标准库函数,而内行的编译程序开发商也知道这一点。如果开发商能提供一套出色的标准库函数,他就会在竞争中占优势。当对相互竞争的编译程序的效率进行比较时,一套出色的标准库函数将起到决定性的作用。因此,开发商比你更有动力,并且有更多的时间,去开发一套高效的标准库函数。

    可移植性:在软件要求不断变化的情况下,标准库函数在任何计算机上,对任何编译程序都具有同样的功能,并且表达同样的含义,因此它们是C程序员屈指可数的几种依靠之一。

    有趣的是,你很难找到一项关于标准库函数的最标准的信息。对于每一个函数,都需要有一个(在极少数情况下需要两个)保证能将该函数的原型提供给你的头文件(在调用任何一个函数时,都应该包含其原型,见8.2)。有趣的是什么呢?这个头文件可能并不是真正包含该函数原型的文件,在有些(非常糟糕!)情况下,甚至由编译程序手册推荐的头文件都不一定正确。对于宏定义,typedef和全局变量,同样会发生这种情况。

    为了找到“正确的”头文件,你可以在一份ANSI/ISO c标准的拷贝中查阅相应的函数。如果你手头没有这样一份拷贝,你可以使用表12.2。

    请参见:

    8.2为什么要使用函数原型?

    12.2 为了定义我要使用的标准库函数,我需要使用哪些头文件?

    12.2 为了定义我要使用的标准库函数,我需要使用哪些头文件?

    你需要使用ANSI/ISO标准规定的你应该使用的那些头文件,见表12.2。

    有趣的是,这些文件并不一定定义你要使用的函数。例如,如果你要使用宏EDOM,你的编译程序保证你能通过包含(errno.h)得到这个宏,而(errno.h)可能定义了宏EDOM,也可能只包含定义这个宏的头文件。更糟的是,编译程序的下一个版本可能会在另一个地方定义宏EDOM。

    因此,你不用去寻找真正定义一个函数的头文件并使用这个文件,而应该使用那个被假定为定义了该函数的头文件,这样做是肯定可行的。

    有几个名字在多个头文件中被定义:NULL,size_t和wchar_t。如果你需要其中一个名字的定义,可以使用任意一个定义了该名字的头文件((stddef.h>是一个较好的选择,它不仅小,而且包含了常用的宏定义和类型定义)。

               表12.2标准库函数的头文件

----------------------------------------------------------------------

  函数                               头文件

----------------------------------------------------------------------

abort                                stdlib. h

abs                                  stdlib. h

acos                                 math. h

asctime                              time. h

asin                                 math. h

assert                               assert.h

atan                                 math. h

atan2                                math. h

atexit                               stdlib. h

atof                                 stdlib. h

atoi                                 stdlib. h

atol                                 stdlib. h

bsearch                              stdlib. h

BUFSIZ                               stdio. h

calloc                               stdlib. h

ceil                                 math. h

clearerr                             stdio. h

clock                                time. h

CLOCKS-PER-SEC                       time. h

clock_t                              time. h

cos                                  math. h

cosh                                 math. h

ctime                                time. h

difftime                             time. h

div                                  stdlib. h

div_t                                stdlib. h

EDOM                                 errno. h

EOF                                  stdio. h

ERANGE                               errno. h

errno                                errno. h

exit                                 stdlib. h

EXIT_FAILURE                         stdlib. h

EXIT_SUCCESS                         stdlib. h

exp                                  math. h

fabs                                 math. h

fclose                               stdio. h

feof                                 stdio.h

ferror                               stdio.h

fflush                               stdio. h

fgetc                                stdio.h

fgetpos                              stdio. h

fgets                                stdio.h

FILE                                 stdio. h

FILENAME-MAX                        stdio. h

floor                                math. h

fmod                                 math. h

fopen                                stdio. h

FOPEN_MAX                            stdio. h

fpos_t                               stdio. h

fpnntf                               stdio. h

fputc                                stdio.h

fputs                                stdio. h

head                                 stdio. h

free                                 stdlib. h

freopen                              stdio. h

frexp                                math. h

fscanf                               stdio. h

fseek                                stdio. h

fsetpos                              stdio. h

ftell                                stdio. h

fwrite                               stdio. h

getc                                 stdio.h

getchar                              stdio. h

getenv                               stdlib. h

gets                                 stdio.h

gmtime                               time. h

HUGE-VAL                             math.h

_IOFBF                               stdio. h

_IOLBF                               stdio. h

_IONBF                               stdio. h

isalnum                              ctype. h

isalpha                              ctype. h

iscntrl                              ctype. h

isdigit                              ctype. h

isgraph                              ctype. h

islower                              ctype. h

isprint                              ctype. h

ispunct                              ctype. h

isspace                              ctype. h

isupper                              ctype. h

isxdigit                             ctype. h

jmp_buf                              setjmp. h

labs                                 stdlib. h

LC_ALL                               locale. h

LC_COLLATE                           locale. h

LC_CTYPE                             locale. h

LC_MONETARY                          locale. h

LC_NUMERIC                           locale. h

LC_TIME                              locale. h

struct lconv                         locale. h

ldexp                                math. h

ldiv                                 stdlib. h

ldiv_t                               stdlib. h

localeconv                           locale. h

localtime                            time. h

log                                  math.  h

log10                                math.  h

longjmp                              setjmp. h

L_tmpnam                             stdio. h

malloc                               stdlib. h

mblen                                stdlib. h

mbstowcs                             stdlib. h

mbtowc                               stdlib. h

MB_CUR_MAX                           stdlib. h

memchr                               string. h

memcmp                               string. h

memcpy                               string. h

memmove                              string. h

memset                               string. h

mktime                              time. h

modf                                 math. h

NDEBUG                               assert. h

NULL                                 locale. h.stddef. h.stdio. h.stdlib. h.string. h.time. h

offsetof                             stddef. h

perror                               stdio.h

pow                                  math. h

printf                               stdio.h

ptrdiff_t                            stddef. h

putc                                 stdio. h

putchar                              stdio. h

puts                                 stdio. h

qsort                                stdlib. h

raise                                signal. h

rand                                 stdlib. h

RAND_MAX                             stdlib. h

realloc                              stdlib. h

remove                               stdio. h

rename                               stdio. h

rewind                               stdio. h

scanf                                stdio.h

SEEK_CUR                             stdio. h

SEEK_END                             stdio. h

SEEK_SET                             stdio. h

setbuf                               stdio. h

setjmp                               setjmp. h

setlocale                            locale. h

setvbuf                              stdio. h

SIGABRT                              signal. h

SIGFPE                               signal. h

SIGILL                               signal. h

SIGINT                               signal. h

signal                               signal. h

SIGSEGV                              signal. h

SIGTERM                              signal. h

sig_atomic_t                         signal. h

SIG_DFL                              signal. h

SIG_ERR                              signal. h

SIG_IGN                              signal. h

sin                                  math. h

sinh                                 math. h

size_t                               stddef. h.stdlib. h.string. h

sprintf                              stdio. h

sqrt                                 math. h

srand                                stdlib. h

sscanf                               stdio. h

stderr                               stdio.h

stdin                                stdio. h

stdout                               stdio. h

strcat                               string. h

strchr                               string. h

strcmp                               string. h

strcoll                              string. h

strcpy                               string. h

strcspn                              string. h

strerror                             string.h

strftime                             time. h

strlen                               string. h

strncat                              string. h

strncmp                              string. h

strncpy                              string. h

strpbrk                              string. h

strrchr                              string. h

strspn                               string. h

strstr                               string. h

strtod                               stdlib. h

strtok                               string. h

strtol                               stdlib. h

strtoul                              stdlib. h

strxfrm                              string. h

system                               stblib. h

tan                                  math. h

tanh                                 math. h

time                                 time. h

time_t                               time. h

struct tm                            time. h

tmpfile                              stdio. h

tmpnam                               stdio. h

TMP_MAX                              stdio. h

tolower                              ctype. h

toupper                              ctype. h

ungetc                               stdio. h

va_arg                               stdarg. h

va_end                               stdarg. h

valist                               stdarg. h

va_ start                            stdarg. h

vfprintf                             stdio. h

vprintf                              stdio. h

vsprintf                             stdio. h

wchar_t                              stddef. h. stdlib. h

wcstombs                             stdlib. h

wctomb                               stdlib. h

-------------------------------------------------------------------------

    请参见:

     5.12 #include(file~和#include“file”有什么不同?

    12.1  为什么应该使用标准库函数而不要自己编写函数?

    12.3  怎样编写参数数目可变的函数?

    你可以利用(stdarg.h)头文件,它所定义的一些宏可以让你处理数目可变的参数。

    注意:这些宏以前包含在名为(varargs.h)或类似的一个头文件中。你的编译程序中可能还有这样一个文件,也可能没有;即使现在有,下一个版本中可能就没有了。因此,还是使用(stadrg.h)为好。

   如果对传递给c函数的参数不加约束,就没有一种可移植的方式让c函数知道它的参数的数目和类型。如果一个c函数的参数数目不定(或类型不定),就需要引入某种规则来约束它的参数。例如,printf()函数的第一个参数是一个字符串,它将指示其后都是一些什么样的参数:

printf( Hello,  world! );  /* no more arguments */

printf(%s , Hello, world!);   /*  one more string argument  */

printf(%s, %s , Hello , world!);   /*  two more string arguments  */

printf(%s, %d , Hello, 42);   /*  one string, one int */

   例12.3给出了一个简单的类似printf()的函数,它的第一个参数是格式字符串,根据该字符串可以确定其余参数的数目和类型。与真正的printf()函数一样,如果格式字符串和其余参数不匹配,那么结果是没有定义的,你无法知道程序此后将做些什么(但很可能是一些糟糕的事情)。

  例12.3一个简单的类似printf()的函数

# include      

# include      

# include      

# include      

static char *

int2str (int n)

{

       int     minus = (n < 0) ;

       static char     buf[32];

       char      * p =  &buf[3l];

       if (minus)

                n = —n;

       *P = ’’,

       do {

                *---p = ’0’+n%10;

                n/=10;

       }  while (n>0);

       if (minus)

          *- - p = ’-’;

       return p;

}

/*

 * This is a simple printf-like function that handles only

 * the format specifiers %%, %s, and %d.

 */

void

simplePrintf(const char  * format, . . . )

{

      va_list     ap; / * ap is our argument pointer.  * /

      int         i;

      char        * s ;

      /*

        * Initialize ap to start with  the argument

        * after format

        */

      va_start(ap, format);

      for (;  * format;  format + + ) {

             if (* format !=’%’){

                     putcharC * format);

                    continue;

             }

             switch  ( * ++format) {

             case ’s’ :

                    / *  Get next argument (a char * )  * /

                    s = va_arg(ap, char  * );

                    fputs(s, stdout);

                    break;

             case ’d’:/ * Get next  argument (an int) * /

                     i  = va_arg(ap, int);

                     s  = int2str(i) ;

                     fputs(s, stdout) ;

                     break s

             case ’ ’ : format---;

                    breaks

             default :putchar ( * format) ;

                    break;

              }

       }

       / *  Clean up  varying arguments before returning  * /

       va_end(ap);

 }

 void

 main()

 {

             simplePrintK The %s tax rate is  %d%%. ,

                     sales, 6);

 }

    请参见:

    12.2为了定义我要使用的标准库函数,我需要使用哪些头文件?

    12.4 独立(free—standing)环境和宿主(hosted)环境之间有什么区别?

    并不是所有的C程序员都在编写数据库管理系统和字处理软件,有些C程序员要为嵌入式系统(embedded system)编写代码,例如防抱死刹车系统和智能型的烤面包机。嵌入式系统可以不要任何类型的文件系统,也可以基本上不要操作系统。ANSI/1SO标准称这样的系统为“独立(free—standing)”系统,并且不要求它们提供除语言本身以外的任何东西。与此相反的情况是程序运行在RC机、大型机或者介于两者之间的计算机上,这被称为“宿主(hosted)”环境。

    即使是开发独立环境的程序员也应该重视标准库:其一,独立环境往往以与标准兼容的方式提供某种功能(例如求平方根函数,重新设计该函数显然很麻烦,因而毫无意义);其二,在将嵌入式程序植入烤面包机这样的环境之前,通常要先在PC机上测试该程序,而使用标准库函数能增加可同时在测试环境和实际环境中使用的代码的总量。