IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言sizeof()与strlen()如何作用于指针及char数组,及%s格式化输入带来的影响 -> 正文阅读

[C++知识库]C语言sizeof()与strlen()如何作用于指针及char数组,及%s格式化输入带来的影响

1.实验代码

#include <stdlib.h>
#include <stdio.h>
#include <cstring>

int main() {
	printf("-----------test1--------------\n");
	char *p1 = "qwer";
	printf("程序中直接给指针赋值:*p1=\"qwer\"\n");
	printf("strlen(p1)==%d\tsizeof(p1)==%d\n\n", strlen(p1), sizeof(p1));

	printf("-----------test2--------------\n");
	char *p2 = (char *)malloc(sizeof(char) * 6);
	printf("已申请6个char型地址,请手动赋值:");
	scanf("%s", p2);
	printf("strlen(p2)==%d\tsizeof(p2)==%d\n", strlen(p2), sizeof(p2));
	char *p3 = (char *)malloc(sizeof(char) * 6);
	printf("已申请6个char型地址,请手动赋值:");
	scanf("%s", p3);
	printf("strlen(p3)==%d\tsizeof(p3)==%d\n", strlen(p3), sizeof(p3));
	char *p4 = (char *)malloc(sizeof(char) * 6);
	printf("已申请6个char型地址,请手动赋值:");
	scanf("%s", p4);
	printf("strlen(p4)==%d\tsizeof(p4)==%d\n\n", strlen(p4), sizeof(p4));

	printf("-----------test3--------------\n");
	char s1[] = "qwer";
	printf("程序中直接给数组赋值:s1[]=\"qwer\"\n");
	printf("strlen(s1)==%d\tsizeof(s1)==%d\n\n", strlen(s1), sizeof(s1));

	printf("-----------test4--------------\n");
//	char s2[4] = "qwer"; 测试请解开注释
	printf("程序中直接给数组赋值:s2[4]=\"qwer\"会报错!\n");
	printf("错误信息为\"[错误] 初始化-string 对于 array of chars is too long\"\n\n");

	printf("-----------test5--------------\n");
	char s3[5] = "qwer";
	printf("程序中直接给数组赋值:s3[5]=\"qwer\"\n");
	printf("strlen(s3)==%d\tsizeof(s3)==%d\n\n", strlen(s3), sizeof(s3));

	printf("-----------test6--------------\n");
	char s4[6];
	printf("已初始化s4[6],请手动赋值:");
	scanf("%s", s4);
	printf("strlen(s4)==%d\tsizeof(s4)==%d\n\n", strlen(s4), sizeof(s4));
	char s5[6];
	printf("已初始化s5[6],请手动赋值:");
	scanf("%s", s5);
	printf("strlen(s5)==%d\tsizeof(s5)==%d\n\n", strlen(s5), sizeof(s5));
	char s6[6];
	printf("已初始化s6[6],请手动赋值:");
	scanf("%s", s6);
	printf("strlen(s6)==%d\tsizeof(s6)==%d\n\n", strlen(s6), sizeof(s6));

	return 0;
}

2.代码运行演示

-----------test1--------------
程序中直接给指针赋值:*p1="qwer"
strlen(p1)==4   sizeof(p1)==8

-----------test2--------------
已申请6char型地址,请手动赋值:qwer
strlen(p2)==4   sizeof(p2)==8
已申请6char型地址,请手动赋值:qwerty
strlen(p3)==6   sizeof(p3)==8
已申请6char型地址,请手动赋值:qwertyu
strlen(p4)==7   sizeof(p4)==8

-----------test3--------------
程序中直接给数组赋值:s1[]="qwer"
strlen(s1)==4   sizeof(s1)==5

-----------test4--------------
程序中直接给数组赋值:s2[4]="qwer"会报错!
错误信息为"[错误] 初始化-string 对于 array of chars is too long"

-----------test5--------------
程序中直接给数组赋值:s3[5]="qwer"
strlen(s3)==4   sizeof(s3)==5

-----------test6--------------
已初始化s4[6],请手动赋值:qwer
strlen(s4)==4   sizeof(s4)==6

已初始化s5[6],请手动赋值:qwerty
strlen(s5)==6   sizeof(s5)==6

已初始化s6[6],请手动赋值:qwertyu
strlen(s6)==7   sizeof(s6)==6

--------------------------------
Process exited after 17.79 seconds with return value 0
请按任意键继续. . .

3.结论

  1. strlen函数会返回给的首地址到字符串结束符’\0’中间的所有字符数量。
  2. sizeof函数,如果给的参数是指针,那么返回4或8(取决于指针类型在该台电脑中占的字节数),如果给的参数是数组,那么返回数组的长度。
  3. %s:因为内存现实存在,程序会将输入的字符全部读入,不被指针分配空间与数组长度限制。因此建议输入时不要越界。
  4. 字符串若直接赋给指针(没有分配空间)或者数组(没有说明长度),那么程序会在后面自动补’\0’

4.演示验证说明

  1. test1字符串直接赋值给指针,程序会在内存中申请一段字符串长度+1的空间(+1是为了在后面补’\0’),然后将这段空间的首地址赋值给指针。因此strlen得到4,至于sizeof因为我的电脑是64位所以返回8。

  2. test2预先申请了6个char空间:

    1. 在赋值时只给4个字符,那么后面两个字符自动补’\0’,因此strlen=4,sizeof因为是指针所以返回8。

    2. 在赋值时通过%s格式化输入突破了输入限制,给到了6个字符和7个字符,实际上这不符合规范,虽然没有报错但是越界了。
      这里因为此程序所用到的内存小,所以很幸运我们用到的内存后面紧接的内存系统默认为\0,所以strlen分别得到6与7。
      如果所用到的内存后面紧跟着的内存也被程序使用了,那么这时strlen得到的就不是6和7了。sizeof因为是指针所以返回8。

      举个例子:

      1.申请六个内存空间,且这六个后的内存空间也没有被使用:_ _ _ _ _ _ \0 \0 \0 …

      输入qwer四个字符:q w e r \0 \0 \0 \0 \0 …,strlen得到4,没有问题。

      输入qwerty六个字符:q w e r t y \0 \0 \0 …,strlen得到6,很幸运没有问题。

      1.申请六个内存空间,且这六个后的内存空间被使用:_ _ _ _ _ _ a b \0 …

      输入qwer四个字符:q w e r \0 \0 a b \0 …,strlen得到4,没有问题。

      输入qwerty六个字符:q w e r t y a b \0 …,出问题了,strlen得到的结果为8!

  3. test3将字符串直接赋值给数组(没有指定长度),与test1一样,程序申请一段字符串长度+1的空间,然后将首字母赋值给数组,因此输入qwer,得到strlen为4,又因为是数组,sizeof返回数组具体的长度,为5。

  4. test4中体现,如果数组指定长度,并且你想给数组赋值,那么赋值的字符串长度一定要小于数组长度,至少留出一个给\0的空间,否则会报错。

  5. test5比test4多预留了一个\0的空间,因此可以运行,运行结果strlen=4,siezof=5。

  6. test6的情况与test3一样,使用%s格式化输入突破了数组长度的限制,strlen返回的情况与test3一致,而sizeof因为是数组,因此返回数组的长度。

5.总结

  1. 可以直接将字符串赋值给没有分配空间的指针或者没有指定长度的数组。
  2. 若指针已分配空间或者数组长度指定,那么填写的字符串应该预留一个位置。相应的,如果已有字符串数组要有指针或者数组保存,那么申请的空间应该多一个。
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:26:01  更:2022-05-18 17:28:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/14 3:40:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码