| 头文件 | 函数 | 一句话 |
|---|---|---|
| stdlib.h | abs / labs / div | 绝对值 / 商+余数一次算 |
| stdlib.h | rand / srand | 伪随机数:rand 返回 0~RAND_MAX,srand 设种子(不设每次运行同序列) |
| stdlib.h | strtol / strtod | 字符串转数值的严谨版:能报错、能拿「没读完的尾巴」 |
| math.h | sin/cos/tan、exp/log/log10、pow/fabs/floor/ceil/fmod | 三角、指数对数、幂、取整;参数和返回都是 double |
/* strtol 优于 atoi:能检测「根本不是数字」和「溢出」 */
char *end;
errno = 0;
long v = strtol("123xyz", &end, 10);
if (end == "123xyz") /* 一个字符都没转 */
fprintf(stderr, "不是数字\n");
else if (*end != '\0') /* 123 读到了,后面剩 xyz */
fprintf(stderr, "尾巴:%s\n", end);clock_t c0 = clock(); /* 处理器时间(测耗时) */
do_work();
double sec = (double)(clock() - c0) / CLOCKS_PER_SEC;
time_t now = time(NULL); /* 当天时间:从纪元起的秒数 */
struct tm *t = localtime(&now);
printf("%04d-%02d-%02d %02d:%02d:%02d\n",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
char buf[64];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", t); /* 格式化时间 */
puts(buf);两套时钟:clock() 测「程序用了多少 CPU 时间」,time() 给「墙上的钟」。测性能用前者,打日志用后者。struct tm 的年份从 1900 数、月份从 0 数——两个经典 off-by-one。
/* setjmp/longjmp:跨函数「弹射」,错误处理的前身 */
jmp_buf env;
void deep(void)
{
longjmp(env, 1); /* 直接弹回 setjmp 处,跳过所有中间层 */
}
int main(void)
{
if (setjmp(env) == 0) /* 首次调用返回 0:正常流程 */
deep();
else /* longjmp 弹回后返回 1:错误流程 */
puts("从深处逃出来了");
}/* signal:异步事件(Ctrl+C 等)的处理钩子 */
void on_int(int sig) { (void)sig; exit(0); }
signal(SIGINT, on_int); /* SIGFPE 算术错误 / SIGSEGV 段违例 ... */
/* assert:调试期契约检查,发布版 #define NDEBUG 一键关闭 */
assert(p != NULL && "指针不能为空"); /* 失败即打印位置并终止 */static int cmp_int(const void *a, const void *b)
{
int x = *(const int *)a, y = *(const int *)b;
return (x > y) - (x < y);
}
int arr[] = { 5, 3, 9, 1, 7 };
qsort(arr, 5, sizeof arr[0], cmp_int); /* 快排:任意类型 */
int key = 7;
int *hit = bsearch(&key, arr, 5, sizeof arr[0], cmp_int);
if (hit)
printf("找到了:%d\n", *hit);两者共用同一套「元素比较函数」约定:返回负/零/正。bsearch 要求已排序——先 qsort 再 bsearch 是固定组合。比较函数写 (x>y)-(x<y) 而不是 x-y,可避免极端差值溢出。