1.1.1 C语言常用的一些函数(持续更新)

news2025/1/16 20:02:04
总框架见(0. 总框架-CSDN博客)
(1)socket

(a)分配fd;(b)分配tcp控制块(tcb)

int socket(int domain, int type, int protocol);

       AF_INET             IPv4 Internet protocols          ip(7)
       AF_INET6            IPv6 Internet protocols          ipv6(7)
       AF_IPX              IPX - Novell protocols
(2)bind

把fd和ip绑定到tcp控制块

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
(3)listen

开始监听fd

int listen(int sockfd, int backlog);
(4)accept

(a)为客户端分配fd;(b)分配tcp控制块(tcb)

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
(5)recv

从内核copy数据到用户空间

 ssize_t recv(int sockfd, void *buf, size_t len, int flags);
(6)send

从用户空间copy数据到内核

ssize_t send(int sockfd, const void *buf, size_t len, int flags);
(7)connect

connect客户端发送连接请求

 int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);
(8)epoll_create
int epoll_create(int size);
(9)epoll_ctl
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

    EPOLL_CTL_ADD       EPOLLIN        EPOLLLT 
    EPOLL_CTL_MOD       EPOLLOUT       EPOLLET
    EPOLL_CTL_DEL
(10)epoll_wait
int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
(11)poll
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
(12)select
int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);
(13)read
ssize_t read(int fd, void *buf, size_t count);

参数说明
int fd
文件描述符,表示要读取的文件、管道、套接字或设备。
通常由系统调用(如 open()、socket() 等)返回。
void *buf
指向接收读取数据的缓冲区指针。
系统调用会将读取的数据写入到此缓冲区。
size_t count
要读取的最大字节数,指定缓冲区的大小。

返回值
成功时:
返回读取的字节数(可能小于请求的字节数 count)。
返回 0 表示已到达文件末尾(EOF)。
失败时:
返回 -1,并设置全局变量 errno 来指示错误原因
(14)write
ssize_t write(int fd, const void *buf, size_t count);

参数说明
int fd
文件描述符,表示数据要写入的目标。
通常由 open() 或 socket() 等函数返回。
const void *buf
指向包含要写入数据的缓冲区的指针。
size_t count
指定要写入的字节数

返回值
成功时:
返回实际写入的字节数(可能小于请求的字节数 count)。
失败时:
返回 -1,并设置全局变量 errno 表示错误原因。
(15)fork

创建的新进程,它是父进程的一个副本,几乎所有的数据(变量、文件描述符等)都会被复制。

返回值
父进程中:fork() 返回子进程的 PID(正整数)。
子进程中:fork() 返回 0。
出错时:返回 -1,同时设置 errno
(16)perror

读取系统定义的全局变量 errno,然后通过查找对应的错误码输出一个与其相关联的错误消息

