当前位置: 首页 > news >正文

sizeof与strlen练习

前言

在这里插入图片描述
本篇仅仅是为了更加了解sizeof操作符和strlen函数练习.
对于多条sizeof操作符和strlen函数出现,可能很容易造成头脑不清晰,做题时容易混乱.

目录

  • 前言
  • 一维数组
  • 字符数组
    • 情况1:
    • 情况2
    • 情况3
  • 二维数组

练习之前请牢记下面这段话.这将是头脑清晰地关键.
提示:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

sizeof只关心()里面的类型,并不关心里面放的是什么,这点希望做题目时可以牢记.
strlen()括号里面的是地址,它只会通过访问括号里面的地址,往后一直寻找’\0’,直到’\0’才会停止.

一维数组

#include <stdio.h>
int main()
{int a[] = { 1,2,3,4 };printf("%d\n", sizeof(a));			//1printf("%d\n", sizeof(a + 0));		//2printf("%d\n", sizeof(*a));			//3printf("%d\n", sizeof(a + 1));		//4printf("%d\n", sizeof(a[1]));		//5printf("%d\n", sizeof(&a));			//6printf("%d\n", sizeof(*&a));		//7printf("%d\n", sizeof(&a + 1));		//8printf("%d\n", sizeof(&a[0]));		//9printf("%d\n", sizeof(&a[0] + 1));	//10return 0;
}

在这里插入图片描述
运行结果:

1	->	16
2	->	8
3	->	4
4	->	8
5	->	4
6	->	8
7	->	16
8	->	8
9	->	8
10	->	8

详细分析答案:

1.	16字节:		数组名a单独出现在sizeof()的括号中表示计算整个数组的大小,4*4=16字节
2.	4/8字节: 	a数组名不是单独出现,+0表示首地址表示表示首元素地址,地址的大小4/8字节
3.	4字节:		(*a)解引用得到的是数组首元素数组首元素是1,类型为整形,整形大小是4字节.
4.	4/8字节:	a+1表示数组第二个元素的地址.地址大小4/8字节.
5.	4字节:		a[1]表示数组的第二个元素,元素2的类型是整形,整形的大小是4字节.
6.	4/8字节:	&a表示是整个数组的地址,类型为int(*)[4].但是数组的地址也是地址,地址就是4/8字节.
7.	16字节		*&a表示对&a解引用,得到的是整个数组的地址.也可以理解为*&符号是可以抵消的,即等价于sizeof(a);结果为4*4=16字节
8.	4/8个字节:	&a+1表示指向数组最后一个元素的后面.因为&a的类型是int(*)[4],+1会跳过四个整形.
地址的大小就是4/8个字节.
9.	4/8字节:	&a[0]表示首元素的地址,地址大小为4/8字节.
10. 4/8字节:	(&a[0] + 1表示第二个元素的地址.4/8字节.

在这里插入图片描述

字符数组

情况1:

字符数组:

char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ };

#include <stdio.h>
#include <string.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", sizeof(arr));			//1printf("%d\n", sizeof(arr + 0));		//2printf("%d\n", sizeof(*arr));			//3printf("%d\n", sizeof(arr[1]));			//4printf("%d\n", sizeof(&arr));			//5printf("%d\n", sizeof(&arr + 1));		//6printf("%d\n", sizeof(&arr[0] + 1));	//7printf("%d\n", strlen(arr));			//8printf("%d\n", strlen(arr + 0));		//9printf("%d\n", strlen(*arr));			//10printf("%d\n", strlen(arr[1]));			//11printf("%d\n", strlen(&arr));			//12printf("%d\n", strlen(&arr + 1));		//13printf("%d\n", strlen(&arr[0] + 1));	//14return 0;
}

在这里插入图片描述

答案分析:

1.	6字节:	 	表示整个数组的地址,1*6=6个字节
2. 	4/8字节	:	首元素地址是4/8个字节.
3. 	1字节:		*arr表示首元素是一个字符型,1个字节.
4.	1字节:		arr[1]表示数组的第二个元素,大小为1个字节.
5. 	4/8个字节:	&arr表示整个数组的地址,4/8个字节.
6.	4/8个字节:	&arr+1表示数组最后一个元素的后一个位置的地址.4/8个字节
7. 	4/8个字节:	表示第二个元素的地址.4/8个字节

