从数组和指针笔试题深度理解 sizeof 和 strlen

一、sizeof 和 strlen 的区别 

a.sizeof

        sizeof 计算变量所占内存内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。sizeof 只关注占用内存空间的大小,不在乎内存中存放什么数据。

b.strlen

        strlen 是C语言库函数,功能是求字符串长度。函数原型如下:

size_t strlen ( const char * str );

        统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。
strlen 函数会一直向后找 \0 字符,直到找到为止,所以可能存在越界查找。

        具体详见:strlen - C++ Reference (cplusplus.com)

strlen(arr1)的值是未定义的,因为数组arr1中没有 '\0' ,出现越界访问,sizeof(arr2)之所以为4,这是因为字符串的隐含条件 '\0' ,故arr2数组有元素 'a' 、'b'、 'c'、 '\n'。

c.sizeof与strlen的区别

二、数组和指针笔试题解析(32位环境)

a.一维数组( int a[ ] = { 1 , 2 , 3 , 4 } )

1、

printf("%d\n",sizeof(a));

数组名在sizeof单独出现,其代表的是整个数组,此计算的是整个数组占内存空间的大小,为 4 * 4 = 16字节。

2、

printf("%d\n", sizeof(a + 0));

数组名不单独在sizeof出现,其代表首元素地址,a + 0 为首元素地址,类型为int* ,指针变量占内存大小为4字节。

3、

printf("%d\n", sizeof(*a));

数组名不单独在sizeof出现,其代表首元素地址,对其解引用,得到数组首元素,类型为int,占内存空间大小为4字节。

4、

printf("%d\n", sizeof(a[1]));

a[1]访问第一个数组元素,其类型为int,占内存空间大小为4字节。

5、

printf("%d\n", sizeof(&a));

数组名不单独在sizeof出现,其代表首元素地址,对其取地址,那仍然还是一个地址,为二级指针,类型为int**,占内层空间大小为4字节。

6、

printf("%d\n", sizeof(*&a));

数组名不单独在sizeof出现,其代表首元素地址,对其取地址又解应用,*&a == a,所以又变成了数组名单独在sizeof出现。

b.字符数组

(char arr[ ] = {'a' , 'b' , 'c' , 'd' , 'e' , 'f' })

1、

printf("%d\n", sizeof(arr));
printf("%d\n", strlen(arr));

数组名单独在sizeof内出现代表首元素地址,计算的是整个数组的大小,为 6 * 1 = 6 字节。arr作为首元素地址,意味着strlen从第一个元素开始向后统计,但arr数组中没有 '\0' ,所以统计结果未定义。

2、

printf("%d\n", sizeof(*arr));
printf("%d\n", strlen(*arr));

arr未单独出现,为数组首元素地址,对其解引用得到首元素,strlen库函数在前文中介绍已知,其参数为字符串地址,这里传参错误。

3、

printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(&arr[0] + 1));

arr[0] 为首元素,对其取地址再 +1 ,那么这就是第二个元素的地址喽,其类型为int*,占内存空间大小为4字节,故sizof计算为4字节,但是strlen库函数又是老问题,无论从第几个元素开始,由于没有 '\n' 结尾,结果都是未定义的。

( char arr[ ] = "abcdef" )

1、

printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));

大多数情况下,数组名都代表首元素地址,除了sizeof数组名或&数组名两个例外,那么这里arr与arr + 0 都代表数组首元素地址,这一次由于字符串末尾隐含 '\0' ,所以可以成功计数,为6。这里的6不是六个字节,而是六个字符元素。

2、

printf("%d\n", sizeof(arr));

数组名单独出现于sizeof,代表整个数组,由于字符串隐含 '\0',所以数组arr实有7个字符元素,占内存空间大小为7 * 1 = 7字节。

3、

printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr[0]));

