嵌入式开发—C语言函数复习总结
- 无终止符检查:与 strcpy 不同,memcpy 严格按 n 字节拷贝,不因 \0 停止。不处理重叠内存:若 src 和 dest 内存重叠,行为未定义,应改用 memmove。,用于将字符串按指定的分隔符拆分成多个子字符串(称为 token)。,其名称源自 ASCII to floating point 的缩写。,用于按字典顺序比较两个字符串的前 n 个
memset函数
memset 是 C/C++ 标准库中的一个高效内存操作函数,用于将指定内存区域的每个字节设置为特定值。
- 函数原型与参数
void *memset(void *s, int c, size_t n);
参数:
s:目标内存指针(需可写)。
c:填充值(仅低8位有效,范围0~255)。
n:填充的字节数。
返回值:返回指针 s,便于链式调用。
- 核心功能
- 按字节填充:将 s 指向的内存前 n 字节设为 c 的低8位(unsigned char 类型)。
- 常见用途:
- 初始化内存(如清零数组、结构体)。
- 清空敏感数据(如密码缓冲区)。
- 快速填充字符数组(如字符串初始化)。
- 使用示例
- 清零整型数组:
int arr[10];
memset(arr, 0, sizeof(arr)); // 每个字节设为0,整型结果为0
- 填充字符数组:
char str[100];
memset(str, '*', sizeof(str)); // 每个字节设为'*'
- 初始化结构体:
struct Student { char name[20]; int age; };
struct Student s;
memset(&s, 0, sizeof(s)); // 所有成员清零
memcpy函数
memcpy 是 C/C++ 标准库中的内存拷贝函数,用于将源内存区域的数据复制到目标内存区域。以下是其核心要点:
1. 函数原型
void *memcpy(void *dest, const void *src, size_t n);
参数:
dest:目标内存指针(需可写)。
src:源内存指针(需可读)。
n:要复制的字节数。
返回值:返回 dest 指针,便于链式调用。
2. 功能与特性
-
逐字节复制:按字节拷贝数据,不关心数据类型(如整型、结构体、字符串等)。
-
不处理重叠内存:若 src 和 dest 内存重叠,行为未定义,应改用 memmove。
- 无终止符检查:与 strcpy 不同,memcpy 严格按 n 字节拷贝,不因 \0 停止。
3. 使用示例 -
复制字符串
#include <string.h>
int main() {
char src[] = "Hello";
char dest[10];
memcpy(dest, src, strlen(src) + 1); // 包含 '\0'
printf("%s", dest); // 输出 "Hello"
return 0;
}
- 复制结构体
struct Person { char name[20]; int age; };
struct Person p1 = {"Alice", 25};
struct Person p2;
memcpy(&p2, &p1, sizeof(struct Person)); // 深拷贝
- 与 strcpy 的区别
| 特性 | memcpy | strcpy |
|---|---|---|
| 复制内容 | 任意数据(字节级) | 仅字符串(以 \0 结尾 |
| 长度控制 | 需显式指定n | 自动到 \0 结束 |
| 安全性 | 可能溢出 | 更易溢出(无长度检查) |
strncpy函数
strncpy 是 C 标准库中用于安全复制字符串的函数,定义在 <string.h> 头文件中。
1. 函数原型
char *strncpy(char *dest, const char *src, size_t n);
参数:
dest:目标字符数组,用于存储复制结果。
src:源字符串,需复制的数据来源。
n:最多复制的字符数(包括 \0)。
返回值:返回 dest 的指针。
2. 功能特性
-
复制规则:
- 若 src 的前 n 个字符不含 \0,则 dest 不会自动添加 \0,需手动补全。
- 若 src 长度小于 n,剩余空间用 \0填充。
- 若 n < src 长度,仅复制前 n 个字符(不包含 \0)。
-
安全性:
相比 strcpy,strncpy 通过限制复制长度避免缓冲区溢出,但需手动处理 \0。
3. 使用示例
- 基础用法
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[20];
strncpy(dest, src, 5); // 复制前5个字符
dest[5] = '\0'; // 手动添加终止符
printf("%s\n", dest); // 输出 "Hello"
return 0;
}
- 安全复制(防止溢出)
void safe_strncpy(char *dest, const char *src, size_t dest_size) {
strncpy(dest, src, dest_size - 1);
dest[dest_size - 1] = '\0'; // 强制终止
}
4. 注意事项
- 内存重叠:strncpy 不处理重叠内存,需用 memmove 替代。
- 性能:频繁填充 \0可能影响效率,适合固定长度场景(如结构体字段)。
- 替代方案:现代代码推荐使用 snprintf 或平台专用函数(如
strlcpy)。
5. 与 strcpy 对比
| 特性 | strncpy | strcpy |
|---|---|---|
| 安全性 | 限制长度,避免溢出 | 无长度检查,高风险 |
| 终止符处理 | 需手动添加 \0 | 自动添加 \0 |
| 适用场景 | 固定长度缓冲区、结构体 | 已知安全长度的快速复制 |
strncmp函数
strncmp 是 C/C++ 中的字符串比较函数,用于按字典顺序比较两个字符串的前 n 个字符。以下是核心要点:
1. 函数原型(C/C++)
#include <string.h>
int strncmp(const char *str1, const char *str2, size_t n);
参数:
str1, str2:待比较的字符串(C 中以 \0 结尾)。
n:比较的最大字符数。
返回值:
0:前 n 个字符完全相同。
<0:str1 的前 n 个字符小于 str2。
>0:str1 的前 n 个字符大于 str2。
2. 功能特性
- 区分大小写:比较基于 ASCII 码值(如 ‘A’ < ‘a’)。
- 安全限制:仅比较前 n 个字符,避免越界风险(与strcmp 不同,后者比较到 \0 结束)。
- 部分匹配:适用于前缀检查(如验证协议头 “HTTP/1.1” 的前 4 字符是否为
“HTTP”)。
3. 示例代码(C)
#include <stdio.h>
#include <string.h>
int main() {
const char *s1 = "Hello";
const char *s2 = "Hexagon";
int result = strncmp(s1, s2, 3); // 比较前3字符 "Hel" vs "Hex"
if (result == 0) printf("Equal\n");
else if (result < 0) printf("s1 < s2\n"); // 输出此结果('l' < 'x')
else printf("s1 > s2\n");
return 0;
}
4. 与 strcmp 的区别
| 特性 | strncmp | strcmp |
|---|---|---|
| 比较范围 | 仅前 n 个字符 | 整个字符串(直到 \0) |
| 安全性 | 更安全(避免溢出) | 需确保字符串以 \0 结尾 |
| 用途 | 部分匹配、前缀检查 | 完整字符串比较 |
- 典型应用场景
- 协议解析:检查消息头(如 strncmp(buf, “GET”, 3))。
- 输入验证:匹配固定前缀(如文件名扩展.txt)。
- 排序辅助:按前缀分组字符串。
strchr函数
strchr 是 C/C++ 中的字符串查找函数,用于在字符串中搜索指定字符的首次出现位置。
- 函数原型
#include <string.h>
char *strchr(const char *str, int c);
参数:
str:待搜索的字符串(以 \0 结尾)。
c:要查找的字符(以 int 形式传递,实际按 ASCII 码处理)。
返回值:
成功:返回指向字符 c 首次出现的指针。
失败:返回 NULL(未找到字符)。
- 示例代码
#include <stdio.h>
#include <string.h>
int main() {
const char *s = "Hello, World!";
char *ptr = strchr(s, 'W');
if (ptr)
printf("Found: %s\n", ptr); // 输出 "World!"
else
printf("Not found\n");
return 0;
}
- 特性
- 区分大小写:‘a’ 和 ‘A’ 视为不同字符。
- 搜索范围:包括字符串的终止符 \0(可查找 \0 的位置)。
- 效率:时间复杂度为 O(n),需遍历字符串直到找到匹配或结束
atof函数
atof 是 C/C++ 标准库中用于将字符串转换为双精度浮点数(double)的函数,其名称源自 ASCII to floating point 的缩写。
1. 函数原型与头文件
#include <stdlib.h>
double atof(const char *str);
参数:str 为待转换的字符串(如 "123.45" 或 "-1.23e-4")。
返回值:成功时返回对应的 double 值,失败或无效输入时返回 0.0。
2. 功能特性
- 解析规则:
- 跳过字符串开头的空白字符(空格、制表符等)。
- 识别正负号(+/-)、小数点(.)及科学计数法(e/E)。
- 遇到非法字符(如字母)时停止转换,返回已解析部分。
- 示例:
printf("%f\n", atof("3.14")); // 输出 3.140000
printf("%f\n", atof(" -2.5e3")); // 输出 -2500.000000
3. 注意事项
- 安全性问题:
不检查输入合法性(如 NULL 指针或非数字字符串),可能引发未定义行为。
推荐替代:使用更安全的 strtod 函数,支持错误检测:
char *endptr;
double num = strtod(str, &endptr);
if (str == endptr) printf("转换失败\n");
- 精度与兼容性:
返回 double 类型,若需 float 需显式转换(如 (float)atof(str))。
跨平台时需注意字节序(大端/小端)问题。
4. 相关函数对比
| 函数 | 功能 | 返回值类型 |
|---|---|---|
| atoi | 字符串 → 整数 | int |
| atol | 字符串 → 长整数 | long |
| atoll | 字符串 → 长长整数 | long long |
5. 典型应用场景
- 解析配置文件中的浮点参数。
- 处理命令行输入的数值。
- 读取文本文件中的科学计数法数据。
6. 示例代码(C语言)
#include <stdio.h>
#include <stdlib.h>
int main() {
const char *str = " -12.34E-2";
double num = atof(str);
printf("转换结果: %.6f\n", num); // 输出 -0.123400
return 0;
}
strtok 函数
strtok 是C标准库中的字符串分割函数,用于将字符串按指定的分隔符拆分成多个子字符串(称为 token)。其原型为:
char *strtok(char *str, const char *delim);
- str:首次调用时传入待分割的字符串;后续调用需传入 NULL,表示继续处理同一字符串。
- delim:分隔符集合(如空格、逗号等),函数会根据其中任意字符分割字符串。
2. token = strtok(NULL, " ") 的含义
- 首次调用:需传入原始字符串指针,例如:
token = strtok(original_str, " "); // 返回第一个token(如"Hello")
- 后续调用:传入 NULL,表示从上一次分割结束的位置继续查找下一个token:
token = strtok(NULL, " "); // 返回下一个token(如"world")
- 关键点:NULL 参数告知函数继续处理剩余字符串,直到所有token被提取完毕(返回 NULL)。
- 示例代码
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello world this is C";
char *token = strtok(str, " "); // 首次调用
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, " "); // 后续调用
}
return 0;
}
- 输出:
Hello
world
this
is
C
更多推荐
所有评论(0)