一维数组易混淆的点,各种数组名+-的各种坑,sizeof与strlen求的数值的坑

2024 - 10 - 05 - 笔记 - 22
作者(Author):郑龙浩 / 仟濹(网名)

一维数组易混淆的点,各种数组名±的含义,各种坑

1) 一维数组【int】int arr[] = {1, 2, 3, 4}

int arr[] = {1, 2, 3, 4};//在大多数情况下,arr表示的是首元素地址,但是在sizeof里面代表的是整个数组,所以打印的是整个数组的值大小,一个元素为4字节,所以4个元素的大小为4 * 4 == 16字节
printf("%d\n", sizeof(arr));//16 byte//虽然说arr + 0 与 arr没有什么区别,但实际上arr + 0就不能表示整个数组了,而是表示的首元素的地址,arr + 0相当于 &arr[0] + 0 == &arr[0] == arr
printf("%d\n", sizeof(arr + 0));//4 byte / 8 byte(32位4字节,64位8字节)//大部分情况下,只要sizeof中不是只有单独的arr,那么arr就是首元素地址,在这里arr为首元素地址,解引用就是首元素的值,即arr[0]
printf("%d\n", sizeof(*arr));//1 byte//同上,arr为首元素地址,首元素地址加1为第二个元素的地址,只要是地址,就是 4 / 8 (32位 / 64位)
printf("%d\n", sizeof(arr + 1));//4 byte / 8 byte//arr[1]为第二个元素的值,而这个元素的值为int型,int型的数据就是4个字节
printf("%d\n", sizeof(arr[ 1 ]));//4 byte//这个稍微复杂一点
//1.&arr表示的是整个数组的地址
//2.还有一种解释相对复杂,&arr拿到的是整个数组的地址,那么类型就是int(*)[4],这是一种数组指针,但是指针所占的大小依然是固定的
//只要是地址,就是4 byte Or 8 byte
printf("%d\n", sizeof(&arr));//4 byte / 8 byte (32位 / 64位)//这个也稍微复杂一点
//1.&arr表示的是整个数组的地址, 然后再解引用,就是表示的整个数组.可以理解为*&相互抵消了
//2.还有一种解释相对复杂,&arr拿到的是整个数组的地址,那么类型就是int(*)[4],这是一种数组指针,对数组指针解引用,得出来的就是【数组】
printf("%d\n", sizeof(*&arr));//16 byte//同上,地址 + 1照样还是地址,只要是地址,就是4 byte Or 8 byte
printf("%d\n", sizeof(&arr + 1));//4 byte / 8 byte(32位 / 64位)//&arr[0] 首元素的地址,首元素地址也是地址(4 byte / 8 byte),+1后仍然还是地址,所以还是 4 byte / 8 byte
printf("%d\n", sizeof(&arr[ 0 ] + 1));//4 byte / 8 byte(32位 / 64位)

2) 一维数组【char】char arr[] = {'a', 'b', 'c', 'd'};

char arr[] = {'a', 'b', 'c', 'd'};

sizeof


//在sizeof中,单写一个数组名,该数组名表示的就是整个数组,那么该数组的大小就是4  * 1 byte
printf("%d\n", sizeof(arr));//4 byte//arr表示的首元素地址,地址的大小就是 4 byte / 8 byte
printf("%d\n", sizeof(arr + 0));//4 byte / 8 byte(32位 / 64位)//arr表示的是首元素地址,解引用首元素地址 -> 元素的值 -> char的元素,占 1 byte
printf("%d\n", sizeof(*arr));//1 byte//arr[1]为第2个元素值,该值的元素为char类型,所以占 1 byte
printf("%d\n", sizeof(arr[ 1 ]));//1 byte//1.&arr表示的是整个数组的地址
//2.还有一种解释相对复杂,&arr拿到的是整个数组的地址,那么类型就是int(*)[4],这是一种数组指针,但是指针所占的大小依然是固定的
//只要是地址,一般就是 4 byte / 8 byte
printf("%d\n", sizeof(&arr));// 4 byte / 8 byte//整个数组的地址 + 1,直接跳过整个数组,至于地址是什么地方就不知道了,可能直接变为了野指针,但是指针的大小依然不变
printf("%d\n", sizeof(&arr + 1));// 4 byte / 8 byte //&arr[0]为首元素的地址,首元素的地址 + 1 就是 &arr[1],只要是地址,依然是4 byte / 8 byte
printf("%d\n", sizeof(&arr[ 0 ] + 1 ));// 4 byte / 8 byte(32位 / 64位)