strlen函数从参数处开始,遇到’\0’才会停止.

8.随机值.: 	由于该数组没有’\0,所以会向后一直找直到碰到'\0',
9.随机值:	arr+0同样表示从数组的第一个元素,从第一个元素往后找,与上面一个道理.
10.报错:	strlen()括号里面是地址,所以会访问地址名为a的地址,a的ASCII码值是’97,访问地址’97,系统会报错
11.报错:	同理,访问数组第二个元素,地址名b的地址,系统报错
12.随机值:	&arr取出的是整个数组的地址,地址还是从数组首地址开始往后找'\0'.
13.随机值:	&arr的类型是char(*)[6],+1会跳过这个数组从数组后面开始找'\0'.
14.随机值:	从数组的第二个元素开始找'\0'.

情况2

字符数组:

char arr[] = “abcdef”;

#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";printf("%d\n", sizeof(arr));			//1printf("%d\n", sizeof(arr + 0));		//2printf("%d\n", sizeof(*arr));			//3printf("%d\n", sizeof(arr[1]));			//4printf("%d\n", sizeof(&arr));			//5printf("%d\n", sizeof(&arr + 1));		//6printf("%d\n", sizeof(&arr[0] + 1));	//7printf("%d\n", strlen(arr));			//8printf("%d\n", strlen(arr + 0));		//9printf("%d\n", strlen(*arr));			//10printf("%d\n", strlen(arr[1]));			//11printf("%d\n", strlen(&arr));			//12printf("%d\n", strlen(&arr + 1));		//13printf("%d\n", strlen(&arr[0] + 1));	//14return 0;
}

答案分析:

1.	7字节:	 	表示整个数组的地址,1*7=7个字节
2. 	4/8字节:	首元素地址是4/8个字节.
3. 	1字节:		*arr表示首元素是,一个字符型,1个字节.
4.	1字节:		arr[1]表示数组的第二个元素,大小为1个字节.
5. 	4/8个字节:	&arr表示整个数组的地址,4/8个字节.
6.	4/8个字节:	&arr+1表示数组最后一个元素的后一个位置的地址4/8个字节
7. 	4/8个字节:	表示第二个元素的地址4/8个字节
8.	6字节: 		从数组首元素开始,直到最后一个元素’\0,6个元素.6*1=6字节.
9.	6字节:		arr+0同样表示从数组的第一个元素,从第一个元素往后找,与上面一个道理.
10.	报错:		strlen()括号里面是地址,所以会访问地址名为a的地址,a的ASCII码值是’97,访问地址’97,系统会报错
11.	报错:		同理,访问数组第二个元素,地址名b的地址,系统报错
12.	6字节:		&arr取出的是整个数组的地址,地址还是从数组首地址开始往后找'\0.
13.	随机值:		&arr的类型是char(*)[6],+1会跳过这个数组,从数组后面开始找'\0.
14.	5字节:		从数组的第二个元素'b'开始往后找'\0'.

情况3

char* p = “abcdef”;

#include <stdio.h>
#include <string.h>
int main()
{char* p = "abcdef";printf("%d\n", sizeof(p));				//1printf("%d\n", sizeof(p + 1));			//2printf("%d\n", sizeof(*p));				//3printf("%d\n", sizeof(p[0]));			//4printf("%d\n", sizeof(&p));				//5printf("%d\n", sizeof(&p + 1));			//6printf("%d\n", sizeof(&p[0] + 1));		//7printf("%d\n", strlen(p));				//8printf("%d\n", strlen(p + 1));			//9printf("%d\n", strlen(*p));				//10printf("%d\n", strlen(p[0]));			//11printf("%d\n", strlen(&p));				//12printf("%d\n", strlen(&p + 1));			//13printf("%d\n", strlen(&p[0] + 1));		//14return 0;
}

答案分析:
在这里插入图片描述

