<stdlib.h>头文件: C 语言常用标准库函数详解

这篇具有很好参考价值的文章主要介绍了<stdlib.h>头文件: C 语言常用标准库函数详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

在C语言中,<stdlib.h> 是一个重要的头文件,它包含了一些标准库函数,提供了内存分配、随机数生成、字符串转换等功能。本博客将深入解析 <stdlib.h> 头文件,介绍其中一些常用函数的用法和实现原理。


1. <stdlib.h> 概览

<stdlib.h> 是 C 标准库的一部分,它定义了一些宽泛的实用函数。这些函数通常涉及内存管理、伪随机数生成、整数转换等方面。

1.1 头文件包含

在使用 <stdlib.h> 头文件之前,我们通常会在程序中包含以下语句:

#include <stdlib.h>

这样可以确保我们在程序中使用标准库函数时能够正确调用相应的功能。


2. 内存管理函数

2.1 malloc 函数

  • 功能:malloc 函数用于在堆上分配一块指定大小的内存空间。成功时返回指向分配内存的指针,失败时返回 NULL
  • 原型:void* malloc(size_t size);
#include <stdio.h>
#include <stdlib.h>

int main() {
	// 定义一个指针,分配包含 5 个整数的内存块
	int *dynamicArray = (int *)malloc(5 * sizeof(int));


	// 检查内存是否成功分配
	if (dynamicArray == NULL) {
		printf( "内存分配失败\n");
		return 1; // 返回错误代码
	}

	// 向动态数组中写入数据
	int i;
	for (i = 0; i < 5; ++i) {
		dynamicArray[i] = i * 2;
	}

	// 输出动态数组的内容
	printf("动态数组的内容:\n");
	for (i = 0; i < 5; ++i) {
		printf("%d ", dynamicArray[i]);
	}

	// 释放动态分配的内存
	free(dynamicArray);

	return 0;
}

动态数组的内容:
0 2 4 6 8

2.2 calloc 函数

  • 功能:calloc 函数用于在堆上分配一块指定数量和大小的内存空间,与 malloc 不同的是,calloc 会将分配的内存块初始化为零。
  • 原型: void* calloc(size_t num, size_t size);

例如 int* 初始化就是0
char* 初始化就是’\0’

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

int main() {
    // 定义一个指针,用于存储分配的内存地址
    int *dynamicArray;

    // 使用 calloc 分配包含 5 个整数的内存块
    dynamicArray = (int *)calloc(5, sizeof(int));

    // 检查内存是否成功分配
    if (dynamicArray == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return 1; // 返回错误代码
    }

    // 输出动态数组的内容,此时数组已被初始化为零
    printf("动态数组的内容:\n");
    int i;
    for (i = 0; i < 5; ++i) {
        printf("%d ", dynamicArray[i]);
    }

    // 释放动态分配的内存
    free(dynamicArray);

    return 0;
}

动态数组的内容:
0 0 0 0 0

2.3 realloc 函数

  • 功能:realloc 函数用于修改之前由 malloccallocrealloc 分配的内存块的大小。它可以用于扩大或缩小内存块。
  • 原型: void* realloc(void* ptr, size_t size);
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 初始分配 10 个整数大小的内存块
    int *arr = (int *)malloc(10 * sizeof(int));

    if (arr == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return 1;
    }

    printf("初始分配内存后的地址:%p\n", (void *)arr);

    // 使用 realloc 缩小内存块到 5 个整数大小
    int *newArr = (int *)realloc(arr, 5 * sizeof(int));

    if (newArr == NULL) {
        fprintf(stderr, "内存重新分配失败\n");
        free(arr);  // 如果 realloc 失败,需要释放原始的内存块
        return 1;
    }

    printf("缩小内存后的地址:%p\n", (void *)newArr);

    // 现在 newArr 可以用于存储 5 个整数

    // 不要忘记释放内存
    free(newArr);

    return 0;
}


2.4 free 函数

  • 功能:free 函数用于释放之前由 malloccallocrealloc 分配的内存空间。释放后,该指针不再指向有效的内存区域。
  • 原型:void free(void* ptr);