strlen - strlen是一个函数,用于计算并返回给定字符串的长度

从提供的地址开始,计算直至遇到字符串终止符‘\0’所在地址,确定字符串的实际长度。

//给的是数组的首地址,而strlen是从给的地址计算到'\0'所在地址的,然而该数组中可能并没有'\0',因为后面的数据是随机的,所以不知道指向第几个地址时才会有'\0',那么求的该数组字符串的大小就是随机的了
printf( "%d\n", strlen( arr ) );//随机值//与上方的情况一样,依然是个随机值
printf( "%d\n", strlen( arr + 0 ) );//随机值//这个就好玩了,arr是收元素的地址,*arr就是首元素的值,而在该数组中,首元素的值为'a',那么strlen(*arr) <==> strlen('a') <==> strlen( 97 );
//strlen中的参数是个地址,所以计算机会把97当做地址,而这种地址是未定义或者不可预知的,也就是平时所熟知的野指针了,对于这种野指针,在编译的时候,一般不会报错,但是在调试的时候,会有弹窗来报错提示的
printf( "%d\n", strlen( *arr ) );//程序错误 - 野指针//与上方的情况是类似的,依然是报错
printf( "%d\n", strlen( arr[ 1 ] ) );//程序错误 - 野指针//依然是随机值,和strlen(arr)情况相似,在strlen(arr)中,arr表示的是数组首元素的地址( 类型 - char* ),&arr表示的是整个数组的地址( 类型 - (char*)[4] ),这俩虽然类型不一样,但是strlen的参数类型设置的是 const char*,在传参过去的时候,也会强行将地址类型转换为char*,所以这俩所表示的地址还是一样的,都是首元素的地址,所以依然是随机值
//其实首元素的地址和整个数组的地址虽然类型不一样,但是在打印的时候,数值确还是一样的,所以不要太纠结
printf( "%d\n", strlen( &arr ) );//随机值//&arr表示整个数组的地址,对&arr加1会跳过整个数组的内存区域,指向数组之后的内存,但这并不提供关于原数组长度的任何信息。对&arr加1后得到的地址与原数组无直接关联,它指向的是数组之后的内存区域。如果试图从这个地址开始“计算长度”,实际上依然是没有意义的。结果也就是随机值了。计算的时候不是从数组首地址开始计算的,而是从数组首地址开始算,第5个位置开始计算的,所以计算出来的大小就是原来的基础之上再减去4个(数组宽度)。
printf( "%d\n", strlen( &arr + 1 ) );//随机值 - 4//首元素的地址 + 1 得出的是arr[1]的地址,即&arr[1],从这开始计算,比原来少计算了1个
printf( "%d\n", strlen( &arr[0] + 1 ) );//随机值 - 1

