memset函数

memset 是 C/C++ 标准库中的一个高效内存操作函数,用于将指定内存区域的每个字节设置为特定值

  1. ​​函数原型与参数​​
void *memset(void *s, int c, size_t n);
​​参数​​:
s:目标内存指针(需可写)。
c:填充值(仅低8位有效,范围0~255)。
n:填充的字节数。
​​返回值​​:返回指针 s,便于链式调用。
  1. ​​核心功能​​
  • ​​按字节填充​​:将 s 指向的内存前 n 字节设为 c 的低8位(unsigned char 类型)。
  • ​​常见用途​​:
    • 初始化内存(如清零数组、结构体)。
    • 清空敏感数据(如密码缓冲区)。
    • 快速填充字符数组(如字符串初始化)。
  1. ​​使用示例​​
  • ​​清零整型数组​​:
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)); // 深拷贝
  1. 与 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++ 中的字符串查找函数,用于​​在字符串中搜索指定字符的首次出现位置​​。

  1. ​​函数原型​​
#include <string.h>
char *strchr(const char *str, int c);
​​参数​​:
str:待搜索的字符串(以 \0 结尾)。
c:要查找的字符(以 int 形式传递,实际按 ASCII 码处理)。
​​返回值​​:
​​成功​​:返回指向字符 c 首次出现的指针。
​​失败​​:返回 NULL(未找到字符)。
  1. 示例代码​​
#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;
}
  1. 特性​​
  • ​​区分大小写​​:‘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)。
  1. 示例代码​​
#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
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