int main() {
    int fd = open("nonexistent_file.txt", O_RDONLY);
    if (fd == -1) {
        perror("Error opening file");
    }
    return 0;

输出:
Error opening file: No such file or directory
(17)strerror

如果需要获取错误描述并在代码中使用,而不是直接打印,可以使用 strerror(errno)。

#include <string.h>
printf("Error: %s\n", strerror(errno));
(18)atoi

是 C 标准库中用于将字符串转换为整数的函数。atoi 是 ASCII to Integer 的缩写。

int atoi(const char *str);

参数
str
指向需要转换的字符串(应以空字符 \0 结束)。

返回值
如果字符串可以成功解析为整数,则返回该整数值。
如果字符串不包含有效的数字,则返回值可能为 0(不安全,推荐使用 strtol 替代)。

int main() {
    char str1[] = "   -456";
    char str2[] = "+789";

    printf("Converted number 1: %d\n", atoi(str1)); 
    // Output: -456
    printf("Converted number 2: %d\n", atoi(str2)); 
    // Output: 789
    return 0;
}
(19)strcmp

是 C 标准库中的一个函数,用于比较两个字符串的大小(基于字典序)。

int strcmp(const char *str1, const char *str2);

参数解释
str1
指向第一个字符串的指针。
str2
指向第二个字符串的指针

返回值
小于 0
如果 str1 的字典序小于 str2。
等于 0
如果 str1 和 str2 内容完全相同。
大于 0
如果 str1 的字典序大于 str2

int main() {
    char str1[] = "apple";
    char str2[] = "banana";

    int result = strcmp(str1, str2);
    printf("Result: %d\n", result); 
    // Output: Result: negative value (e.g., -1)
    return 0;
}
(20)memset

是 C 标准库中的一个函数,主要用于对一块内存区域进行初始化或设置。

void *memset(void *s, int c, size_t n);

参数说明
void *s
指向要初始化的内存区域的起始地址。
int c
用于设置的值,会被解释为一个 unsigned char(0 到 255),然后复制到内存区域。
size_t n
要设置的字节数。

返回值
返回指向内存区域 s 的指针。
功能
将指定的值填充到连续的内存区域中。
常用于数组或结构体的初始化。

常见用途
功能1:初始化数组
使用 memset 将数组清零或设置为某个默认值。
int arr[10];
memset(arr, 0, sizeof(arr)); // 初始化为 0

功能2:清空结构体中的所有成员变量。
struct Data {
    int a;
    char b[20];
} data;
memset(&data, 0, sizeof(data)); // 将结构体清零
(21)memcpy

是 C 标准库中的一个函数,将内存块中的数据从一个位置复制到另一个位置。

void *memcpy(void *dest, const void *src, size_t n);

参数说明
void *dest
目标内存地址,表示复制数据的目的地。
const void *src
源内存地址,表示复制数据的来源。
size_t n
要复制的字节数。

返回值
返回目标内存地址 (dest) 的指针。

基本用法
int main() {
    char src[] = "Hello, World!";
    char dest[20];
    memcpy(dest, src, strlen(src) + 1);  
    // 复制 src 到 dest
    printf("Source: %s\n", src);
    printf("Destination: %s\n", dest);
    return 0;
}

输出:
Source: Hello, World!
Destination: Hello, World!

int main() {
    int src[5] = {1, 2, 3, 4, 5};
    int dest[5];
    memcpy(dest, src, 5 * sizeof(int));  // 复制 5 个整型值
    for (int i = 0; i < 5; i++) {
        printf("dest[%d] = %d\n", i, dest[i]);
    }
    return 0;
}

输出:
dest[0] = 1
dest[1] = 2
dest[2] = 3
dest[3] = 4
dest[4] = 5

应用场景
字符串操作:复制字符串的原始字节数据(与 strcpy 的主要区别是 memcpy 可以复制非空终止的二进制数据)。
数组复制:处理任意类型的数组,例如 int 或 float。
内存初始化:与 memset 配合使用,分配和初始化内存。
结构体复制:在需要字节级拷贝时,处理复杂结构体数据。
(22)strncpy

复制字符串的指定长度

char *strncpy(char *dest, const char *src, size_t n);

参数说明
char *dest
目标字符数组的指针,复制后的字符串将存储在这里。
const char *src
源字符串的指针,要被复制的字符串内容。
size_t n
要复制的最大字符数。如果 src 长度小于 n,则目标字符串会填充空字符(\0);如果 src 长度大于或等于 n,则目标字符串不会被空字符终止。

返回值
返回 dest 指针,即目标字符串的指针。

功能
将源字符串 src 复制到目标字符数组 dest 中,最多复制 n 个字符。
如果源字符串长度小于 n,strncpy 会用空字符(\0)填充目标字符串的剩余部分;如果源字符串长度大于或等于 n,目标字符串没有终止符(\0)。

与 strcpy 的对比
strcpy:直接复制整个字符串,直到遇到终止符 \0。无法防止溢出。
例如:strcpy(dest, src);
strncpy:复制指定数量的字符,并会根据情况使用终止符 \0 填充目标字符串。
更安全,因为可以限制复制的字符数,防止溢出

int main() {
    char src[] = "Hello, World!";
    char dest[20];
    // 将最多 10 个字符从 src 复制到 dest
    strncpy(dest, src, 10);
    dest[10] = '\0';  // 确保终止符
    printf("Copied string: %s\n", dest);  
    // 输出: Hello, Wo
    return 0;
}

代码解析
strncpy(dest, src, 10);:最多复制 10 个字符。
然后手动添加终止符 dest[10] = '\0';,这是因为源字符串可能没有包含终止符(在字符串更长的情况下)。
结果是 dest 中的内容为 "Hello, Wo",因为 src 前 10 个字符被复制。
(23)strlen
size_t strlen(const char *str);

功能
strlen 用于计算字符串的长度(不包括终止符 \0)。
它会遍历字符串直到遇到第一个空字符 \0 为止,并返回已遍历的字符数。
参数说明
const char *str
指向以空字符 \0 结尾的字符串。
返回值
返回字符串的长度(不包括终止符 \0)的大小,以 size_t 类型表示。

int main() {
    char str[] = "Hello, World!";
    size_t length = strlen(str);
    printf("The length of the string is: %zu\n", length); 
    // 输出: 13
    return 0;
}

代码解析
字符串 str[]:
包含 "Hello, World!",长度为 13(不包括终止符 \0)。
strlen(str):
遍历字符串,直到遇到终止符 \0。
计算字符数:'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'。
返回值:
返回 13,表示字符串的长度

与 sizeof 的对比
strlen运行时计算字符串长度。适用于动态字符串。不包括终止符 \0。
sizeof编译时计算数组大小(字节数)。适用于固定大小的字符数组。包括终止符 \0 的大小。
示例:
char str1[] = "Hello";
char *str2 = "Hello";
printf("strlen(str1): %zu\n", strlen(str1));  // 输出 5
printf("sizeof(str1): %zu\n", sizeof(str1));  // 输出 6
printf("strlen(str2): %zu\n", strlen(str2));  // 输出 5
printf("sizeof(str2): %zu\n", sizeof(str2));  // 输出 8 (指针大小)
(24)snprint

用于将格式化的数据写入字符串,并确保不会溢出字符串缓冲区。它是 sprintf 的更安全版本,避免了可能的缓冲区溢出问题。

int snprintf(char *str, size_t size, const char *format, ...);

参数说明
char *str
指向要写入格式化输出的字符数组。
size_t size
指定目标字符串的最大大小,包括结尾的 '\0'(空字符)。snprintf 确保总输出长度不超过这个值。
const char *format
格式化字符串,与 printf 的格式化字符串类似,例如 %d, %s, %f 等。
... (可变参数)
需要插入到格式化字符串中的数据

返回值
返回写入的字符数,不包括终止的 \0 字符:
如果 size 足够大,返回值是实际写入的字符数。
如果 size 不够大,返回值是本应该写入的字符数(截断的字符串长度)。

缓冲区不足的情况
int main() {
    char buffer[10];
    int num = 123456;
    int written = snprintf(buffer, sizeof(buffer), "Number: %d", num);
    printf("Formatted string: %s\n", buffer);  // 输出截断的内容
    printf("Characters written: %d\n", written);  // 返回未截断的实际字符数
    return 0;
}

输出:
Formatted string: Number: 1
Characters written: 12
说明:
缓冲区 buffer 长度为 10,无法容纳完整字符串 "Number: 123456"。
结果字符串被截断为 "Number: 1",但 snprintf 的返回值是实际所需的字符数 12
(25)malloc

堆上分配内存,并返回指向分配内存块的指针。

void *malloc(size_t size);

参数说明
size
请求分配的内存大小(以字节为单位)。size 必须大于 0。

返回值
返回分配的内存的起始地址,类型是 void*,即通用指针。
如果内存分配失败(比如系统没有足够的内存),malloc 返回 NULL。

特性
动态内存分配
malloc 函数从程序的堆内存区域(Heap)分配指定大小的内存。在堆上分配的内存空间不会随着函数调用结束而销毁,必须通过 free 显式释放。

基本用法
int main() {
    int *arr = (int *)malloc(5 * sizeof(int));  // 动态分配 5 个整数的空间
    if (arr == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
        printf("%d ", arr[i]);
    }
    printf("\n");
    free(arr);  // 释放内存
    return 0;
}

输出:
1 2 3 4 5
(26)free

用于释放由动态内存分配函数(如 malloc、calloc 或 realloc)分配的内存。将之前分配的动态内存归还给操作系统或内存管理器。释放后,该内存块可以被再次分配和使用。

void free(void *ptr);

参数说明
void *ptr
动态分配的内存块的指针,该指针通常是通过 malloc、calloc 或 realloc 返回的。
如果 ptr 是 NULL,free 不会进行任何操作。

基本用法
int main() {
    int *arr = (int *)malloc(5 * sizeof(int));  // 动态分配 5 个整数的空间
    if (arr == NULL) {
        perror("malloc failed");
        return 1;
    }
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
        printf("%d ", arr[i]);
    }
    printf("\n");
    free(arr);  // 释放内存
    arr = NULL; // 避免悬空指针
    return 0;
}

