C语言:字符串以及与内存地址的关系
发布时间:2026/10/8 19:03:40 锦皓数字建站

本次教程我们将学习字符串我们已更改密码的例子为一个项目来学习#includestdio.h#includestring.hintmain(){charpassword[20];charpassword1[20];printf(input your password\n);scanf(%s,password);printf(input your password again\n);scanf(%s,password1);if(strcmp(password,password1)0){printf(Your password has been updated.);}else{printf(The passwords do not match.);}}我们将针对这一串代码进行学习charchara[10]123;// 字符串intb123;// 整数char和int一样可以声明变量 char声明的则是字符串chara[30]caito123;这个声明的是a字符串为“caito123”[10]这里和数组十分相似代表这个字符串有10个位置分别是 0 1 2 3 4 5 6 7 … 28 29 三十个位置a ↓ c a i t o 1 2 3 \0 0 ...... ←────────────────→ 字符串 ←────────────── 30个char ──────────────→“caito123” 有 8 个字符再加 \0 刚好九个这个 \0 指终止符规定字符串到这里结束但明确指定了[30]所以整个数组有 30 个 char 空间。这意味着后面还可以继续放东西还有一种chara[]caito123;这里没有指定数组大小编译器会根据字符串自动计算caito123加终止符总共9个字符char a[]所以实际上相当于char a[9] “caito123”;它没有多余空间什么是字符串字符串和数字有什么区别呢我们从内存的角度探讨一下数字是“数值”字符串是“字符序列”。即使字符串看起来是数字它在内存中的含义也完全不同。例如int a 123;你可以把它理解成a ↓ ┌────────────────────┐ │ 123 │ └────────────────────┘假设 int 是 4 字节那么它占4 Bytes在内存里实际存储是一个代表数值 123 的二进制数字1111011再看char a[] “123”;这完全不同。内存是a ↓ ┌─────┬─────┬─────┬─────┐ │ 1 │ 2 │ 3 │ \0│ └─────┴─────┴─────┴─────┘也就是4 Bytes每一个字符占一个 char。按照 ASCII‘1’ → 49‘2’ → 50‘3’ → 51所以内存实际上类似49 50 51 0#include string.h之前我们学习过像这种#开头的是预处理命令像一个工具说明书今天终于学习别的说明书了重点先掌握这些函数 作用 示例 strlen() 获取字符串长度 strlen(a) strcpy() 复制字符串 strcpy(a, b) strncpy() 复制指定数量字符 strncpy(a, b, 5) strcat() 拼接字符串 strcat(a, b) strncat() 拼接指定数量字符 strncat(a, b, 5) strcmp() 比较两个字符串 strcmp(a, b) strncmp() 比较前几个字符 strncmp(a, b, 5) strchr() 查找某个字符 strchr(str, a) strstr() 查找一个字符串 strstr(str, abc)今天我们先只学strncmp()strcmp() 比较后会返回一个整数。它的规定是strcmp(a,b)返回 0 → 两个字符串完全相同 0 → a 小于 b 0 → a 大于 b可以写成strcmp(a, b) 0strcmp(a, b) 0strcmp(a, b) 0%s %d 观察一下开头的代码可以发现scanf(%s,password);和之前学习的有一点不一样password不应该写成password吗这边我将进行详细的解释先记住一句最核心的话%d、%s 是告诉 scanf“输入的数据是什么类型” 是告诉 scanf“数据应该放到哪里”。1. 先看一个整数int age;scanf(“%d”, age);假设 age 的地址是 1002。内存可以简单理解成 地址 内容 1000 [ ] 1001 [ ] 1002 [ ] 1003 [ ]执行scanf(%d,age);可以理解成%d “我准备输入一个整数”age “请把这个整数放到 age 的地址”假设你输入123那么age的1002内存中最终保存了整数 123。2. 为什么 %d 后面需要 因为age代表的是age 里面存的值而age代表age 的地址例如int age 18;可以理解成age 18内存 ┌────────────┐ │ 18 │ └────────────┘ ↑ 地址1002所以age得到18而age得到1002scanf 需要的是地址因为它要修改你的变量。所以scanf(“%d”, age);正确。而scanf(“%d”, age);错误。3. %s 为什么不需要 现在看你的字符串char password[20];scanf(“%s”, password);这里就很容易产生疑问为什么没有 password因为password是一个数组。数组名在这种表达式中会自动转换成数组第一个元素的地址假设 char password[20]; 内存 password ↓ 地址从1000开始 1000 1001 1002 1003 1004 ... ┌────┬────┬────┬────┬────┬───── │ │ │ │ │ │ └────┴────┴────┴────┴────┴───── ↑ password[0]所以password实际上可以理解成password[0]因此scanf(“%s”, password);意思就是%s “我要输入一个字符串”password ↓ “从这个地址开始把字符串放进去”4. 输入 Caito123 会发生什么char password[20];scanf(“%s”, password);输入Caito123内存变成 地址 内容 1000 C 1001 a 1002 i 1003 t 1004 o 1005 1 1006 2 1007 3 1008 \0 1009 ...注意最后‘\0’这是字符串结束符。看到这里我相信你已经可以自己写出一个重新设置密码的简单程序了这个程序仅仅只是一个最简单的逻辑框架实际应用上还要考虑登录身份验证HTTPS/TLS密码强度登录失败次数限制防暴力破解密码哈希与盐会话/Token数据库安全日志中避免泄露密码
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。