1.	4/8字节:	 p是一个指针变量,这里指向的是常量字符串,首元素’a’,指针大小4/8字节.
2.	4/8字节:	p+1表示指向第二个元素’b’,地址(指针)的大小为4/8字节.
3.	1字节:		*p表示首元素’a’,字符a是char类型,占一个字节.
4.	1字节:		p[0]同样是表示数组首元素,占一个字节.
5.	4/8个字节:	&p表示一级指针变量p的地址,类型为char**的二级指针,指针大小为4/8字节.
6.	4/8个字节:	二级指针&p+1,表示该二级指针的后一个地址,请看图.指针大小4/8字节.
7.	4/8个字节:	表示首元素地址+1,即第二个元素地址,4/8个字节.
8	6字节 		从字符串首元素开始,直到最后一个元素’\0,6个元素.6*1=6字节.
9	5字节		从字符串第二个元素往后,找’\0,’bcdef’共5个元素
10.	报错:		表示从a地址,97’地址往后找’\0,系统报错.
11.	报错:		同理, 也是访问地址名为’97’的地址.系统报错.
12.	随机值	 	&p表示一级指针变量p的地址,从存放指针’p’的地址往后找’\0.
13.	随机值:		&p+1表示从存放指针变量’p’的地址后面一个地址,找’\0.
14	5字节:		从字符串的第二个元素开始找'\0'.

二维数组

//二维数组
#include <stdio.h>
int main()
{int a[3][4] = { 0 };printf("%d\n", sizeof(a));						//1printf("%d\n", sizeof(a[0][0]));				//2printf("%d\n", sizeof(a[0]));					//3printf("%d\n", sizeof(a[0] + 1));				//4printf("%d\n", sizeof(*(a[0] + 1)));			//5printf("%d\n", sizeof(a + 1));					//6printf("%d\n", sizeof(*(a + 1)));				//7printf("%d\n", sizeof(&a[0] + 1));				//8printf("%d\n", sizeof(*(&a[0] + 1)));			//9printf("%d\n", sizeof(*a));						//10printf("%d\n", sizeof(a[3]));					//11return 0;
}

答案:
在这里插入图片描述

1.	48字节		a单独出现在sizeof括号中,表示计算整个数组的地址,数组每个元素是整形,4*3*4=48字节
2.	4字节		a[0][0]计算数组首元素的地址,是一个整形占四个字节.
3.	16字节		a[0]是第一行的数组名,数组名单独放在sizeof,表示第一行的地址,4*4=16字节
4.	4/8字节		a[0]不是单独出现,也没有&(取地址),表示的是第一行第一个元素即a[0][0],后面+1表示第一行第二个元素的地址.
5.	4字节		因为a[0]+1表示第一行第二个元素的地址,则解引用得到的是第一行第二个元素.该元素是整形.
6.	4/8字节		a是数组名,表示二维数组的第一行,a的类型是int(*)[4],那么+1会跳过一行,即表示第二行的地址,地址4/.8字节.
7.	16字节		*(a+1)等价于a[0],第二行的数组名单独放在sizeof里面,表示得到第二行所有元素.
8.	4/8字节		 (&a[0] + 1)),&a[0]表示第一行的地址,+1表示第二行的地址,地址是4/8字节
9.	16字节	 	对第二行解引用,等价于a[1],数组名单独放进sizeof,表示这一行的大小.
10.	16字节		a是表示第一行的地址,*a等价于a[0],类型是int(*)[4].
11. 16字节		a[3]虽然表示第四行数组名,二维数组只有3,但是sizeof并没有访问第四行,而是计算第四行类型大小,int(*)[4].

希望通过这些练习能更加清楚的指针,通过sizeof和strlen函数里面的参数,指针的来回变化会加深对指针的理解.

相关文章:

sizeof与strlen练习

前言 本篇仅仅是为了更加了解sizeof操作符和strlen函数练习. 对于多条sizeof操作符和strlen函数出现,可能很容易造成头脑不清晰,做题时容易混乱. 目录前言一维数组字符数组情况1:情况2情况3二维数组练习之前请牢记下面这段话.这将是头脑清晰地关键. 提示: sizeof(数组名)&#…...

