C语言实例_stdlib.h库函数功能及其用法详解

一、前言

C语言作为一种高效、灵活的编程语言,标准库的使用对于开发人员来说是不可或缺的。其中,stdlib.h是C语言中一个重要的标准库头文件,提供了许多常用的函数和工具,以便开发人员能够更加便捷地进行内存管理、字符串处理、随机数生成等操作。本文将对stdlib.h中的各个函数进行全面介绍,包括它们的功能和使用方法,以帮助开发者更好地理解和利用该标准库。

二、stdlib.h函数介绍

C语言的标准库头文件 stdlib.h 提供了一些常用的函数,用于执行各种实用程序和内存管理任务。

以下是 stdlib.h 头文件中包含的主要函数及其功能的详细介绍:

【1】内存管理函数

  • malloc(size_t size):动态分配指定大小的内存块,并返回指向该内存块的指针。
  • calloc(size_t num, size_t size):动态分配 num 个长度为 size 字节的连续内存区域,并将每个字节初始化为零。
  • realloc(void* ptr, size_t size):重新分配先前分配的内存块 ptr 的大小为 size 字节,并返回指向重新分配后内存块的指针。
  • free(void* ptr):释放之前通过动态内存分配函数分配的内存。

【2】字符串转换函数

  • atoi(const char* str):将字符串转换为对应的整数并返回结果。
  • atol(const char* str):将字符串转换为对应的长整数并返回结果。
  • atof(const char* str):将字符串转换为对应的双精度浮点数并返回结果。
  • itoa(int value, char* str, int base):将整数转换为字符串并存储在 str 中。
  • rand(void):生成伪随机数。
  • srand(unsigned int seed):设置随机数发生器的种子。

【3】环境控制函数

  • system(const char* command):执行命令行参数中指定的 shell 命令。
  • exit(int status):终止程序的执行并返回状态码。
  • _Exit(int status):终止程序的执行并返回状态码,不进行清理操作。
  • abort(void):中止程序的执行,并生成一个异常终止信号。

【4】动态分配排序函数

  • qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*)):对数组进行快速排序。

【5】字符串处理函数

  • rand_r(unsigned int* seedp):可重入版本的 rand() 函数。
  • system_l(const char* command, locale_t loc):根据指定的本地化环境执行命令。
  • posix_memalign(void** memptr, size_t alignment, size_t size):分配对齐的内存块。
  • aligned_alloc(size_t alignment, size_t size):分配对齐的内存块。

三、代码示例

3.1 内存管理函数

【1】malloc(size_t size) :动态分配指定大小的内存块,并返回指向该内存块的指针。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        int* ptr;
        int num = 5;
    ​
        // 动态分配一个 int 数组,数组长度为 num
        ptr = (int*)malloc(num * sizeof(int));
        
        // 检查内存是否成功分配
        if (ptr == NULL) {
            printf("内存分配失败\n");
            exit(1);
        }
    ​
        // 使用分配的内存
        for (int i = 0; i < num; i++) {
            ptr[i] = i + 1;
        }
        
        // 输出数组的值
        for (int i = 0; i < num; i++) {
            printf("%d ", ptr[i]);
        }
    ​
        // 释放内存
        free(ptr);
    ​
        return 0;
    }

【2】calloc(size_t num, size_t size) :动态分配 num 个长度为 size 字节的连续内存区域,并将每个字节初始化为零。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        int* ptr;
        int num = 5;
    ​
        // 动态分配一个 int 数组,数组长度为 num,并初始化为零
        ptr = (int*)calloc(num, sizeof(int));
        
        // 检查内存是否成功分配
        if (ptr == NULL) {
            printf("内存分配失败\n");
            exit(1);
        }
    ​
        // 输出数组的值
        for (int i = 0; i < num; i++) {
            printf("%d ", ptr[i]);
        }
    ​
        // 释放内存
        free(ptr);
    ​
        return 0;
    }

*【3】realloc(void ptr, size_t size)** :重新分配先前分配的内存块 ptr 的大小为 size 字节,并返回指向重新分配后内存块的指针。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        int* ptr;
        int num = 5;
    ​
        // 动态分配一个 int 数组,数组长度为 num
        ptr = (int*)malloc(num * sizeof(int));
        
        // 检查内存是否成功分配
        if (ptr == NULL) {
            printf("内存分配失败\n");
            exit(1);
        }
    ​
        // 输出数组的值
        for (int i = 0; i < num; i++) {
            printf("%d ", ptr[i]);
        }
    ​
        // 重新分配内存为更大的数组
        num = 10;
        ptr = (int*)realloc(ptr, num * sizeof(int));
    ​
        // 使用重新分配的内存
        for (int i = 5; i < num; i++) {
            ptr[i] = i + 1;
        }
    ​
        // 输出数组的值
        for (int i = 0; i < num; i++) {
            printf("%d ", ptr[i]);
        }
    ​
        // 释放内存
        free(ptr);
    ​
        return 0;
    }