// 例子
free(arr);

3. 随机数生成函数

3.1 rand 函数

  • 功能:rand 函数用于生成一个伪随机数。每次调用 rand 都会返回一个范围在 0 到 RAND_MAX 之间的整数。
  • 原型:int rand(void);

请注意,rand 函数生成的是伪随机数,其实际上是通过一定的算法计算的,因此不是真正的随机数。

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


int main() {

    int randomNum1 = rand();
    int randomNum2 = rand();

    // 打印随机数
    printf("Random Number 1: %d\n", randomNum1);
    printf("Random Number 2: %d\n", randomNum2);

    return 0;
}

// 第一次运行
Random Number 1: 41
Random Number 2: 18467

// 第二次运行
Random Number 1: 41
Random Number 2: 18467
...

3.2 srand 函数

  • 功能:srand 函数用于设置 rand 函数的种子值,以便生成不同的随机数序列。
  • 原型: void srand(unsigned int seed);
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    // 没有使用 srand 设置种子
    printf("未使用 srand:\n");
    int i;
	for (i = 0; i < 5; ++i) {
        printf("%d ", rand());
    }

    // 使用 srand 设置种子
    srand(time(NULL)); // 42 只是一个示例种子值,可以是任何值
    printf("\n使用 srand:\n");
    for (i = 0; i < 5; ++i) {
        printf("%d ", rand());
    }

    return 0;
}

// 第一次运行
未使用 srand:
41 18467 6334 26500 19169
使用 srand:
29346 6213 16299 17151 17694

// 第二次运行
未使用 srand:
41 18467 6334 26500 19169
使用 srand:
29372 26664 28140 13050 1907

...

在这个例子中,srand(time(NULL)) 使用当前时间作为随机数生成器的种子。由于时间每次都在变化,这样就能确保每次运行程序都会得到不同的随机数序列。


4. 字符串转换函数

4.1 atoi 函数

  • 功能:atoi 函数用于将字符串转换为整数。
  • 原型: int atoi(const char* str);
#include <stdio.h>
#include <stdlib.h>

int main() {
	// 定义一个字符串
	char str1[] = "12345";
	char str2[] = "12345abdc";
	// 使用atoi将字符串转换为整数
	int num1 = atoi(str1);
	int num2 = atoi(str2);

	// 打印结果
	printf("String str1: %s\n", str1);
	printf("Integer int1: %d\n", num1);

	printf("String str2: %s\n", str2);
	printf("Integer int2: %d\n", num2);
	return 0;
}
String str1: 12345
Integer int1: 12345
String str2: 12345abdc
Integer int2: 12345

4.2 atof 函数

  • 功能:atof 函数用于将字符串转换为浮点数。
  • 原型: double atof(const char* str);
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 定义字符串
    char str1[] = "12345.137";
    char str2[] = "12345.111abdc";
    
    // 使用atof将字符串转换为浮点数
    double num1 = atof(str1);
    double num2 = atof(str2);

    // 打印结果
    printf("字符串 str1:%s\n", str1);
    printf("浮点数 num1:%lf\n", num1);

    printf("字符串 str2:%s\n", str2);
    printf("浮点数 num2:%lf\n", num2);

    return 0;
}

字符串 str1:12345.137
浮点数 num1:12345.137000
字符串 str2:12345.111abdc
浮点数 num2:12345.111000

4.3 itoa 函数

  • 功能:itoa 函数用于将整数转换为字符串。它接受三个参数:要转换的整数 value,存储结果的字符串指针 str,和进制 basebase 可以是 2 到 36 之间的任意值,表示输出的字符串使用的进制。
  • 原型: char* itoa(int value, char* str, int base);
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 定义整数
    int num1 = 12345;
    int num2 = -6789;

    // 定义足够大的字符数组来存储转换后的字符串
    char str1[20];
    char str2[20];

    // 使用 itoa 将整数转换为字符串
    itoa(num1, str1, 10);  // 第三个参数是基数,这里使用10进制
    itoa(num2, str2, 10);

    // 打印结果
    printf("整数 num1:%d\n", num1);
    printf("字符串 str1:%s\n", str1);

    printf("整数 num2:%d\n", num2);
    printf("字符串 str2:%s\n", str2);

    return 0;
}