知识图谱的介绍

知识图谱的由来 谷歌在2012年提出了知识图谱的概念&#xff0c;当时目的在于优化搜索引擎的返回结构&#xff0c;为用户提供更精确的结果。 知识图谱的定义 为了理解知识图谱&#xff0c;我们首先要明白信息与知识的概念。首先&#xff0c;信息表示的是外部的客观事实&#…...

【Redis】Redis高级客户端Lettuce详解

文章目录前提Lettuce简介连接Redis定制的连接URI语法基本使用API同步API异步API反应式API发布和订阅事务和批量命令执行Lua脚本执行高可用和分片普通主从模式哨兵模式集群模式动态命令和自定义命令高阶特性配置客户端资源使用连接池几个常见的渐进式删除例子在SpringBoot中使用…...

Qt——自定义界面之QStyle

1. Qt控件结构简介 首先我们要来讲讲GUI控件结构&#xff0c;这里以QComboBox为例&#xff1a; 一个完整的控件由一种或多种GUI元素构成&#xff1a; Complex Control Element。Primitive Element。Control Element。 1.1 Complex Control Element Complex control elements …...

指针和数组面试题(逐题分析,完善你可能遗漏的知识)

人生不是一种享乐&#xff0c;而是一桩十分沉重的工作。 —— 列夫托尔斯泰 前言&#xff1a;之前我们就学习了数组和指针的知识。 数组&#xff1a;数组就是能够存放一组相同类型的元素&#xff0c;数组的大小取决于数组的元素个数和元素类型。 指针&#xff1a;…...

centos7搭建nfs挂载日志目录完整步骤

NFS服务器配置 1.安装NFS服务 首先使用yum安装nfs服务&#xff1a; yum -y install rpcbind nfs-utils 2.创建共享目录 在服务器上创建共享目录&#xff0c;并设置权限。 mkdir /data/share/ chmod 755 -R /data/share/ 3.配置NFS nfs的配置文件是 /etc/exports &…...

三、JavaScript

目录 一、JavaScript和html代码的结合方式 二、javascript和java的区别 1、变量 2、运算 3、数组&#xff08;重点&#xff09; 4、函数 5、重载 6、隐形参数arguments 7、js中的自定义对象 三、js中的事件 四、DOM模型 五、正则表达式 一、JavaScript和html代码的结合方…...

深圳大学计软《面向对象的程序设计》实验11 多继承

A. 在职研究生&#xff08;多重继承&#xff09; 题目描述 1、建立如下的类继承结构&#xff1a; 1)定义一个人员类CPeople&#xff0c;其属性&#xff08;保护类型&#xff09;有&#xff1a;姓名、性别、年龄&#xff1b; 2)从CPeople类派生出学生类CStudent&#xff0c;…...

并发变成实战-原子变量与非阻塞同步机制

文章目录1.锁的劣势2.硬件对并发的支持2.1 比较并交换2.2 非阻塞的计数器3.原子变量类3.1 原子变量是一种“更好的volatile”3.2 性能比较&#xff1a;锁与原子变量4.非阻塞算法4.1 非阻塞的栈4.2 非阻塞的链表4.3 ABA问题非阻塞算法设计和实现上要复杂的多&#xff0c;但在可伸…...

sql数据库常用操作指令

一、操作库-- 创建库create database db1;-- 创建库是否存在&#xff0c;不存在则创建create database if not exists db1;-- 查看所有数据库show databases;-- 查看某个数据库的定义信息 show create database db1; -- 修改数据库字符信息alter database db1 character set ut…...

4-1 定时任务的示例10个

文章目录前言基本命令与格式示例前言 Linux crontab 是用来定期执行程序的命令。当安装完成操作系统之后&#xff0c;默认都已经安装&#xff0c;并启动此任务调度命令。 crond 命令每分钟会定期检查是否有要执行的工作&#xff0c;如果有要执行的工作便会自动执行该工作。 基…...

外贸建站多少钱才能达到预期效果?