对数组名取地址,得到的是整个数组的地址,但其值和首元素地址相同,由于没有进形指针运算,那么这里实则还是从数组首元素开始计数,为6字节;对数组首元素取地址得到数组首元素地址从数组首元素开始计数,为6字节。

c.二维数组( int a[3][4] = { 0 } )

1、

printf("%d\n", sizeof(a));

数组名单独出现于sizeof,代表整个数组,计算的是整个数组大小,占空间 3 * 4 * 4 = 48字节。

2、

printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0] + 1));

因为a为二维数组,那么a[0]就代表着第一行首元素的地址,但由于其单独出现于sizeof,计算为第一行元素总大小,为 4 * 4 = 16字节,a[0] + 1并非a[0]单独出现了,就代表第一行首元素大小,那么+1就是第一行第二个元素的地址,但由于其是一个地址,则计算结果为4字节。

3、

printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));

因为a为二维数组,故数组名代表首元素地址,二二维数组首元素地址为第一行元素数组的地址,但是当其 +1 跳过4 * 4 = 16字节后,仍然还是个地址,作为指针变量,其占内存空间大小就为4字节,对其解引用,其效果相当于第二行元素组成元素的数组名,代表整个第二行数组,计算的是第二行数组大小,其大小为4 * 4 = 16字节。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/26012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql学习(八)——多表查询

文章目录 五、多表查询5.1 多表关系5.2 多表查询概述5.3 内连接5.4 外连接5.5 自连接5.6 联合查询5.7子查询5.8 总结 五、多表查询 5.1 多表关系 概述:项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,…

Deepin安装PostGresql

最近要把开发环境完全从Windows移到Deepin上,本次介绍在Deepin借助apt-get安装和配置数据库。同时可以用Dbever提供图形化管理工具。 安装PostGreSQL数据库和创建数据库 #安装postgresql zhanglianzhuzhanglianzhu-PC:/$ sudo apt-get install postgresql-16 正在…

STM32CubeIDE使用过程记录

最近在做一款机器人的开发,使用到了STM32CubeIDE,这里记录一些使用技巧方便后续查阅。 STM32CubeIDE使用过程记录 快捷键开启代码自动补全功能看门狗设置CRC设置IO口取反定时器设置 及 定时器中断外部中断GPIO配置STC15单片机GPIO模式配置片内闪存&#…

完美落地的自动化测试框架(pytest):智能生成?业务依赖?动态替换?报告构建?你来,这儿有!

前言 随着软件测试行业的快速发展,去测试化、全员测开化的趋势,技术测试已成为确保软件质量不可或缺的一环。 但对于许多没有代码基础或缺乏系统性自动化知识的测试人员来说,如何入手并实现高质量的自动化测试成为了一个挑战。 为此&#xff…

C语言 图形化界面方式连接MySQL【C/C++】【图形化界面组件分享】

博客主页:花果山~程序猿-CSDN博客 文章分栏:MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一.配置开发环境 二…

基于Java-SpringBoot-VUE-MySQL的企业财务报销系统

基于Java-SpringBoot-VUE-MySQL的企业财务报销系统 登陆界面 联系作者 如需本项目源代码,可扫码或者VX:bob1638 联系作者。 主页-02 系统功能持续更新中。。。 介绍 本系统是采用现代信息技术手段,采用JAVA开发语言,VUE语言,HTML语…

python导入非当前目录(如:父目录)下的内容

在开发python项目时,通常会划分不同的目录,甚至不同层级的目录,这时如果直接导入不在当前目录下的内容时,会报如下的错误:ModuleNotFoundError: No module named miniai其实这里跟操作系统的环境变量很类似的&#xff…

WMS仓储管理系统高效驱动制造企业物料管理

在现代制造业的快速发展中,仓储管理作为供应链的核心环节,其效率直接影响到企业的生产力和市场竞争力。随着科技的进步,实施WMS仓储管理系统逐渐成为推动仓储管理向智能化转型的关键力量。本文将深入探讨WMS仓储管理系统如何以创新的方式驱动…

