C 语言指针、字符串与内存函数

📅 2026/7/19 22:23:20
C 语言指针、字符串与内存函数
一、学习脉络说明本文基于指针专项、字符串库函数、内存操作、堆内存管理系列课程整理覆盖 C 语言中最核心、易错的底层语法全部为标准 C 基础考点适用于期末复习、基础开发巩固。二、指针模块1.指针基础定义普通变量存储数据本身指针变量存储内存地址通过地址间接访问内存数据。取值运算符*对指针解引用获取地址对应存储的数据取地址运算符获取变量在内存中的起始地址。传值与传址传值函数接收变量副本函数内修改副本不会影响外部原变量传址传入变量地址函数通过指针直接操作原始内存可修改外部变量。2. 指针与数组数组名是数组首元素的地址常量指针不可修改arr[i]等价于*(arr i)。字符数组用于存储字符串末尾必须包含\0结束符缺少结束符会造成内存越界输出乱码。指针运算规则指针仅能和整数做加减运算两个同类型、同数组内的指针可相减差值为中间元素个数指针不支持乘除运算。3. 二级指针定义格式类型** pp存储一级指针变量的地址常用于修改一级指针本身、操作字符串数组。4. 指针高频坑点野指针未初始化、指向已释放内存、越界访问的指针直接解引用会程序崩溃空指针NULL值为 0 的指针代表不指向任何有效内存访问空指针程序报错常量指针与指针常量区分const int* p指针指向的值不可修改指针本身可改变指向int* const p指针本身指向固定不可改指向的数据可修改。三、字符串库函数头文件 string.h所有字符串函数均以\0作为操作终止标记仅适用于字符型字符串。1. strcpy 字符串拷贝函数原型char* strcpy(char* dest, const char* src);将源字符串完整拷贝至目标空间自动携带末尾\0风险不限制拷贝长度若目标数组空间不足会发生数组越界。2. strncpy 限制长度拷贝原型char* strncpy(char* dest, const char* src, size_t num);最多拷贝 num 个字符不会主动追加\0使用后需手动补结束符安全性高于 strcpy工程开发优先使用。3. strcat 字符串拼接原型char* strcat(char* dest, const char* src);从目标字符串原有\0位置开始追加源字符串前提目标字符数组剩余空间足够容纳拼接后的全部字符 结束符。4. strcmp 字符串比较原型int strcmp(const char* str1, const char* str2);逐字符按 ASCII 码对比返回规则str1 str2 → 返回正数str1 str2 → 返回负数两字符串完全一致 → 返回 0 禁止直接使用判断字符串相等仅比较地址不比较内容。5. strlen 求字符串有效长度原型size_t strlen(const char* str);统计\0之前的字符个数不计入结束符。四、通用内存操作函数头文件 string.hmem 系列函数直接操作内存字节不识别\0可处理 int、char、结构体等任意数据类型。1. memcpy 内存拷贝原型void* memcpy(void* dest, const void* src, size_t num);从 src 地址拷贝 num 个字节到 dest源内存与目标内存不能重叠重叠场景会出现数据覆盖错误。2. memmove 安全内存拷贝原型void* memmove(void* dest, const void* src, size_t num);兼容内存重叠场景内部开辟临时缓冲区中转数据需要拷贝重叠区间时必须使用 memmove。3. memset 内存批量初始化原型void* memset(void* ptr, int value, size_t num);将 ptr 起始的 num 个字节全部设置为 value常用于数组批量置 0。核心区分考点仅处理字符串用 str 系列拷贝整型、结构体、存在内存重叠时必须使用 mem 系列函数。五、堆内存动态管理函数头文件 stdlib.h栈内存局部变量函数执行结束自动释放空间容量有限 堆内存开发者手动申请、手动释放生命周期可控适合动态数组、链表存储。1. malloc 动态分配内存原型void* malloc(size_t size);申请 size 字节连续堆空间内存内容随机无初始化返回 void * 指针需强制转换对应类型。// 申请存放10个int的堆空间 int* p (int*)malloc(10 * sizeof(int));2. calloc 初始化分配原型void* calloc(size_t num, size_t size);分配 num 个、每个 size 字节的连续空间分配后自动全部初始化为 0。3. realloc 扩容 / 缩容堆空间原型void* realloc(void* ptr, size_t new_size);对已分配的堆内存调整大小若原空间后方无足够连续内存会重新开辟新空间并拷贝旧数据释放原空间扩容失败返回 NULL原内存不会释放需提前保存原指针。4. free 释放堆内存原型void free(void* ptr);释放 malloc/calloc/realloc 申请的堆内存释放后指针仍保留原地址会变为野指针规范写法free(p); p NULL;堆内存两大典型问题内存泄漏申请堆内存后未调用 free 释放程序持续占用内存重复释放、访问已释放内存free 后未将指针置空再次解引用或 free 触发程序崩溃。#include stdio.h #include string.h #include stdlib.h // 指针传址交换数字 void swap(int* a, int* b) { int temp *a; *a *b; *b temp; } int main() { // 指针基础演示 int m 12, n 34; swap(m, n); printf(交换后 m%d, n%d\n, m, n); // 字符串函数演示 char str1[40] C Language Study; char str2[40]; strcpy(str2, str1); printf(拷贝字符串%s\n, str2); printf(字符串长度%zu\n, strlen(str2)); // 通用内存拷贝 int arr1[5] {1,2,3,4,5}; int arr2[5]; memcpy(arr2, arr1, sizeof(arr1)); // 堆内存操作 char* heap_str (char*)malloc(64 * sizeof(char)); strcpy(heap_str, Dynamic memory string); printf(堆内存字符串%s\n, heap_str); free(heap_str); heap_str NULL; return 0; }七、知识点总结学习顺序指针基础 → 指针与数组习题 → 字符串库函数 → 通用内存函数 → 堆动态内存核心分界线str 函数依赖\0终止mem 函数按字节操作无结束符限制内存开发规范堆内存申请与 free 成对出现释放后指针置空字符串操作保证目标数组空间充足杜绝越界访问。