字符数组无法直接插入,需手动右移元素并确保空间充足;std::string::insert()更安全但仍有O(n)开销,频繁中部插入应选std::deque。

字符数组不能直接“插入”,必须手动移动后续元素
字符数组是固定长度的连续内存块,char arr[10] 定义后,容量就锁死了。C++ 没有类似 Python list.insert() 的内置插入机制——所谓“在索引 i 插入字符”,本质是:把 i 及之后的所有有效字符整体右移一位,再把新字符填到 i 位置。
关键前提:目标数组必须留有至少一个空余位置(即当前长度 '\0',导致字符串逻辑损坏。
- 先检查
i是否合法:i >= 0 && i (注意:允许插在末尾,即 <code>i == current_length) - 确认剩余空间足够:
current_length + 1 - 从末尾开始倒序移动,避免覆盖:
for (int j = current_length; j > i; --j) arr[j] = arr[j-1]; - 赋值:
arr[i] = 'x'; - 更新长度并补
'\0':arr[current_length + 1] = '\0';
用 std::string 更安全,但要注意底层仍是复制
如果原意是操作字符串逻辑而非裸数组,std::string 的 insert() 成员函数最直接:s.insert(i, 1, 'x') 或 s.insert(i, "x")。它自动处理内存扩容、移动和终止符。
但要注意:即使使用 std::string,insert() 在中间位置仍需 O(n) 时间移动后续字符;频繁在头部/中部插入时性能差,此时应考虑 std::deque<char></char> 或先拼接再构造。
立即学习“C++免费学习笔记(深入)”;
-
s.insert(2, 1, 'Z')→ 在索引 2 处插入单个字符'Z' -
s.insert(s.begin() + 2, 'Z')效果相同,但迭代器版本更通用 - 若
i超出[0, s.length()],会抛std::out_of_range - 底层可能触发重新分配,原有指针/迭代器失效
常见错误:越界、漏移、忽略 '\0'
手写数组插入时,这三类错误几乎必现:
- 用正向循环移动:
for (int j = i; j → <code>arr[i]被立即覆盖,后续全错 - 没检查空间:
arr已满(len == sizeof(arr)-1),再插就写到arr[sizeof(arr)],UB - 移动后忘了写
'\0':arr[len+1]是脏数据,printf("%s", arr)可能打印乱码或崩溃 - 索引
i误用为strlen(arr)以外的值却未验证——比如i = -1或i = 100
真要原地操作数组?封装成函数并传入尺寸
裸数组操作极易出错,务必把尺寸和当前长度作为参数显式传递,杜绝 magic number。
bool insert_char_at(char arr[], size_t max_size, size_t current_len, size_t i, char c) {
if (i > current_len || current_len + 1 >= max_size) return false;
for (size_t j = current_len; j > i; --j) {
arr[j] = arr[j-1];
}
arr[i] = c;
arr[current_len + 1] = '\0';
return true;
}
// 调用:insert_char_at(buf, sizeof(buf), strlen(buf), 3, 'X');
注意:sizeof(buf) 只在数组定义作用域内有效;若传入函数参数(退化为指针),必须额外传 max_size,否则无法判断边界。


