使用 C# 学习面向对象编程:第 1 部分

介绍 C# 完全基于面向对象编程 (OOP)。首先,类是一组相似的方法和变量。在大多数情况下,类包含变量、方法等的定义。当您创建此类的实例时,它被称为对象。在此对象上,您可以使用定义的方法和变量。 步骤1. 创建名为“LearnClass…

【深度学习】NLP,Transformer讲解,代码实战

文章目录 1. 前言2. Transformer结构训练过程1. 输入嵌入和位置编码2. 编码器层2.1 单头的注意力机制(便于理解)2.2 多头的注意力机制(Transformer真实使用的)2.3 残差连接和层归一化2.4 前馈神经网络(FFN)2.5 残差连接和层归一化2.6 总结 3. 解码器层 推…

Oracle数据库连接并访问Microsoft SQL Server数据库

Oracle数据库连接并访问Microsoft SQL Server数据库 说明:  1.实际开发中,Oracle数据库与SQLServer数据库之间可能需要相互进行访问,方便业务数据抽取,编写视图及表等操作。  2.SQLServer访问Oracle数据库配置相对较为简单&…

MySQL高性能(SQL性能分析)

MySQL性能系列 SQL性能分析 前言1.SQL执行评率2. 慢查询日志3. profile详情4. Explain执行计划4.1. Explain — id4.2. Explain — type4.3. Explain — table4.4. Explain — key 前言 本篇文章采用的MySQL版本是8代,同时自己使用的是Linux mysql8,本篇…

msfconsole利用Windows server2008cve-2019-0708漏洞入侵

一、环境搭建 Windows系列cve-2019-0708漏洞存在于Windows系统的Remote Desktop Services(远程桌面服务)(端口3389)中,未经身份验证的攻击者可以通过发送特殊构造的数据包触发漏洞,可能导致远程无需用户验…

数据结构与算法笔记:基础篇 - 红黑树(上):为什么工程中都用红黑树这种二叉树?

概述 上两篇文章,我们依次讲解了树、二叉树、二叉查找树。二叉查找树是最常用的一种二叉树,它支持快速插入、删除、查找操作,各个操作的时间复杂度跟树的高度成正比,理想情况下,时间复杂度是 O ( l o g n ) O(logn) …

互联网应用主流框架整合之SpringMVC初始化及各组件工作原理

Spring MVC的初始化和流程 MVC理念的发展 SpringMVC是Spring提供给Web应用领域的框架设计,MVC分别是Model-View-Controller的缩写,它是一个设计理念,不仅仅存在于Java中,各类语言及开发均可用,其运转流程和各组件的应…

双列集合 HashMap以及TreeMap底层原理

双列集合 特点: 双列集合一次需要存一对数据,分别为键和值 键不能重复,值可以重复 键和值是一一对应的,每个键只能找到自己对应的值 键和值这个整体在Java中叫做“Entry对象” Map的常见API Map是双列集合的顶层接口,…

基于SpringBoot二手图书管理系统

摘 要 本毕业论文设计并实现了一款基于 Spring Boot 的二手图书管理系统。该系统旨在解决传统图书管理系统存在的一系列问题,如用户体验不佳、功能单一等。首先,论文详细分析了当前二手图书市场的需求和存在的问题,明确了设计该系统的必要性…

你还不知道无线PLC?

随着技术的不断发展,工业控制系统也在经历着革新。无线PLC(Programmable Logic Controller,可编程逻辑控制器)是一种结合了无线通讯技术和传统PLC系统的创新型技术。它为工业自动化提供了一种更灵活、更便捷的解决方案&#xff0c…

简单聊聊大数据解决方案

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

IO流(转换流)

InputStreamReader(字符输入转换流 ) 解决不同编码时,字符流读取文本内容乱码的问题 public static void main(String[] args) {try (//1.得到文件的原始字节流(GBK的字节流形式)FileInputStream is new FileInputStream("src/666.tx…