C 标准函数库(C standard library,缩写:libc)

标准函数库通常会随附在编译器上。windows系统和Linux系统下都可以尽情使用。是最基本的C函数库,也叫ANSI C。ANSI C共包括15个头文件。1995年,Normative Addendum 1 (NA1)批准了3个头文件(iso646.h、wchar.h和wctype.h)增加到C标准函数库中。C99标准增加了6个头文件(complex.h、fenv.h、inttypes.h、stdbool.h、stdint.h和tgmath.h)。

C11标准中又新增了5个头文件(stdalign.h、stdatomic.h、stdnoreturn.h、threads.h和uchar.h)。至此,C标准函数库共有29个头文件。总而言之,几乎在任何平台上的 C 语言 (包括非 UNIX 平台) 都支持此标准。

ISO C

这个东西其实也是一个标准,保证在各个平台上使用各个编译器对同一份源码能编译出相同的结果。
ISO C是从ANSI C继承而来,也可以叫Standard C,其实可以理解为是一样的东西,就是C的标准。
但是既然把他归类到POSIX下,那就肯定是跟POSIX有点关系呀~
ISO C其实是POSIX的一个子集,除此之外,它还包含各种系统服务接口,如socket等。但是ISO C还是领先于POSIX的,很多C的新标准并没有进入POSIX中,比如线程相关部分。
C中还有一个Posix库,他就是基于POSIX标准定义的一套头文件实现的lib库。

POSIX

是 Portable Operating System Interface(可移植操作系统接口) 的缩写,X表示UNIX,它是 ISO C 的延伸,明定了一个可移植的操作系统所应具备的种种条件,其范围不只有系统函数库而已。POSIX库 就是C POSIX library。C POSIX library是C语言的POSIX系统下的标准库。包含了一些在C语言标准库之外的函数。为了OS之间的可移植性,POSIX标准规定了一些标准的接口。而这些接口标准的集合就是POSIX库。

GNU C库(英语:GNU C Library,常简称为glibc)

是一种按照LGPL许可协议发布的,自由的,公开源代码的函数库。既包含C标准库,也包含POSIX库。glibc是linux下面c标准库的实现,即GNU C Library。glibc本身是GNU旗下的C标准库,后来逐渐成为了Linux的标准c库,而Linux下原来的标准c库Linux libc逐渐不再被维护。Linux下面的标准c库不仅有这一个,如uclibc、klibc,以及上面被提到的Linux libc,但是glibc无疑是用得最多的。glibc在/lib目录下的.so文件为libc.so.6
glibc库不但包含标准C库的所有头文件,还包含了所有POSIX库的头文件。

如果对POSIX不了解建议先了解下POSIX,参见POSIX是什么有什么用。

JVjPkp1tIU8xmZ6

POSIX是标准C库的超集,需要注意的是,它遵从标准C库。如果C和POSIX发生冲突,C获胜。

套接字、文件描述符、共享内存等都是POSIX的一部分,但在C库中不存在。

pthread.h用于POSIX线程,threads.h是C11的新头,是C库的一部分。也许pthread在将来的某个时候会被弃用,取而代之的是C线程,但是你可能还不能指望C11能得到广泛的部署。因此,如果你想要可移植性,你现在应该更喜欢pthreads。如果可移植性不是一个问题,并且您有C11线程可用,那么您可能应该使用这些线程。

Linux系统下各个库头文件位置

以CentOS7为例。通过查看CentOS下标准C库,glibc库,POSIX库头文件的位置,可以对它们的关系有更直接的理解。

一般linux系统把gcc和glibc都安装到/usr/目录,所以gcc可执行文件在/usr/bin目录下,而glibc的库文件在/usr/lib目录下,glibc的头文件在/usr/include目录下。

当然上述的关系并不是一定的,在安装gcc和glibc的时候可以手工指定。可以使用命令“gcc -print-search-dirs”来查看gcc库的搜索路径

详细的可以看这篇文章 Linux头文件和库的搜索路径

C标准库头文件的位置

连接:C 标准库头文件

Vm9R8kwcafqDQTt