*【4】free(void ptr)** :释放之前通过动态内存分配函数分配的内存。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        int* ptr;
    ​
        // 动态分配一个 int 数组
        ptr = (int*)malloc(5 * sizeof(int));
        
        // 检查内存是否成功分配
        if (ptr == NULL) {
            printf("内存分配失败\n");
            exit(1);
        }
    ​
        // 使用分配的内存
        for (int i = 0; i < 5; i++) {
            ptr[i] = i + 1;
        }
        
        // 输出数组的值
        for (int i = 0; i < 5; i++) {
            printf("%d ", ptr[i]);
        }
    ​
        // 释放内存
        free(ptr);
    ​
        return 0;
    }

以上是这些内存管理函数的基本用法。动态内存管理函数允许在程序运行时根据需要分配或释放内存,提供了更灵活和高效地使用内存的方式。重要的是记得在使用完毕后及时释放内存,以避免内存泄漏问题。

3.2 字符串转换与随机数函数

这里是给这些字符串转换函数和随机数函数的例子和用法介绍:

*【1】atoi(const char str)** :将字符串转换为对应的整数并返回结果。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        const char* str = "12345";
        int num = atoi(str);
        
        printf("字符串转换为整数:%d\n", num);
    ​
        return 0;
    }

*【2】atol(const char str)** :将字符串转换为对应的长整数并返回结果。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        const char* str = "1234567890";
        long num = atol(str);
        
        printf("字符串转换为长整数:%ld\n", num);
    ​
        return 0;
    }

*【3】atof(const char str)** :将字符串转换为对应的双精度浮点数并返回结果。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        const char* str = "3.14159";
        double num = atof(str);
        
        printf("字符串转换为双精度浮点数:%f\n", num);
    ​
        return 0;
    }

*【4】itoa(int value, char str, int base)** :将整数转换为字符串并存储在 str 中。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    ​
    int main() {
        int num = 12345;
        char str[20];
        
        itoa(num, str, 10);
        
        printf("整数转换为字符串:%s\n", str);
    ​
        return 0;
    }

【5】rand(void) :生成伪随机数。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    int main() {
        srand(time(NULL)); // 设置随机数发生器的种子为当前时间
        
        for (int i = 0; i < 5; i++) {
            int randomNum = rand();
            printf("随机数:%d\n", randomNum);
        }

        return 0;
    }

【6】srand(unsigned int seed) :设置随机数发生器的种子。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    int main() {
        srand(123); // 设置随机数发生器的种子为 123
        
        for (int i = 0; i < 5; i++) {
            int randomNum = rand();
            printf("随机数:%d\n", randomNum);
        }

        return 0;
    }

3.3 环境控制函数

*【1】system(const char command)** :执行命令行参数中指定的 shell 命令。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>

    int main() {
        const char* command = "ls -l"; // 列出当前目录下的文件和文件夹
        
        int status = system(command);
        
        if (status == -1) {
            printf("命令执行失败。\n");
        } else {
            printf("命令执行成功。\n");
        }

        return 0;
    }

【2】exit(int status) :终止程序的执行并返回状态码。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>

    int main() {
        printf("程序开始执行。\n");
        
        // 退出程序,并返回状态码 0
        exit(0);
        
        printf("此行不会被执行。\n");

        return 0;
    }

【2】_Exit(int status) :终止程序的执行并返回状态码,不进行清理操作。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>

    int main() {
        printf("程序开始执行。\n");
        
        // 退出程序,并返回状态码 0,不进行清理操作
        _Exit(0);
        
        printf("此行不会被执行。\n");

        return 0;
    }

【3】abort(void) :中止程序的执行,并生成一个异常终止信号。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>

    int main() {
        printf("程序开始执行。\n");
        
        printf("触发异常终止信号。\n");
        abort();
        
        printf("此行不会被执行。\n");

        return 0;
    }

3.4 动态分配排序函数

