探究C语言的stdlib库:功能与示例详解

Posted by Buddy on April 14, 2024

C语言的stdlib(standard library)库是C语言程序员经常使用的标准库之一,它提供了一系列功能丰富的函数,涵盖了内存管理、字符串处理、随机数生成、数学计算等方面。本文将详细介绍stdlib库中一些常用函数的功能,并通过示例代码来说明它们的用法。

1. 内存管理函数

1.1 malloc()、calloc()和realloc()

这三个函数用于动态内存分配。其中:

  • malloc(size_t size) 用于分配指定大小的内存空间,并返回指向该内存空间的指针。
  • calloc(size_t num, size_t size) 用于分配指定数量、指定大小的内存空间,并将该空间的每一位初始化为0,然后返回指向该内存空间的指针。
  • realloc(void *ptr, size_t size) 用于重新分配之前分配的内存空间的大小,ptr 是之前分配的内存的指针,size 是重新分配的大小。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 使用malloc分配10个int大小的内存空间
    int *ptr1 = (int *)malloc(10 * sizeof(int));
    
    // 使用calloc分配20个int大小的内存空间
    int *ptr2 = (int *)calloc(20, sizeof(int));
    
    // 使用realloc重新分配ptr1所指向的内存空间大小为20个int
    ptr1 = (int *)realloc(ptr1, 20 * sizeof(int));
    
    // 释放内存
    free(ptr1);
    free(ptr2);
    
    return 0;
}

1.2 free()

free(void *ptr) 用于释放之前动态分配的内存空间,ptr 是指向需要释放的内存空间的指针。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 动态分配内存空间
    int *ptr = (int *)malloc(10 * sizeof(int));
    
    // 使用内存空间
    
    // 释放内存空间
    free(ptr);
    
    return 0;
}

2. 字符串处理函数

2.1 strcpy()、strncpy()和strcat()

这些函数用于字符串的拷贝和连接。

  • strcpy(char *dest, const char *src) 将源字符串 src 复制到目标字符串 dest 中,直到遇到 '\0' 结束。
  • strncpy(char *dest, const char *src, size_t n) 类似于 strcpy,但最多复制 n 个字符。
  • strcat(char *dest, const char *src) 将源字符串 src 连接到目标字符串 dest 的末尾。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char dest[20] = "Hello";
    char src[] = " world!";
    
    // 将src复制到dest
    strcpy(dest, src);
    printf("strcpy: %s\n", dest);
    
    char dest2[20] = "Hello";
    // 将src的前5个字符复制到dest2
    strncpy(dest2, src, 5);
    printf("strncpy: %s\n", dest2);
    
    char dest3[20] = "Hello";
    // 将src连接到dest3的末尾
    strcat(dest3, src);
    printf("strcat: %s\n", dest3);
    
    return 0;
}

2.2 strlen()

strlen(const char *str) 返回字符串 str 的长度,不包括结尾的 '\0'

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char str[] = "Hello";
    int len = strlen(str);
    printf("Length of string: %d\n", len);
    
    return 0;
}

3. 随机数生成函数: rand() 和 srand()

rand() 函数用于生成一个伪随机数,范围在 0 到 RAND_MAX 之间,其中 RAND_MAX 是一个常量,代表随机数的最大取值。需要注意的是,每次程序运行时,使用 rand() 函数生成的随机数序列是相同的。

为了产生不同的随机数序列,可以使用 srand() 函数来设置随机数生成器的种子。通常,可以使用当前时间作为种子,以保证每次运行程序时生成的随机数序列都不同。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    // 设置随机数生成器的种子为当前时间
    srand(time(NULL));
    
    // 生成随机数
    int random_num = rand() % 100; // 生成 0 到 99 之间的随机数
    printf("Random number: %d\n", random_num);
    
    return 0;
}

4. 系统退出函数: exit()

exit(int status) 函数用于退出程序,并返回一个状态码 status 给操作系统。通常情况下,状态码 0 表示程序正常结束,非零状态码表示程序异常结束。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("Before exit.\n");
    
    // 退出程序,并返回状态码 0
    exit(0);
    
    printf("After exit. This line won't be executed.\n");
    
    return 0;
}

5. 环境变量操作函数: getenv()

getenv(const char *name) 函数用于获取指定名称的环境变量的值,并返回该值的字符串指针。如果指定名称的环境变量不存在,则返回 NULL。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 获取环境变量 PATH 的值
    char *path_value = getenv("PATH");
    
    if (path_value != NULL) {
        printf("Value of PATH: %s\n", path_value);
    } else {
        printf("PATH environment variable not found.\n");
    }
    
    return 0;
}

6. 数学计算函数

6.1 abs() 和 labs()

