C89 표준 라이브러리는 15개로 나뉘며, C99에서는 9개의 헤더가 추가되었다. 물론 그 외에 수많은 라이브러리가 존재하나, 표준은 아니다. 어떤 라이브러리는 실행 환경에 따라 작동 여부가 갈리기도 하기 때문이다.
표준 헤더를 포함한 파일에서는 헤더에서 쓰인 이름을 어떤 목적을 위해서라도 다시 사용할 수 없다. 예를 들어 <stdio.h>가 포함된 파일에서는 NULL이라는 이름을 쓸 수 없다.(이미 정의되어 있기 때문이다.) 그리고 파일 스코프의 라이브러리 이름은 파일 수준에서 다시 정의될 수 없다. 따라서 <stdio.h>를 포함한 파일은 size_t를 파일 스코프 차원에서 사용할 수 없다.
그 밖에도 여러 제한이 있다.
이 규칙들은 프로그램 내 모든 파일에 적용된다. 헤더 파일을 포함하지 않아도 말이다. 물론 이 규칙에 해당하는 단어가 라이브러리에 없을 수도 있다. 하지만 그것은 향후 라이브러리에서 등장할 가능성이 있기에 금지한것이다.
C 프로그래머에 있어 작은 함수들이 매개변수화 된 매크로로 대체되는 것은 흔한 일이다. 이러한 관습은 표준 라이브러리에서도 찾아볼 수 있다. C 표준은 헤더파일로 하여금 라이브러리 함수의 이름과 같은 이름을 갖는 매크로를 정의하는 것을 허용해준다. 하지만 함수가 사용가능할 것을 요구해서 프로그래머를 보호한다. 그 결과, 라이브러리 헤더에서 함수를 선언하고 매크로를 같은 이름으로 정의하는 것은 흔하진 않다.
우리는 이미 이런 예시를 살펴본 바가 있다.
int getchar(void);
<stdio.h>는 일반적으로 getchar를 매크로로 정의한다.
#define getchar() getc(stdin)
기본적으로 getchar 호출은 매크로 호출로 간주될 것이다. 대부분의 경우 함수를 직접 실행하기보다 매크로를 사용하는 것은 프로그램 실행 속도에서 이점을 갖는다. 하지만 가끔 우리는 코드 크기를 줄이기 위해 진짜 함수를 사용하길 원한다. 이 경우 우리는 #undef를 통해 매크로 정의를 삭제할 수 있다.
#include <stdio.h>
#undef getchar
getchar가 매크로가 아니더라도 문제가 없다.
이 방법 대신 아래 방법으로 사용을 막을 수도 있다.
ch = (getchar)();
프로세서는 매개변수화된 매크로를 특정할 수 없다.(함수 이름 뒤에 괄호가 붙지 않는한 말이다.) 하지만 컴파일러가 바보는 아닌지라, getchar는 함수로 여전히 인식된다.
C89에는 다음과 같은 표준 라이브러리가 있다.
<assert.h>, <ctype.h>, <errno.h>
<float.h>, <limits.h>, <locale.h>
<math.h>, <setjmp.h>, <signal.h>
<stdarg.h>, <stddef.h>, <stdio.h>
<stdlib.h>, <string.h>, <time.h>
C99에서의 가장 큰 변화점 중 일부는 표준 라이브러리에도 영향을 미쳤다. 이 영향은 크게 세 개로 나뉜다.
(1) 헤더 추가: C99 표준 라이브러리는 9개의 헤더가 추가되었다. 이는 다음과 같다.
<iso646.h>, <wchar.h>, <wctype.h>, <complex.h>, <fenv.h>, <inttypes.h>, <stdbool.h>, <stdint.h>, <tgmath.h>
(2) 매크로와 함수의 추가: <float.h>, <math.h>등의 라이브러리에서 사용할 수 있는 함수가 추가되었다.
(3) 기존 함수 개선
<stddef.h> 헤더는 자주 사용되는 자료형 혹은 매크로 정의를 제공한다. 함수는 없다. 이 자료형들은
sizeof 연산자의 반환형위 세 개는 보두 정수형이며, 첫 번째는 부호를 가지고, size_t는 무부호 형이다.
<stddef.h> 헤더는 매크로 두 개를 정의한다. 그 중 하나가 NULL이다. 다른 것은 offsetof로, 입력변수 두 개를 요구한다.(구조체 유형과 멤버-지정자)
offsetof는 구조체 시작 지점과 구조체 멤버까지의 바이트 거리를 계산한다. 예를 들어, offsetof(struct s, a)에서 s가 구조체 a가 첫 번째 구성원인 경우, 계산결과는 0이다. 하지만 다른 구성원의 경우 확답을 할 수 없는 것이, 컴파일러에 따라 구성원 간에 hole을 만들어 두는 경우가 있기 때문이다. 하지만 이게 offsetof의 존재의의다. 덕분에 어떤 컴파일러를 거쳤든, 오프셋을 정확하게 구할 수 있기 때문이다.
<stdbool.h> 헤더는 4개의 매크로를 정의한다.