这里是关于动态分配排序函数的例子和用法介绍:

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>

    // 比较函数,用于指定排序顺序
    int compareFunc(const void* a, const void* b) {
        // 将输入的指针转换为所需的类型
        int num1 = *(int*)a;
        int num2 = *(int*)b;

        // 按升序进行排序
        if (num1 < num2) {
            return -1;
        } else if (num1 > num2) {
            return 1;
        } else {
            return 0;
        }
    }

    int main() {
        int arr[] = {5, 2, 8, 6, 1, 3, 9, 7, 4};
        int size = sizeof(arr) / sizeof(arr[0]);

        printf("排序前的数组:");
        for (int i = 0; i < size; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");

        // 使用 qsort 对数组进行排序
        qsort(arr, size, sizeof(int), compareFunc);

        printf("排序后的数组:");
        for (int i = 0; i < size; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");

        return 0;
    }

在这个例子中,定义了一个整型数组 arr,包含了一些无序的元素。使用 qsort 函数对该数组进行排序。qsort 函数接收四个参数:要排序的数组的起始地址 base,数组中元素的个数 nmemb,每个元素的字节大小 size,以及一个比较函数 compar。比较函数用于指定排序的顺序。

compareFunc中,传入的指针转换为 int 类型,并按照升序排序的规则进行比较。如果第一个元素小于第二个元素,返回 -1;如果第一个元素大于第二个元素,返回 1;如果两个元素相等,返回 0

最后,输出排序前和排序后的数组,可以看到数组已经按升序进行了排序。

qsort 函数是对 C 标准库的一部分,经过高效的优化,可以处理不同类型的数组,而不仅仅是整型数组。

3.5 字符串处理函数

【1】rand_r(unsigned int seedp) * :可重入版本的 rand() 函数,用于生成伪随机数。

cpp 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    int main() {
        unsigned int seed = time(NULL);

        for (int i = 0; i < 5; i++) {
            int randomNum = rand_r(&seed);
            printf("%d ", randomNum);
        }
        printf("\n");

        return 0;
    }

在这个例子中,使用 rand_r 函数生成了5个伪随机数。通过向 rand_r 函数传递一个指向种子的指针,确保每次调用 rand_r 函数时都使用不同的种子,使其成为可重入函数。

*【2】system_l(const char command, locale_t loc)** :根据指定的本地化环境执行命令。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main() {
    const char* command = "ls -l"; // 列出当前目录下的文件和文件夹
    locale_t loc = newlocale(LC_ALL_MASK, "", NULL);

    int status = system_l(command, loc);

    if (status == -1) {
        printf("命令执行失败。\n");
    } else {
        printf("命令执行成功。\n");
    }

    freelocale(loc);

    return 0;
}

在这个例子中,使用 system_l 函数执行了一个命令 ls -l,该命令用于列出当前目录下的文件和文件夹。使用 newlocale 函数创建了一个新的本地化环境 loc,并将其作为参数传递给 system_l 函数。最后,使用 freelocale 函数释放本地化环境。

【3】posix_memalign(void memptr, size_t alignment, size_t size):分配对齐的内存块。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    void* memPtr;
    size_t alignment = 16; // 对齐要求为16字节
    size_t size = 32; // 分配32字节的内存

    int status = posix_memalign(&memPtr, alignment, size);

    if (status == 0) {
        printf("内存分配成功。\n");
        
        // 使用分配的内存
        
        free(memPtr);
    } else {
        printf("内存分配失败。\n");
    }

    return 0;
}

在这个例子中,使用 posix_memalign 函数分配了一个对齐的内存块,要求对齐要求为16字节,分配32字节的内存。通过传递指向 memPtr 的指针,可以在函数内部接收分配的内存地址。最后,使用 free 函数释放内存。

【4】aligned_alloc(size_t alignment, size_t size) :分配对齐的内存块。

arduino 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    size_t alignment = 16; // 对齐要求为16字节
    size_t size = 32; // 分配32字节的内存

    void* memPtr = aligned_alloc(alignment, size);

    if (memPtr != NULL) {
        printf("内存分配成功。\n");
        
        // 使用分配的内存
        
        free(memPtr);
    } else {
        printf("内存分配失败。\n");
    }

    return 0;
}

在这个例子中,使用 aligned_alloc 函数分配了一个对齐的内存块,要求对齐要求为16字节,分配32字节的内存。通过将返回的内存指针赋值给 memPtr 变量,可以获得分配的内存地址。最后,使用 free 函数释放内存。

这些字符串处理函数提供了在 C 语言中处理字符串和执行相关操作的功能。使用这些函数时需要小心内存管理,避免出现内存泄漏等问题。

相关推荐
爱上语文35 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
serve the people39 分钟前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
罗政6 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
拾光师8 小时前
spring获取当前request
java·后端·spring
Java小白笔记9 小时前
关于使用Mybatis-Plus 自动填充功能失效问题
spring boot·后端·mybatis
JOJO___11 小时前
Spring IoC 配置类 总结
java·后端·spring·java-ee
白总Server12 小时前
MySQL在大数据场景应用
大数据·开发语言·数据库·后端·mysql·golang·php
Lingbug13 小时前
.Net日志组件之NLog的使用和配置
后端·c#·.net·.netcore
计算机学姐13 小时前
基于SpringBoot+Vue的篮球馆会员信息管理系统
java·vue.js·spring boot·后端·mysql·spring·mybatis
好兄弟给我起把狙13 小时前
[Golang] Select
开发语言·后端·golang