这些头文件放在哪些目录下取决于不同的编译器,在我的系统上(CentOS7),stdio.h、stdlib.h、time.h、math.h、assert.h等位于/usr/include目录下,stdarg.h和stddef.h等位于/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include目录下。

1
/usr/include
1
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include

BAZ9y48Nso5kUXL

POSIX库头文件的位置

链接:POSIX.1 and ISO C标准头文件

ISO C标准定义的头文件(24项)

<assert.h> ———————- 验证程序断言

<complex.h> ———————- 支持复数算术运算

<ctype.h> ———————- 字符类型

<errno.h> ———————- 出错码

<fenv.h> ———————- 浮点环境

<float.h> ———————- 浮点常量

<inttypes.h> ———————- 整型格式转换

<iso646.h> ———————- 替代关系操作符宏

<limits.h> ———————- 实现常量

<locale.h> ———————- 局部类别

<math.h> ———————- 数学常量

<setjmp.h> ———————- 非局部goto

<signal.h> ———————- 信号

<stdarg.h> ———————- 可变参数表

<stdbool.h> ———————- 布尔类型和值

<stddef.h> ———————- 标准定义

<stdint.h> ———————- 整型

<stdio.h> ———————- 标准I/O库

<stdlib.h> ———————- 实用程序库函数

<string.h> ———————- 字符串操作

<tgmath.h> ———————- 通用类型数学宏

<time.h> ———————- 时间和日期

<wchar.h> ———————- 扩展的多字节和宽字符支持

<wctype.h> ———————- 宽字符分类和映射支持

sys开头的是Linux系统自己的头文件,sys文件夹在Ubuntu 18.04中的路径:

1
/usr/include/x86_64-linux-gnu/sys

POSIX标准定义的必须的头文件(26项)

<dirent.h> ———————- 目录项

<fcntl.h> ———————- 文件控制

<fnmatch.h> ———————- 文件名匹配类型

<glob.h> ———————- 路径名模式匹配类型

<grp.h> ———————- 组文件

<netdb.h> ———————- 网络数据库操作

<pwd.h> ———————- 口令文件

<regex.h> ———————- 正则表达式

<tar.h> ———————- tar归档值

<termios.h> ———————- 终端I/O

<unistd.h> ———————- 符号常量

<utime.h> ———————- 文件时间

<wordexp.h> ———————- 字扩展类型

<arpa/inet.h> ———————- Internet定义

<net/if..h> ———————- 套接字本地接口

<netinet/in.h> ———————- Internet地址族

<netinet/tcp.h>———————- 传输控制协议定义

<sys/mman.h>———————- 内存管理声明

<sys/select.h>———————- select函数

<sys/socket.h>———————- 套接字接口

<sys/stat.h> ———————- 文件状态

<sys/times.h> ———————- 进程时间

<sys/types.h> ———————- 基本系统数据类型

<sys/un.h> ———————- UNIX域套接字定义

<sys/utsname.h>———————-系统名

<sys/wait.h> ———————- 进程控制

POSIX标准定义的XSI扩展头文件(26项)

<cpio.h> ———————- cpio归档值

<dlfcn.h> ———————- 动态链接

<fmtmsg.h> ———————- 消息显示结构

<ftw.h> ———————- 文件树漫游

<iconv.h> ———————- 代码集转换实用程序

<langinfo.h> ———————- 语言信息常量

<libgen.h> ———————- 模式匹配函数定义

<monetary.h> ———————- 货币类型

<ndbm.h> ———————- 数据库操作

<nl_types.h> ———————- 消息类别

<poll.h> ———————- 轮询函数

<search.h> ———————- 搜索表

<strings.h> ———————- 字符串操作

<syslog.h> ———————- 系统出错日志记录

<ucontext.h> ———————- 用户上下文

<ulimit.h> ———————- 用户限制

<utmpx.h> ———————- 用户帐户数据库

<sys/ipc.h> ———————- IPC

<sys/msg.h> ———————- 消息队列

<sys/resource.h>——————- 资源操作

<sys/sem.h> ———————- 信号量

<sys/shm.h> ———————- 共享存储

<sys/statvfs.h>———————- 文件系统信息