整数 num1:12345
字符串 str1:12345
整数 num2:-6789
字符串 str2:-6789

4.4 ltoa 函数

  • 功能:将长整型转换为字符串,参数和用法与 itoa 类似-
  • 原型: char* ltoa(long value, char* str, int base);
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 定义整数
    long num1 = 12345;
    long num2 = 987654321;

    // 使用ltoa将整数转换为字符串
    char str1[20];  // 假设足够大以容纳转换后的字符串
    char str2[20];  

    ltoa(num1, str1, 10);
    ltoa(num2, str2, 10);

    // 打印结果
    printf("整数 num1:%ld\n", num1);
    printf("字符串 str1:%s\n", str1);

    printf("整数 num2:%ld\n", num2);
    printf("字符串 str2:%s\n", str2);

    return 0;
}

整数 num1:12345
字符串 str1:12345
整数 num2:987654321
字符串 str2:987654321

4.5 ultoa函数

  • 功能:将无符号长整型转换为字符串,参数和用法与 itoa 类似
  • 原型: char* ultoa(unsigned long value, char* str, int base);
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 定义无符号长整型数
    unsigned long num1 = 12345;
    unsigned long num2 = 879631;

    // 定义存储转换后字符串的数组
    char str1[20]; // 大小需要足够存储转换后的字符串
    char str2[20];

    // 使用 ultoa 将无符号长整型数转换为字符串
    ultoa(num1, str1, 10);
    ultoa(num2, str2, 10);

    // 打印结果
    printf("无符号长整型数 num1: %lu\n", num1);
    printf("字符串 str1: %s\n", str1);

    printf("无符号长整型数 num2: %lu\n", num2);
    printf("字符串 str2: %s\n", str2);

    return 0;
}

String str1: 12345
Integer int1: 12345
String str2: 879631
Integer int2: 879631

4.5 strtol函数

  • 功能:将二进制字符串转换为整数,参数和用法与 itoa 类似
  • 原型:long int strtol(const char *str, char **endptr, int base);
#include <stdio.h>
#include <stdlib.h>

int main() {
    char binaryString[] = "110101"; // 二进制字符串
    char *endptr; // 用于存储转换后的剩余部分的指针

    // 使用 strtol 将二进制字符串转换为整数
    long result = strtol(binaryString, &endptr, 2);

    // 检查转换是否成功
    if (*endptr != '\0') {
        printf("转换失败,无效字符:%c\n", *endptr);
    } else {
        printf("转换成功,结果为:%ld\n", result);
    }

    return 0;
}

转换成功,结果为:53

5 其他函数

5.1 qsort函数

qsort & bsearch 实现二分查找

  • 功能:用于对数组进行快速排序的函数
  • 原型: void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

下面对函数的参数进行详解:

  • base:指向要排序的数组的起始地址的指针。
  • nmemb:数组中元素的个数。
  • size:数组中每个元素的大小(以字节为单位)。
  • compar:比较函数的指针。这个函数用于定义数组元素之间的比较规则。它接受两个指向元素的指针,比较这两个元素的大小,并返回一个整数,表示它们的相对顺序。比较函数的返回值有三种情况:
    • 若返回值小于 0,则表示第一个元素要在第二个元素后面
    • 若返回值等于 0,不进行操作
    • 若返回值大于 0,则表示第一个元素要在第二个元素之前

qsort 函数使用快速排序算法,这是一种高效的排序算法,平均时间复杂度为 O(n log n)。排序是在原地进行的,不需要额外的辅助数组。

以下是一个简单的示例,演示如何使用 qsort 函数:

#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, 9, 1, 5, 6};
    size_t n = sizeof(arr) / sizeof(arr[0]);

    // 调用 qsort 函数进行排序
    qsort(arr, n, sizeof(arr[0]), compare);

    // 输出排序后的数组
    for (size_t i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }

    return 0;
}
1 2 5 5 6 9