abs(int n) 函数用于计算整数 n 的绝对值,返回一个整数。

labs(long int n) 函数用于计算长整数 n 的绝对值,返回一个长整数。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int num1 = -10;
    long int num2 = -1000000;
    
    // 计算整数的绝对值
    int abs_num1 = abs(num1);
    printf("Absolute value of %d: %d\n", num1, abs_num1);
    
    // 计算长整数的绝对值
    long int abs_num2 = labs(num2);
    printf("Absolute value of %ld: %ld\n", num2, abs_num2);
    
    return 0;
}

6.2 atof()、atoi() 和 atol()

atof(const char *str) 函数将字符串 str 转换为浮点数,并返回结果。

atoi(const char *str) 函数将字符串 str 转换为整数,并返回结果。

atol(const char *str) 函数将字符串 str 转换为长整数,并返回结果。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char str_float[] = "3.14";
    char str_int[] = "12345";
    char str_long[] = "123456789012345";

    // 将字符串转换为浮点数
    float float_num = atof(str_float);
    printf("Float number: %f\n", float_num);

    // 将字符串转换为整数
    int int_num = atoi(str_int);
    printf("Integer number: %d\n", int_num);

    // 将字符串转换为长整数
    long int long_num = atol(str_long);
    printf("Long integer number: %ld\n", long_num);
    
    return 0;
}

7. 环境控制函数

7.1 system()

system(const char *command) 函数用于在系统中执行指定的命令。它会调用操作系统的 shell 并执行给定的命令字符串。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 执行系统命令 "ls",列出当前目录下的文件和文件夹
    system("ls");
    
    return 0;
}

7.2 getenv()

getenv(const char *name) 函数用于获取指定名称的环境变量的值,并返回该值的字符串指针。如果指定名称的环境变量不存在,则返回 NULL。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 获取环境变量 PATH 的值
    char *path_value = getenv("PATH");
    
    if (path_value != NULL) {
        printf("Value of PATH: %s\n", path_value);
    } else {
        printf("PATH environment variable not found.\n");
    }
    
    return 0;
}

8. 排序和搜索函数

8.1 qsort()

qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *)) 函数用于对数组进行快速排序。其中:

  • base 是指向要排序的数组的指针。
  • num 是数组中元素的个数。
  • size 是每个元素的大小(以字节为单位)。
  • compar 是一个指向比较函数的指针,用于指定元素之间的比较方式。

示例代码:

#include <stdio.h>
#include <stdlib.h>

// 比较函数,用于指定整数的升序排列方式
int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int arr[] = {5, 2, 8, 1, 9};
    int n = sizeof(arr) / sizeof(arr[0]);

    // 对数组进行升序排序
    qsort(arr, n, sizeof(int), compare);

    printf("Sorted array: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

8.2 bsearch()

bsearch(const void *key, const void *base, size_t num, size_t size, int (*compar)(const void *, const void *)) 函数用于在有序数组中搜索指定的元素。其中:

  • key 是要搜索的元素的指针。
  • base 是指向要搜索的有序数组的指针。
  • num 是数组中元素的个数。
  • size 是每个元素的大小(以字节为单位)。
  • compar 是一个指向比较函数的指针,用于指定元素之间的比较方式。

如果找到了指定的元素,则返回指向该元素的指针;否则返回 NULL。

示例代码:

#include <stdio.h>
#include <stdlib.h>

// 比较函数,用于指定整数的升序排列方式
int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    int key = 3;

    // 在有序数组中搜索指定元素
    int *result = (int*)bsearch(&key, arr, n, sizeof(int), compare);

    if (result != NULL) {
        printf("Element found: %d\n", *result);
    } else {
        printf("Element not found.\n");
    }

    return 0;
}

9. 文件操作函数

9.1 fopen() 和 fclose()

FILE *fopen(const char *filename, const char *mode) 函数用于打开文件,并返回一个指向文件的指针。其中:

  • filename 是要打开的文件的名称。
  • mode 是打开文件的模式,包括 “r”(只读)、”w”(写入)、”a”(追加)等。

int fclose(FILE *stream) 函数用于关闭打开的文件。

示例代码:

#include <stdio.h>

int main() {
    FILE *fp;
    char c;

    // 打开文件以进行读写操作
    fp = fopen("test.txt", "w+");

    // 写入字符到文件
    fprintf(fp, "This is testing for fprintf...\n");
    fputs("This is testing for fputs...\n", fp);

    // 读取并输出文件内容
    rewind(fp);
    while ((c = fgetc(fp)) != EOF)
        printf("%c", c);

    // 关闭文件
    fclose(fp);
    
    return 0;
}