外贸建站多少钱才能达到预期效果&#xff1f;这是每个外贸企业都会问的问题。作为一个做外贸建站多年的人&#xff0c;我有一些个人的操盘感想。 首先&#xff0c;我认为外贸建站的投资是非常必要的。 因为在现代社会&#xff0c;网站已经成为外贸企业开展业务的必要工具之一…...

【Java学习笔记】5.Java 基本数据类型

Java 基本数据类型 变量就是申请内存来存储值。也就是说&#xff0c;当创建变量的时候&#xff0c;需要在内存中申请空间。 内存管理系统根据变量的类型为变量分配存储空间&#xff0c;分配的空间只能用来储存该类型数据。 因此&#xff0c;通过定义不同类型的变量&#xf…...

InnoDB 死锁和问题排查

文章目录死锁&#xff08;dead lock&#xff09;示例 1问题排查查看连接的线程查看相关的表查看最近一次的死锁信息查看服务器的锁信息查看正在使用的表如何尽可能地避免死锁死锁&#xff08;dead lock&#xff09; 两个及以上的事务各自持有对方需要的锁&#xff0c;导致双方…...

tensorflow07——使用tf.keras搭建神经网络(Sequential顺序神经网络)——六步法——鸢尾花数据集分类

使用tf.keras搭建顺序神经网络 六步法——鸢尾花数据集分类 01 导入相关包 02 导入数据集&#xff0c;打乱顺序 03 建立Sequential模型 04 编译——确定优化器&#xff0c;损失函数&#xff0c;评测指标&#xff08;用哪一种准确率&#xff09; 05 训练模型——把各项参入填入…...

关于Java连接Hive,Spark等服务的Kerberos工具类封装

关于Java连接Hive&#xff0c;Spark等服务的Kerberos工具类封装 idea连接服务器的hive等相关服务的kerberos认证注意事项 idea 本地配置&#xff0c;连接服务器&#xff1b;进行kerberos认证&#xff0c;连接hive、HDFS、Spark等服务注意事项&#xff1a; 本地idea连接Hadoo…...

大数据框架之Hadoop:MapReduce(五)Yarn资源调度器

Apache YARN (Yet Another Resource Negotiator) 是 hadoop 2.0 引入的集群资源管理系统。用户可以将各种服务框架部署在 YARN 上&#xff0c;由 YARN 进行统一地管理和资源分配。 简言之&#xff0c;Yarn是一个资源调度平台&#xff0c;负责为运算程序提供服务器运算资源&…...

uniapp实现地图点聚合功能

前言 在工作中接到的一个任务&#xff0c;在app端实现如下功能&#xff1a; 地图点聚合地图页面支持tab切换&#xff08;设备、劳务、人员&#xff09;支持人员搜索显示分布 但是uniapp原有的map标签不支持点聚合功能&#xff08;最新的版本支持了点聚合功能&#xff09;&am…...

经典分类模型回顾2—GoogleNet实现图像分类(matlab版)

GoogleNet是深度学习领域的一种经典的卷积神经网络&#xff0c;其在ImageNet图像分类任务上的表现十分优秀。下面是使用Matlab实现GoogleNet的图像分类示例。 1. 数据准备 在开始之前&#xff0c;需要准备一些图像数据用来训练和测试模型&#xff0c;可以从ImageNet等数据集中…...

Java经典面试题——谈谈 final、finally、finalize 有什么不同?

典型回答 final 可以用来修饰类、方法、变量&#xff0c;分别有不同的意义&#xff0c;final 修饰的 class 代表不可以继承扩展&#xff0c; final 的变量是不可以修改的&#xff0c;而 final 的方法也是不可以重写的&#xff08;override&#xff09;。 finally 则是 Java 保…...

Phi-3-mini-128k-instruct与STM32开发:生成嵌入式C代码与调试逻辑

Phi-3-mini-128k-instruct与STM32开发&#xff1a;生成嵌入式C代码与调试逻辑 1. 引言 如果你玩过STM32&#xff0c;尤其是像STM32F103C8T6这种经典的“蓝色药丸”最小系统板&#xff0c;肯定对下面这些场景不陌生&#xff1a;为了点亮一个LED&#xff0c;翻遍数据手册&#…...