输出:
1 2 3 4 5

常见问题
1. 为什么释放未分配的内存是危险的?
如果尝试 free 一个未分配的指针,可能会导致程序崩溃或者未定义行为,因为内存管理器试图释放一个它没有跟踪的内存区域。
2. 为什么要将指针置为 NULL?
避免悬空指针(Dangling Pointer)。
悬空指针是指指向已释放内存区域的指针,如果不小心使用它(如读写操作),可能会导致不可预测的错误。
3. 始终配对 malloc 和 free,避免内存泄漏和悬空指针。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2277683.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux x86_64 程序动态链接之GOT 和 PLT

文章目录 前言一、动态链接二、位置无关代码三、GOT 和 PLT3.1 GOT3.2 PLT3.3 延时绑定3.4 示例 四、demo演示五、延迟绑定技术和代码修补参考资料 前言 这篇文章描述了&#xff1a;Linux x86_64 程序静态链接之重定位&#xff0c;接来本文描述Linux x86_64 程序动态链接之GOT…

学习记录-责任链模式验证参数

学习记录-责任链模式验证参数 1.什么是责任链模式 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许将请求沿着一个处理链传递&#xff0c;直到链中的某个对象处理它。这样&#xff0c;发送者无需知道哪个对象将处理…

练习:MySQL单表查询与多表查询