9.2 fread() 和 fwrite()

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 函数用于从文件中读取数据,并存储到指定的内存位置。

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 函数用于将数据从内存写入到文件中。

示例代码:

#include <stdio.h>

int main() {
    FILE *fp;
    char buffer[100];

    // 打开文件以进行读写操作
    fp = fopen("test.txt", "w+");
    
    // 写入字符串到文件
    fwrite("Hello, World!", sizeof(char), 13, fp);
    
    // 移动文件指针到文件开头
    rewind(fp);
    
    // 从文件中读取数据到缓冲区
    fread(buffer, sizeof(char), 13, fp);
    
    // 输出缓冲区内容
    printf("Content of file: %s\n", buffer);

    // 关闭文件
    fclose(fp);
    
    return 0;
}

10. 环境清理函数: atexit()

int atexit(void (*func)(void)) 函数用于注册一个在程序退出时自动执行的函数。可以多次调用 atexit() 函数来注册多个退出函数,它们将按照注册的顺序执行。

示例代码:

#include <stdio.h>
#include <stdlib.h>

void cleanup() {
    printf("Performing cleanup...\n");
    // 在这里进行资源释放等清理操作
}

int main() {
    // 注册退出函数
    atexit(cleanup);
    
    printf("Main function executing...\n");

    return 0;
}

11. 程序运行时错误处理函数: perror()

void perror(const char *s) 函数用于输出上一个函数调用的错误信息。它会根据全局变量 errno 的值来确定错误类型,并输出相应的错误信息到标准错误流(stderr)。需要注意的是,perror() 函数输出的错误信息包含一个用户提供的字符串 s 和一个冒号分隔符。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    FILE *fp;

    // 尝试打开一个不存在的文件
    fp = fopen("nonexistentfile.txt", "r");

    if (fp == NULL) {
        perror("Error opening file");
        exit(EXIT_FAILURE);
    }

    fclose(fp);
    
    return 0;
}

12. 字符串转换函数: strtol() 和 strtoul()

long int strtol(const char *str, char **endptr, int base) 函数将字符串 str 转换为长整数,并返回结果。参数 endptr 是一个指向字符指针的指针,用于存储转换过程中停止的位置。参数 base 指定了字符串中数字的进制,可以是 2、8、10 或 16。

unsigned long int strtoul(const char *str, char **endptr, int base) 函数与 strtol() 类似,但返回的是无符号长整数。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char str[] = "12345";
    char *endptr;
    long int num;

    // 将字符串转换为长整数
    num = strtol(str, &endptr, 10);

    printf("Converted number: %ld\n", num);
    printf("Stopped at: %s\n", endptr);

    return 0;
}

13. 环境变量操作函数: setenv() 和 unsetenv()

int setenv(const char *name, const char *value, int overwrite) 函数用于设置环境变量的值。参数 name 是环境变量的名称,参数 value 是要设置的值,参数 overwrite 指定是否覆盖已存在的环境变量,如果设置为非零值则覆盖,否则不覆盖。

int unsetenv(const char *name) 函数用于删除指定名称的环境变量。

示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 设置环境变量
    setenv("MY_VAR", "hello", 1);

    // 获取并输出环境变量的值
    char *value = getenv("MY_VAR");
    printf("Value of MY_VAR: %s\n", value);

    // 删除环境变量
    unsetenv("MY_VAR");

    // 再次尝试获取环境变量的值
    value = getenv("MY_VAR");
    if (value == NULL) {
        printf("MY_VAR is not set.\n");
    }

    return 0;
}

14. 宽字符处理函数: wcstombs() 和 mbstowcs()

size_t wcstombs(char *mbstr, const wchar_t *wcstr, size_t n) 函数将宽字符字符串 wcstr 转换为多字节字符字符串,并存储在字符数组 mbstr 中。参数 n 指定了字符数组的最大长度。

size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t n) 函数将多字节字符字符串 mbstr 转换为宽字符字符串,并存储在宽字符数组 wcstr 中。参数 n 指定了宽字符数组的最大长度。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main() {
    wchar_t wcstr[] = L"宽字符测试";
    char mbstr[50];

    // 将宽字符字符串转换为多字节字符字符串
    wcstombs(mbstr, wcstr, sizeof(mbstr));

    // 输出多字节字符字符串
    printf("Multibyte string: %s\n", mbstr);

    // 将多字节字符字符串转换为宽字符字符串
    wchar_t wcstr2[50];
    mbstowcs(wcstr2, mbstr, sizeof(wcstr2));

    // 输出宽字符字符串
    wprintf(L"Wide character string: %ls\n", wcstr2);

    return 0;
}

总结

本文只介绍了stdlib库中的部分函数及其用法,读者可以查阅相关文档进一步了解更多函数的功能和用法。