在这个例子中,compare 函数用于比较整数,将数组元素按升序排序。qsort 函数将会根据 compare
函数的定义对数组进行排序。在实际使用中,可以根据需要定义不同的比较函数来实现不同的排序规则。

compare 的示例

整型

int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

浮点型

int cmp_float(const void* e1, const void* e2)
{
	return (int)(*(float*)e1 - *(float*)e2);
}

字符串

int cmp_str_size(const void* e1, const void* e2)
{
	return strcmp((char*)e1,(char*)e2);
}

字符串的长度

int cmp_str_len(const void* e1, const void* e2)
{
	return strlen((char*)e1)-strlen((char*)e2);
}

结构体

int cmp_by_age(const void*e1, const void*e2)
{
	return (int)(((stu*)e1)->weight - ((stu*)e2)->weight);
}

需要注意的是:返回结果一定要确保是整形,如果不是一定要强制类型转换成整形!

5.1 swab函数

  • 功能:在不同字节序之间交换数据
  • 原型: void swab(char *from,char *to,int n);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
 
int main(void){
 
    char suc[20]={"1234567890"};
 
    char des[20];
 
    swab(suc,des,strlen(suc));
    
    printf("This is  suc: %s\n",suc);

    printf("This is dest: %s\n",des);
 
    return 0;
 
}
This is  suc: 1234567890
This is dest: 2143658709

5.12bsearch函数

qsort & bsearch 实现二分查找

  • 功能:用于二分法搜索
  • 原型: void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

参数说明:

  • key:要查找的元素的指针,即要在数组中查找的元素。
  • base:指向已排序数组的起始地址的指针。
  • nmemb:数组中元素的个数。
  • size:每个元素的大小(以字节为单位)。
  • compar:比较函数的指针,用于定义元素之间的比较规则。该函数应返回一个整数,表示两个元素的相对顺序。

bsearch函数的返回值是一个指向匹配元素的指针,如果找到匹配的元素,则返回指向该元素的指针;如果没有找到匹配的元素,则返回NULL

比较函数compar的原型如下:

int compar(const void *a, const void *b);

比较函数应该返回一个整数,其含义如下:

  • 如果a小于b,则返回负值。
  • 如果a等于b,则返回零。
  • 如果a大于b,则返回正值。
#include <stdio.h>
#include <stdlib.h>

// 比较函数,用于定义整数之间的比较规则
int compareIntegers(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int arr[] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 18};
    int size = sizeof(arr) / sizeof(arr[0]);
    int key = 12;

    // 使用bsearch在已排序数组中查找元素
    int *result = (int*)bsearch(&key, arr, size, sizeof(arr[0]), compareIntegers);

    if (result != NULL) {
        printf("元素 %d 找到在数组中的位置:%ld\n", key, result - arr);
    } else {
        printf("元素 %d 未找到\n", key);
    }

    return 0;
}

元素 12 找到在数组中的位置:6

结语

<stdlib.h> 头文件提供了许多在 C 语言中常用的功能,从内存管理到随机数生成,再到字符串转换,都有涉及。熟练掌握这些函数的用法,有助于提高程序的效率和可维护性。

请记得在使用这些函数时要注意内存的分配和释放,以免造成内存泄漏和其他不稳定的行为。希望本博客对你理解和使用 <stdlib.h> 有所帮助。如有疑问或建议,欢迎留言讨论。文章来源地址https://www.toymoban.com/news/detail-844218.html