一.单表查询 创建worke数据库&#xff0c;在数据库底下创建worker表 mysql> create database worke; Query OK, 1 row affected (0.00 sec)mysql> show databases; -------------------- | Database | -------------------- | information_schema | | mysql …

HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (四、最近上映电影滚动展示及加载更多的实现)

在HarmonyOS NEXT开发环境中&#xff0c;可以使用多种组件和库来构建丰富且交互友好的应用。本文将展示如何使用HarmonyOS NEXT框架和nutpi/axios库&#xff0c;从零开始实现一个简单的影视APP的首页&#xff0c;主要关注最近上映电影的滚动展示及加载更多功能的实现。 开源项目…

卷积神经05-GAN对抗神经网络

卷积神经05-GAN对抗神经网络 使用Python3.9CUDA11.8Pytorch实现一个CNN优化版的对抗神经网络 简单的GAN图片生成 CNN优化后的图片生成 优化模型代码对比 0-核心逻辑脉络 1&#xff09;Anacanda使用CUDAPytorch2&#xff09;使用本地MNIST进行手写图片训练3&#xff09;…

客户案例:某家居制造企业跨境电商,解决业务端(亚马逊平台)、易仓ERP与财务端(金蝶ERP)系统间的业务财务数据对账互通

一、系统定义 1、系统定位&#xff1a; 数据中台系统是一种战略选择和组织形式&#xff0c;通过有型的产品支撑和实施方法论&#xff0c;解决企业面临的数据孤岛、数据维护混乱、数据价值利用低的问题&#xff0c;依据企业特有的业务和架构&#xff0c;构建一套从数据汇聚、开…

服务器一次性部署One API + ChatGPT-Next-Web

服务器一次性部署One API ChatGPT-Next-Web One API ChatGPT-Next-Web 介绍One APIChatGPT-Next-Web docker-compose 部署One API ChatGPT-Next-WebOpen API docker-compose 配置ChatGPT-Next-Web docker-compose 配置docker-compose 启动容器 后续配置 同步发布在个人笔记服…

辅助云运维

为客户提供运维支持&#xff0c;保障业务连续性。 文章目录 一、服务范围二、服务内容三、服务流程四、 服务交付件五、责任分工六、 完成标志 一、服务范围 覆盖范围 云产品使用咨询、问题处理、配置指导等&#xff1b; 云产品相关操作的技术指导&#xff1b; 云相关资源日常…

[Qt]常用控件介绍-多元素控件-QListWidget、QTableWidget、QQTreeWidget

目录 1.多元素控件介绍 2.ListWidget控件 属性 核心方法 核心信号 细节 Demo&#xff1a;编辑日程 3.TableWidget控件 核心方法 QTableWidgetItem核心信号 QTableWidgetItem核心方法 细节 Demo&#xff1a;编辑学生信息 4.TreeWidget控件 核心方法 核心信号…

Windows部署NVM并下载多版本Node.js的方法(含删除原有Node的方法)