WikiJS全文搜索实战:用ElasticSearch+IK分词器提升内容检索效率(Docker版)

WikiJS全文搜索实战&#xff1a;ElasticSearch与IK分词器的深度优化指南 引言&#xff1a;为什么需要专业级全文搜索解决方案&#xff1f; 想象一下&#xff0c;当你面对一个包含数千篇技术文档的Wiki系统时&#xff0c;传统的关键词匹配就像在黑暗房间里寻找一根针。WikiJS自带…...

OpenClaw人人养虾:接入Matrix

Matrix 是一个开放的去中心化通讯协议&#xff08;Decentralized Communication Protocol&#xff09;&#xff0c;任何人都可以搭建自己的 Homeserver&#xff08;家服务器&#xff09;并与全球 Matrix 网络互联。OpenClaw 通过 Matrix Client-Server API 实现接入。 前置要求…...

嵌入式系统调试常见问题与解决方案

嵌入式系统调试中的典型问题分析与解决策略1. 常见调试问题案例分析1.1 程序文件版本错误在嵌入式开发过程中&#xff0c;一个常见的低级错误是使用了错误的程序文件版本。某工程师在调试时发现单片机完全不执行程序&#xff0c;即使是最基本的GPIO控制也无法实现。经过以下排查…...

TIG电弧熔池一体化与MIG电弧熔滴蒸汽一体化

TIG电弧熔池一体化MIG电弧熔滴蒸汽一体化最近在搞焊接数值模拟的朋友估计都被TIG和MIG的热力耦合模型折腾过。这俩工艺看着都是电弧焊&#xff0c;实际在建模时完全不是一个次元的难度。今天咱们就扒一扒TIG熔池和MIG熔滴这对冤家的建模套路。先说TIG电弧熔池一体化建模。核心难…...

【计算机组成原理】1 计算机组成原理学习路线:从晶体管到云架构的知识图谱

1 为什么你需要一张知识图谱 计算机组成原理是计算机科学的核心基石&#xff0c;它研究计算机硬件系统的基本组成原理、逻辑实现及工作机制。对于计算机专业学生或软件开发者而言&#xff0c;理解"代码如何在硬件上运行"不仅是应试需要&#xff0c;更是性能优化、系统…...

别啃书了!用这款70块的Steam游戏《Turing Complete》,手把手带你从逻辑门拼出CPU

从逻辑门到CPU&#xff1a;用《Turing Complete》重构计算机组成原理学习体验 当我在大学第一次翻开《计算机组成原理》教材时&#xff0c;那些密密麻麻的逻辑门符号和抽象的数据通路图让我头皮发麻。直到在Steam上发现标价70元的《Turing Complete》——这款看似简单的电路模拟…...

Oracle数据库架构入门概述

本文分为四个部分简单概述 一、入门概述 二、数据库实例简述 三、数据库物理存储和逻辑存储结构简述 四、网络体系结构概述 入门概述 Oracle 数据库服务器包括一个数据库和至少一个数据库实例 &#xff08;通常是指只有一个实例&#xff09;。 因为实例和数据库关联紧密&#x…...

医疗陪护管理系统:信息化管理在医院的应用

博主介绍&#xff1a; 所有项目都配有从入门到精通的安装教程&#xff0c;可二开&#xff0c;提供核心代码讲解&#xff0c;项目指导。 项目配有对应开发文档、解析等 项目都录了发布和功能操作演示视频&#xff1b; 项目的界面和功能都可以定制&#xff0c;包安装运行&#xf…...

脉冲雷达系统仿真:从理论建模到Matlab代码实现

1. 脉冲雷达系统仿真入门指南 第一次接触雷达系统仿真时&#xff0c;我和大多数初学者一样&#xff0c;面对满屏的数学公式和专业术语完全摸不着头脑。直到把实验室那台老式示波器玩坏了三次之后&#xff0c;我才真正理解脉冲雷达仿真的核心逻辑——它本质上就是在计算机里搭建…...