3) 指针指向常量字符串,int* p = “abcdef” - 数组有’\0’`

//在sizeof中,单写一个数组名,该数组名表示的就是整个数组,但是要注意p可不是数组名,他是一个char*类型的指针变量,指向的是字符串的第一个元素的地址,就是'a'的地址,那么打印出来肯定就是地址的大小了,即 4 byte / 8 byte (32位 / 64 位)
printf("%d\n", sizeof(p));//4 byte / 8 byte//p指向常量字符串"abcdef"的首元素地址,地址的大小就是 4 byte / 8 byte
printf("%d\n", sizeof(p + 0));//4 byte / 8 byte(32位 / 64位)//p指向常量字符串"abcdef"的首元素地址,解引用首元素地址 -> 元素的值 -> char的元素,占 1 byte
printf("%d\n", sizeof(*p));//1 byte//p可以当数组名来用,p[1]为第2个元素值,该值的元素为char类型,所以占 1 byte
printf("%d\n", sizeof(arr[ 1 ]));//1 byte//&p是指针变量的地址,只要是地址,大小就是 4 byte Or 8 byte
printf("%d\n", sizeof(&p));// 4 byte / 8 byte//从p的地址跳过1个偏移量,依然还是地址
printf("%d\n", sizeof(&p + 1));// 4 byte / 8 byte //&p[0]为首元素的地址,首元素的地址 + 1 就是 &p[1],就相当于是'b'的地址,只要是地址,就是 4 byte / 8 byte
printf("%d\n", sizeof(&p[ 0 ] + 1 ));// 4 byte / 8 byte(32位 / 64位)

这次计算字符串长度就和上次不一样了,因为上次是没有‘\0’结尾,这次是有‘\0’结尾

//从'a'的地址开始计算到'f',宽度为6个
printf("%d\n", strlen(p));//6//这里与上面一样的
printf("%d\n", strlen(p + 0));//6//*p取出来是'a',也就是给了strlen一个地址为97
printf("%d\n", strlen(*p));//程序错误 - 野指针//p[1]取出来是'b',也就是给了strlen一个地址为98,这不是一个有定义的自己或是可预知的地址
printf("%d\n", strlen(p[ 1 ]));//程序错误 - 野指针//给strlen的是p的地址,而p是一个指针变量,这个定义的或者是可预知的,往后计算的时候,不知道何时会遇到'\0',那么计算出来就是随机值
printf("%d\n", strlen(&p));// 随机值//给strlen的是p的地址 + 1 偏移量,而p是一个指针变量,这个定义的或者是可预知的,往后计算的时候,不知道何时会遇到'\0',那么计算出来就是随机值
printf("%d\n", strlen(&p + 1));////&p[ 0 ] + 1 等于是 &p[1],相当于'b'开始计算,计算到'f',得出5个
printf("%d\n", strlen(&p[ 0 ] + 1 ));// 5

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

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

相关文章

R包的安装、加载以及如何查看帮助文档

0x01 如何安装R包 一、通过R 内置函数安装&#xff08;常用&#xff09; 1.安装CRAN的R包 install.packages()是一个用于安装 R 包的重要函数。 语法&#xff1a;install.packages(pkgs, repos getOption("repos"),...) 其中&#xff1a; pkgs&#xff1a;要安…

问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题

​ 编码: 把字符转换成字节序列的过程。因为计算机只能处 理二进制数据&#xff0c;所以不能直接处理文本&#xff0c;需要先把文本转换为二进制数据。 解码: 把二进制数据转换成字符的过程。把接收到的数据转换成程序中使用的编码方式。 ​ 这个报错原因就是编码和解码没达成…

【C++ STL】手撕vector,深入理解vector的底层

vector的模拟实现 前言一.默认成员函数1.1常用的构造函数1.1.1默认构造函数1.1.2 n个 val值的构造函数1.1.3 迭代器区间构造1.1.4 initializer_list 的构造 1.2析构函数1.3拷贝构造函数1.4赋值运算符重载 二.元素的插入,删除,查找操作2.1 operator[]重载函数2.2 push_back函数:…

[已解决] Install PyTorch 报错 —— OpenOccupancy 配环境

目录 关于 常见的初始化报错 环境推荐 torch, torchvision & torchaudio cudatoolkit 本地pip安装方法 关于 OpenOccupancy: 语义占用感知对于自动驾驶至关重要&#xff0c;因为自动驾驶汽车需要对3D城市结构进行细粒度感知。然而&#xff0c;现有的相关基准在城市场…

TriLite完成A轮扩展融资:加速AR微型投影仪技术创新与市场拓展

近日,全球领先的AR微型投影仪开发商TriLite宣布成功完成A轮扩展融资,将A轮融资总额提升至超过2000万欧元。这一轮融资不仅彰显了资本市场对TriLite技术实力和市场潜力的高度认可,更为其后续在AR微型投影仪领域的技术研发、产品迭代以及市场拓展提供了坚实的资金保障。以下是…

大厂笔试现已经禁用本地IDE怎么看

如果我说本来面试做题这种事情就是反人类你相信吗&#xff1f; 这个罪恶的源头就是 Google&#xff0c;说是为了选择高素质的计算机编程水平的人才&#xff0c;然后把面试就变成了考试&#xff0c;最大的受益者当然是印度人了。 当把一个考察过程变成标准化的考试过程&#x…

【AI知识点】置信区间(Confidence Interval)

置信区间&#xff08;Confidence Interval, CI&#xff09; 是统计学中用于估计总体参数的范围。它给出了一个区间&#xff0c;并且这个区间包含总体参数的概率等于某个指定的置信水平&#xff08;通常是 90%、95% 或 99%&#xff09;。与点估计不同&#xff0c;置信区间通过区…

Unity Input System自动生成配置

参考视频 创建及配置新输入系统 New Input System&#xff5c;Unity2022.2 最新教程《勇士传说》入门到进阶&#xff5c;4K_哔哩哔哩_bilibili ProjectSettings设置 Unity编辑器菜单栏选择Edit->Project Settings->Player->Other Settings,将Api Compatibility Level…

OpenAI 开发者大会!实时语音功能有API了,GPT-4o支持多模态微调,上下文cache功能上线

家人们&#xff01;十一假期第1天&#xff0c; OpenAI一年一度的开发者大会又来了惹&#xff01;今年的开发者大会分成三部分分别在美国、英国、新加坡三个地点举办&#xff0c;刚刚结束的是第一场。 去年的OpenAI开发者大会公布了GPT-4 Turbo和GPTs&#xff0c;今年没有大更新…

allegro精确画圆形边框

1.显示原点位置&#xff1a; 2.class-subclass依次选择Board Geometry-Outline 3.菜单ADD---Circle,右侧option,依次设置如下&#xff0c;如图可设置为圆心&#xff08;0&#xff0c;0&#xff09;&#xff0c;半径为42mm的边框&#xff0c;不要忘了右键Done&#xff0c;完成绘…

【目标检测】工程机械车辆数据集2690张4类VOC+YOLO格式

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2694 标注数量(xml文件个数)&#xff1a;2694 标注数量(txt文件个数)&#xff1a;2694 标注…

《Windows PE》3.2.4节表

节表由多个节表项&#xff08;IMAGE_SECTION_ HEADER&#xff09;组成&#xff0c;每个节表项&#xff08;40个字节&#xff09;记录了 PE中与某个特定的节有关的信息&#xff0c;如节的属性、节 的大小、在文件和内存中的起始位置等。节表中节的数量由字段IMAGE_FILE_HEADER. …

防止错误输入!Excel单元格限制输入内容的三种有效方式

在Excel中&#xff0c;限制单元格输入内容可以帮助避免数据输入错误&#xff0c;确保数据的一致性和准确性。今天小编分享三种方法&#xff0c;可以轻松限制Excel单元格的输入内容&#xff0c;确保数据输入符合预期要求&#xff0c;一起来看看吧&#xff01; 方法一&#xff1a…

el-pagination组件封装

组件使用 源代码&#xff1a; <script setup> import Pagination from /components/pagination/index.vue import {ref} from "vue";const pageNum ref(1) const pageSize ref(10) const total ref(120)function loadData() {// 加载数据 } </script>…

[云] Hands-on with a sample application--DockerCoins 挖矿程序!

DockerCoins 挖矿程序&#xff01;&#x1f4b0;&#x1f433;&#x1f4e6;&#x1f6a2; 不&#xff0c;你不能用 DockerCoins 买咖啡。 DockerCoins 如何工作&#xff1a; 生成一些随机字节&#xff1a; 程序首先生成一串随机的字节数据。这些随机字节用于模拟挖矿过程中的…

R语言绘制散点图

散点图是一种在直角坐标系中用数据点直观呈现两个变量之间关系、可检测异常值并探索数据分布的可视化图表。它是一种常用的数据可视化工具&#xff0c;我们通过不同的参数调整和包的使用&#xff0c;可以创建出满足各种需求的散点图。 常用绘制散点图的函数有plot()函数和ggpl…

算法专题三: 二分查找

目录 1. 朴素版: 二分查找2. 查找排序数组元素第一个和最后一个位置3. 搜索插入位置4. x的平方根5. 山脉数组的峰顶索引6. 寻找旋转数组中的最小值7. 点名 博客主页: 酷酷学!!! 感谢您的关注~ 正文开始 1. 朴素版: 二分查找 题目思路: 仅需根据题意, 找出二段性, 正确更新下标…

躺平成长:微信小程序运营日记第二天

在进行属于生活的开源之后&#xff0c;自己更加感受到自己存在的渺茫&#xff0c;同时更加开始深刻领会&#xff0c;开源的重要性&#xff0c;在开源&#xff0c;开放&#xff0c;创造&#xff0c;再创新的思维模式下&#xff0c;不发布八部金刚功相关的训练视频&#xff0c;自…

课设实验-数据结构-线性表-手机销售

题目&#xff1a; 代码&#xff1a; #include<stdio.h> #include<string.h> #define MaxSize 10 //定义顺序表最大长度 //定义手机结构体类型 typedef struct {char PMod[10];//手机型号int PPri;//价格int PNum;//库存量 }PhoType; //手机类型 //记录手机的顺序…

如何快速切换电脑的ip地址

在当今的数字化时代&#xff0c;IP地址作为网络身份的重要标识&#xff0c;其重要性日益凸显。无论是出于保护个人隐私的需要&#xff0c;还是为了访问特定的网络服务等&#xff0c;快速切换电脑的IP地址已成为许多用户的迫切需求。本文将为你介绍几种实用的方法&#xff0c;帮…