本文介绍在Windows电脑中&#xff0c;下载、部署NVM&#xff08;node.js version management&#xff09;环境&#xff0c;并基于其安装不同版本的Node.js的方法。 在之前的文章Windows系统下载、部署Node.js与npm环境的方法&#xff08;https://blog.csdn.net/zhebushibiaoshi…

基于STM32设计的粮食仓库(粮仓)环境监测系统

一、前言 1.1 项目开发背景 随着现代农业的发展和粮食储存规模的扩大&#xff0c;粮仓环境的智能化监控需求日益增长。传统的粮仓管理方式通常依赖人工检测和定期巡查&#xff0c;效率低下且容易出现疏漏&#xff0c;无法及时发现潜在问题&#xff0c;可能导致粮食受潮、霉变…

【Linux】--- 进程的等待与替换

进程的等待与替换 一、进程等待1、进程等待的必要性2、获取子进程status3、进程等待的方法&#xff08;1&#xff09;wait&#xff08;&#xff09;函数&#xff08;2&#xff09;waitpid函数 4、多进程创建以及等待的代码模型5、非阻塞接口 轮询 二、进程替换1、替换原理2、替…

Vue2+OpenLayers添加/删除点、点击事件功能实现(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、安装Element-UI 四、代码实现 4.1、添加一个点 4.2、删除所有点 4.3、根据经纬度删除点 4.4、给点添加点击事件 4.5、完整代码 五、Gitee源码 一、案例截图 可以新增/删除标记点&#xff0c;点击标记点可以获取到当前标…

HTML中如何保留字符串的空白符和换行符号的效果

有个字符串 储值门店{{thing3.DATA}}\n储值卡号{{character_string1.DATA}}\n储值金额{{amount4.DATA}}\n当前余额{{amount5.DATA}}\n储值时间{{time2.DATA}} &#xff0c; HTML中想要保留 \n的换行效果的有下面3种方法&#xff1a; 1、style 中 设置 white-space: pre-lin…

GB44495-2024 汽车整车信息安全技术要求 - V2X部分前置要求

背景 GB 44495-2024《汽车整车信息安全技术要求》中关于V2X&#xff08;车与外界通信&#xff09;的部分&#xff0c;主要关注于通信安全要求&#xff0c;旨在确保车辆在与外部设备进行数据交互时的信息安全。其测试大致可分为消息层&#xff08;数据无异常&#xff09;、应用…

[PAT 甲级] 1179 Chemical Equation (DFS)

​ 题目翻译&#xff08;GPT&#xff09;&#xff1a; 1179 化学方程式 化学方程式是一种用符号和公式表示化学反应的方法&#xff0c;其中反应物在方程式的左侧&#xff0c;生成物在右侧。例如&#xff1a; CH₄ 2O₂ -> CO₂ 2H₂O 表示反应物为甲烷和氧气&#xff…

android分区和root

线刷包内容&#xff1a; 线刷包是一个完整的android镜像&#xff0c;不但包括android、linux和用户数据&#xff0c;还包括recovery等。当然此图中没有recovery,但是我们可以自己刷入一个。 主要分区 system.img 系统分区&#xff0c;包括linux下主要的二进制程序。 boot.img…

每日一题(五):n个正整数排列,求组合后最大数

目录 一、题目 二、题目分析 &#xff08;一&#xff09;明确需求 背景知识&#xff1a;字符串的比较与连接 1.字符串的比较 2.字符串的连接 (二)分析思路 三、将思路转换为程序 四、总结 一、题目 给定n个正整数a1,a2,……,an对这n个数进行排列&#xff0c;求组合后可以得到…

【STM32-学习笔记-3-】TIM定时器

文章目录 TIM定时器Ⅰ、TIM定时器函数Ⅱ、TIM_TimeBaseInitTypeDef结构体参数①、TIM_ClockDivision②、TIM_CounterMode③、TIM_Period④、TIM_Prescaler⑤、TIM_RepetitionCounter Ⅱ、定时器配置Ⅲ、定时器外部中断NVIC配置 TIM定时器 Ⅰ、TIM定时器函数 // 将定时器寄存器…

【Rust自学】12.2. 读取文件

12.2.0. 写在正文之前 第12章要做一个实例的项目——一个命令行程序。这个程序是一个grep(Global Regular Expression Print)&#xff0c;是一个全局正则搜索和输出的工具。它的功能是在指定的文件中搜索出指定的文字。 这个项目分为这么几步&#xff1a; 接收命令行参数读…