临时笔记
讲一下字符串初始化的格式
讲一下什么是,sizeof,strlen,stract,strcmp,strcpy
这几个函数是C语言字符串操作的“基石”。特别是 sizeof 和 strlen 的区别,是期末考试和面试的必考题。
我们分两部分来讲:
第一部分:字符串初始化的格式
在 C 语言中,字符串本质上是以 \0 结尾的字符数组。常见的初始化方式有以下 4 种:
1. 指定长度的数组(最标准)
C
1 | |
2. 偷懒写法(省略长度)
C
1 | |
3. 逐个字符赋值(最麻烦,容易漏 \0)
C
1 | |
4. 指针形式(只读,坑很大)
C
1 | |
- 注意:这种写法下的字符串是只读的。如果你写
str[0] = 'H';,程序会直接崩溃(段错误)。初学者建议尽量用数组形式(前两种)。
第二部分:5个核心关键词详解
为了讲清楚这几个概念,我们假设有以下代码:
C
1 | |
1. sizeof (它是运算符,不是函数)
- 含义:容器的大小。问的是“你总共占了多少内存?”
- 计算:包括所有用到的和没用到的空间。
- **针对 s[100]**:
sizeof(s)结果是 100。因为你申请了100个格子,哪怕只住了5个人。
2. strlen (String Length)
- 含义:内容的长度。问的是“里面实际住了多少人?”
- 计算:从头开始数,遇到
\0就停止。**注意:不包括\0**。 - **针对 s[100]**:
strlen(s)结果是 5 (h-e-l-l-o)。
一句话区分:
sizeof看房子有多大,strlen看房子里住了几个人。
3. strcpy (String Copy)
功能:字符串复制。把 B 里的内容(连同
\0)覆盖到 A 里面。用法:
strcpy(目标, 源);记忆口诀:“覆盖”。目标原来的内容会被彻底抹掉。
例子:
C
1
2
3
4char dest[20] = "Old Data";
char src[] = "New";
strcpy(dest, src);
// 现在 dest 变成了 "New",后面的 " Data" 被截断看不见了
4. strcat (String Concatenate)
你写的
stract应该是拼写错误,正确是strcat功能:字符串拼接。把 B 接在 A 的屁股后面。
用法:
strcat(目标, 源);原理:它会找到目标字符串的
\0,把源字符串从这里开始填进去,最后再补一个新的\0。例子:
C
1
2
3
4char dest[20] = "Hello ";
char src[] = "World";
strcat(dest, src);
// dest 变成了 "Hello World"
5. strcmp (String Compare)
功能:字符串比较。
重要原则:决不能用
==比较字符串! 因为==比的是两个数组的地址(门牌号),而不是内容。用法:
int result = strcmp(str1, str2);返回值:
0:两个字符串相等。- **
>0**:str1 比 str2 大(按字典序,比如 “b” 大于 “a”)。 - **
<0**:str1 比 str2 小。
例子:
C
1
2
3if (strcmp(password, "123456") == 0) {
printf("密码正确");
}
总结表格
| 关键字 | 全称/含义 | 核心作用 | 备注/坑点 |
|---|---|---|---|
| sizeof | Size Of | 占内存总大小 | 包含 \0,是运算符 |
| strlen | String Length | 有效字符长度 | 不包含 \0,需头文件 <string.h> |
| strcpy | String Copy | 复制 (覆盖) | 目标空间必须足够大 |
| strcat | String Concatenate | 拼接 (追加) | 目标空间必须足够大 |
| strcmp | String Compare | 比较 | 相等返回 0,千万别用 == |
接下来我们可以做个小测试:
如果我定义 char a[] = “OK\0Hi”;
sizeof(a)是多少?strlen(a) 是多少?
(试着想一下,我可以告诉你答案)
sizeof,strlen,stract,strcmp,strcpy上面讲的这些都是啥,都是能直接写在程序中的吗,还有哪些,与我今天学的字符串有关?
这两个问题问到了点子上!我们来给这些工具分个类,你就会发现它们其实非常有条理。
一、 它们都是啥?能直接写吗?
简单来说,它们是你处理字符串时的 “武器库”。但是,使用它们有一个前提条件。
我们可以把它们分成 两类:
第一类:C语言的“亲儿子” —— sizeof
- 身份:它是 C 语言的 关键字/运算符(和
if、int、+、-是一个级别的)。 - 能直接写吗?:能! 随时随地都能用,不需要打任何招呼(不需要引用头文件)。
第二类:外借的“工具箱” —— strlen, strcpy, strcat, strcmp
- 身份:它们是 库函数。C 语言本身不自带这些功能,而是把它们打包放在了一个叫
<string.h>的工具箱里。 - 能直接写吗?:不能直接写!
- 你必须在代码的最开头(第一行)加上一句“借工具”的申请:
#include <string.h>- 如果你忘了加这一行,虽然有些聪明的编译器(如 VS)会猜到你想干嘛并帮你通过,但标准的做法是必须加,否则会报错。
二、 还有哪些常用的字符串函数?
除了你今天学的“四大天王”(拷贝、拼接、比较、测长),在这个 <string.h> 工具箱里,还有几个非常实用,你哪怕现在不用,期末考试或者以后写代码一定会用到的:
1. 安全卫士版:strncpy, strncat, strncmp
你注意到了吗?它们中间多了一个 **n**。
- 作用:为了防止 “撑爆数组”(缓冲区溢出)。
- 区别:
strcpy(dest, src):我不管你有多少,我全拷过去(容易炸)。strncpy(dest, src, n):我只拷贝前 n 个字符。
- 建议:在真正的公司开发中,老板通常禁止用
strcpy,必须用strncpy。
2. 查找小能手:strchr (Find Char)
作用:在一个字符串里查找某个字符第一次出现的位置。
场景:比如在 “2023-12-09” 里找到 “-“ 的位置。
代码:
C
1
2char str[] = "apple";
char *p = strchr(str, 'l'); // p 会指向 'l' 这个位置
3. 搜索侦探:strstr (Find String)
作用:在一个字符串里查找另一个字符串(子串)。
场景:判断 “i am a student” 里面有没有 “student” 这个词。
代码:
C
1
2
3char haystack[] = "i am a student";
char needle[] = "student";
char *result = strstr(haystack, needle); // 找到了就返回地址,没找到返回 NULL
三、 容易混淆的“邻居” (不在 string.h 里)
还有两个你可能会用到的功能,但它们不归 <string.h> 管,别跑错片场了:
1. 字符串转数字:atoi (ASCII to Integer)
头文件:**
<stdlib.h>**作用:把字符串
"123"变成整数123。C
1
int num = atoi("100"); // num 变成了整数 100,可以做加减法了
2. 变大写变小写:toupper, tolower
- 头文件:**
<ctype.h>** - 作用:把字符
'a'变成'A'。- 注意:它们一次只能变一个字符,想变整个字符串得写循环。
总结一张表
| 函数/工具 | 归属地 | 必须要加的头文件 | 作用 |
|---|---|---|---|
| sizeof | 亲儿子 | 无 (直接写) | 测内存大小 |
| strlen | 工具箱 | <string.h> |
测字符长度 |
| strcpy / strncpy | 工具箱 | <string.h> |
复制 |
| strcat / strncat | 工具箱 | <string.h> |
拼接 |
| strcmp / strncmp | 工具箱 | <string.h> |
比较 |
| strstr | 工具箱 | <string.h> |
找子串 |
| atoi | 隔壁老王 | <stdlib.h> |
字符串转数字 |
| toupper | 楼下邻居 | <ctype.h> |
字符变大写 |
你今天学的这几个是核心中的核心,先把它们用熟练,其他的等到需要用的时候再查都来得及!