到了这里,关于<stdlib.h>头文件: C 语言常用标准库函数详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言】标准库(头文件、静态库、动态库),windows与Linux平台下的常用C语言标准库

    C语言标准库是一组 预定义函数、宏和文件的集合 ,这些函数和文件提供了一些基本的功能和操作,可供C语言程序使用。C语言标准库由C语言的制定者定义,并包含在C语言的编译器中。 C语言标准库包含了许多常见的功能,例如输入和输出操作、字符串处理、内存管理、数学

    2024年02月10日
    浏览(23)
  • 使用vscode中编写c语言——无法打开 源 文件 “stdlib.h“C/C++(1696)问题

    出现这个问题原因如下: 1、没有下载编辑器或者是没有配置好该编辑器的环境变量。 可以通过如下方法检查是否安装并配置好编辑器:打开终端:按win+R cmd,然后输入gcc-v,查看是否有mingw64编辑器,如下图是已经配置好了 如果没有的话就说明没有安装或者没有配置好环境变

    2024年02月04日
    浏览(27)
  • C++动态库编程 | C++名称改编、标准C接口、extern “C”、函数调用约定以及def文件详解

    目录 1、导入导出声明 2、C++函数名称改编与extern \\\"C\\\" 3、函数调用约定与跨语言调用 3.1、函数调用约定 3.2、跨语言调用dll库接口 3.3、函数调用约定以哪个为准 4、def文件的使用 5、在C++程序中引用ffmpeg库中的头文件链接报错问题 6、最后 VC++常用功能开发汇总(专栏文章列表,

    2024年02月11日
    浏览(34)
  • 详解C语言string.h中常用的14个库函数(四)

    本篇博客会讲解最后4个函数,分别是memset, memcpy, memmove, memcmp。这4个函数开头都是mem,即memory(内存)的缩写。 memset可以用来设置内存中的值。该函数可以把从ptr指向的空间开始,后面的num个字节设置成value的值。 举个简单的例子。假设有一个数组: 我们想把这个数组的前

    2023年04月24日
    浏览(26)
  • c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))

    上篇文章介绍了一些常用的字符串函数,大家可以跳转过去浏览一下:c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))_总之就是非常唔姆的博客-CSDN博客 今天接着来介绍一些:  目录 一.字符串查找 1.strstr() 1.1示例 1.2注意事项: 1.3模拟实现  2.

    2024年02月07日
    浏览(33)
  • 【C语言_文件_进程_进程间通讯 常用函数/命令 + 实例】.md_update:23/10/27

    getpid(); fork(); vfork(); //_t 一律返回的是int //获取进程ID 就是pid pid_t getpid(void); //fork创建子进程 pid_t fork(void); //这里返回的是的pid = 0 就是子进程,pid 0 就是父进程; //所以可以通过判断pid的值,来区别父子进程需要执行的代码; //注意fork开辟的子进程,没有等待一说,父子进

    2024年02月07日
    浏览(34)
  • C++标准头文件/常用头文件

    C++ 中有很多标准头文件,每个头文件都提供了不同的函数和数据类型。以下是一些常用的头文件及其用法: iostream :提供输入输出功能,如 cout 和 cin ,用于屏幕输入和输出。 cmath :提供数学函数,如三角函数、对数、指数和幂函数等。 cstdlib :提供与 C 标准库有关的函数

    2024年02月16日
    浏览(45)
  • ⚡【C语言趣味教程】(1) 深入浅出 HelloWorld | 通过 HelloWorld 展开教学 | 头文件详解 | main 函数详解

      🔗 《C语言趣味教程》👈 猛戳订阅!!! 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人一贯的幽默式写作风格,当然,在有趣的同时也同样会保证文章的质量,旨在能够产出 \\\"有趣的干货\\\" !

    2024年02月13日
    浏览(36)
  • 【C语言趣味教程】(1) 深入浅出 HelloWorld:通过 HelloWorld 展开教学 | 头文件详解 | main 函数详解

      🔗 《C语言趣味教程》👈 猛戳订阅!!! 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人一贯的幽默式写作风格,当然,在有趣的同时也同样会保证文章的质量,旨在能够产出 \\\"有趣的干货\\\" !

    2024年02月15日
    浏览(39)
  • ⚡【C语言趣味教程】(1):深入浅出 HelloWorld | 通过 HelloWorld 展开教学 | 头文件详解 | main 函数详解

      🔗 《C语言趣味教程》👈 猛戳订阅!!! 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人一贯的幽默式写作风格,当然,在有趣的同时也同样会保证文章的质量,旨在能够产出 \\\"有趣的干货\\\" !

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包