<sys/time.h> ———————- 时间类型

<sys/timeb.h> ———————- 附加的日期和时间定义

<sys/uio.h> ———————- 矢量I/O操作

POSIX标准定义的可选头文件(8项)

<aio.h> ———————- 异步I/O

<mqueue.h> ———————- 消息队列

<pthread.h> ———————- 线程

<sched.h> ———————- 执行调度

<semaphore.h>——————— 信号量

<spawn.h> ———————- 实时spawn接口

<stropts.h> ———————- XSI STREAMS接口

<trace.h> ———————- 时间跟踪

bjrqgJA2iBhLVvP

glibc库头文件的存放位置

1
/usr/include

总结

  1. POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX )
  2. POSIX标准意在期望获得源代码级别的软件可移植性。

一般情况下,应用程序通过应用编程接口(API)而不是直接通过系统调用来编程。这点很重要,因为应用程序使用的这种编程接口实际上并不需要和内核 提供的系统调用对应。一个API定义了一组应用程序使用的编程接口。它们可以实现成一个系统调用,也可以通过调用多个系统调用来实现,而完全不使用任何系 统调用也不存在问题。实际上,API可以在各种不同的操作系统上实现,给应用程序提供完全相同的接口,而它们本身在这些系统上的实现却可能迥异。

在Unix世界中,最流行的应用编程接口是基于POSIX标准的。从纯技术的角度看,POSIX是由IEEE的一组标准组成,其目标是提供一套大体上基于Unix的可移植操作系统标准。Linux是与POSIX兼容的。

POSIX是说明API和系统调用之间关系的一个极好例子。在大多数Unix系统上,根据POSIX而定义的API函数和系统调用之间有着直接关系。实际上,POSIX标准就是仿照早期Unix系统的界面建立的。另一方面,许多操作系统,像Windows NT,尽管和Unix没有什么关系,也提供了与POSIX兼容的库。

Linux的系统调用像大多数Unix系统一样,作为C库的一部分提供如图5-1所示。如图5-1所示C库实现了Unix系统的主要API,包括标 准C库函数和系统调用。所有的C程序都可以使用C库,而由于C语言本身的特点,其他语言也可以很方便地把它们封装起来使用。此外,C库提供了POSIX的 绝大部分API。

从程序员的角度看,系统调用无关紧要;他们只需要跟API打交道就可以了。

相反,内核只跟系统调用打交道;库函数及应用程序是怎么使用系统调用不是内核所关心的。

完成同一功能,不同内核提供的系统调用(也就是一个函数)是不同的,

例如创建进程:

  • linux下是fork函数
  • windows下是creatprocess函数。

好,我现在在linux下写一个程序,用到fork函数,那么这个程序该怎么往windows上移植?我需要把源代码里的fork通通改成creatprocess,然后重新编译…

posix标准的出现就是为了解决这个问题。linux和windows都要实现基本的posix标准,linux把fork函数封装成posix_fork(随便说的),windows把creatprocess函数也封装成posix_fork,都声明在unistd.h里。这样,程序员编写普通应用时候,只用包含unistd.h,调用posix_fork函数,程序就在源代码级别可移植了

官方回答:

POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),POSIX标准定义了操作系统应该为应用程序提供的接口标准,是IEEE为要在各种UNIX操作系统上运行的软件而定义的一系列API标准的总称,其正式称呼为IEEE 1003,而国际标准名称为ISO/IEC 9945。

POSIX标准意在期望获得源代码级别的软件可移植性。换句话说,为一个POSIX兼容的操作系统编写的程序,应该可以在任何其它的POSIX操作系统(即使是来自另一个厂商)上编译执行。

POSIX 并不局限于 UNIX。许多其它的操作系统,例如 DEC OpenVMS 支持 POSIX 标准,尤其是 IEEE Std. 1003.1-1990(1995 年修订)或 POSIX.1,POSIX.1 提供了源代码级别的 C 语言应用编程接口(API)给操作系统的服务程序,例如读写文件。POSIX.1 已经被国际标准化组织(International Standards Organization,ISO)所接受,被命名为 ISO/IEC 9945-1:1990 标准。