指针,数组 易混题解析(一)
目录
一.相关知识点
1.数组名是什么?
两个例外:
2.strlen
3.sizeof
4. * ( ) 与 [ ] 的互换
二.一维数组
三.字符数组
1. 字符
(1)sizeof
(2)strlen
2.字符串
(1)sizeof
(2)strlen
3.字符指针
(1)sizeof
(2)strlen
四.二维数组
一.相关知识点
1.数组名是什么?
一维数组数组名是首元素的地址。

二维数组数组名是首元素地址,是第一行的地址(一维数组的地址)。

两个例外:
1. sizeof(数组名),这里的数组名是表示整个数组,计算的是整个数组的大小,单位是字节
2. &数组名,这里的数组名是表示整个数组,& 数组名取出的是数组的地址


2.strlen
库函数,用来求字符串长度,统计的是\0之前出现的字符个数,一定要找到 ' \0 ' 才算结束,所以可能存在越界访问的。
头文件:#include <stdio.h>

注意:strlen 的函数参数是字符指针类型,我们要传给它开始统计字符长度位置的地址
3.sizeof
操作符,只关注变量占用内存空间的大小,单位是字节,不关心内存中存放的是什么
注意:1.sizeof 内部的表达式不计算
int main()
{int a = 0;short s = 5;printf("%d\n", sizeof(s = a + 3));//2printf("%d\n", s);//5return 0;
}
原因:

2.sizeof 根据类型判断大小,不会访问对应空间(不存在越界访问数组的情况)
变量是有类型的,数组也是有类型的。去掉名字就是类型
int main()
{int a = 0;int arr[10];printf("%d\n", sizeof(a));printf("%d\n", sizeof(int));printf("%d\n", sizeof(arr));printf("%d\n", sizeof(int [10])); //数组 arr 的类型:int [10]return 0;
}
4. * ( ) 与 [ ] 的互换

二.一维数组
int main()
{int a[] = { 1,2,3,4 };return 0;
}
易混例题:
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(a + 1));
1. 这里是数组名的两个例外情况之一,计算的是整个数组的大小。答案:4 * 4 = 16
2.3. 注意:这里sizeof( ) 里面不止有数组名,不是两个例外情况之一。
a 是数组首元素的地址,a + 0 也是数组第一个元素的地址,a + 1是第二个元素的地址。是地址就是4/8字节。答案:4/8
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[1]));
不是两个例外,a 是数组首元素地址。
*a是数组首元素,a[1] 是第二个元素。计算的是数组首,第二个元素的大小,单位字节。答案:4
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
1. &a是整个数组的地址,整个数组的地址也是地址,地址的大小就是4/8字节
&a 的类型:int (*)[4] 数组指针
2. &a是数组的地址,*&a就是拿到了数组。*&a --> a,a就是数组名,sizeof(*&a)-->sizeof(a)。计算的是整个数组的大小,单位是字节-16。
3. &a是整个数组的地址。&a+1,跳过整个数组,指向数组后边的空间,是一个地址,大小是4/8字节。
&a+1 的类型还是 int (*)[4] 数组指针
是否会越界访问?
不会。&a 与 &a+1 类型相同。sizeof 根据类型判断大小,不会访问对应空间。所以大小也相同。
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));
&a[0]是首元素的地址,&a[0] + 1是第二个元素的地址,计算的是首元素地址的大小,地址的大小就是4/8字节
三.字符数组
1. 字符
int main()
{char arr[] = { 'a','b','c','d','e','f' };return 0;
}
(1)sizeof
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
1. arr单独放在sizeof内部,计算的是整个数组的大小,单位是字节,6
2. arr 是首元素的地址,arr + 0 还是数组首元素的地址,4/8
3. arr 是首元素的地址,*arr是数组的首元素,计算的是首元素的大小:1字节
4. arr[1]是第二个元素,大小1字节
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
1. 取出的数组的地址,数组的地址也是地址,是地址大小就是4/8
2. &arr+1是跳过整个,指向数组后边空间的地址,4/8
3. &arr[0] + 1是数组第二个元素的地址,是地址4/8字节
(2)strlen
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
1.2. 两个传的都是首元素地址,让 strlen 从首元素位置开始统计。但没有 ' \0 ' 不止何时停止,随机值。
3. &arr虽然是数组的地址,但是也是从数组起始位置开始的,计算的还是随机值
&arr 的类型:char (*)[6] 数组指针
4. &arr是数组的地址,&arr+1是跳过整个数组的地址,求字符串长度也是随机值
5. &arr[0] + 1是第二个元素的地址,是'b'的地址,求字符串长度也是随机值
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
*arr 和 arr[1] 分别是数组第一元素 'a' ASCII码值是97;第二元素 'b' ASCII码值是98
strlen('a') 等价于 strlen(97)。直接让 strlen 从内存编号97的地址开始统计。非法访问,这样写是错的!
97作为地址访问内存,抱歉,97这个地址不能直接访问。只有把这片空间分配给你,你才有权限访问它。
2.字符串
int main()
{char arr[] = "abcdef"; // 数组是7个元素// [ a b c d e f \0 ]return 0;
}
(1)sizeof
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
1. 数组名单独放在sizeof内部,计算的是数组的总大小,单位是字节:7
2. arr+0是首元素的地址,大小是4/8
3. *arr是数组首元素,大小是1字节
4. arr[1]是数组的第二个元素,大小是1字节
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
1. &arr是数组的地址,数组的地址也是地址,是4/8字节
2. &arr + 1是跳过整个数组的地址,是4/8字节
3. &arr[0] + 1是第二个元素的地址,是4/8字节
(2)strlen
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
1. arr是数组首元素的地址,strlen从首元素的地址开始统计\0之前出现的字符个数,是6
2. arr + 0是数组首元素的地址,同第一个,结果是6
3. &arr虽然是数组的地址,但是也是从数组起始位置开始的,直至 \0 。 6
4. &arr + 1是跳过数组后的地址,统计字符串的长度是随机值
5. &arr[0]+1是b的地址,从第二个字符往后统计字符串的长度,大小是5
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
非法访问
3.字符指针
int main()
{const char* p = "abcdef";return 0;
}
错:把字符串 abcdef 放到指针 p 里 对:把首字符的地址放到 p 里
字符串里面的内容,地址是连续的
字符串打印只要告诉我起始位置,就可以打印,直到 \0
(1)sizeof
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p + 1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
1. p是指针变量,大小就是4/8字节
2. p + 1是b的地址,是地址,就是4/8个字节
3. *p是'a',sizeof(*p)计算的是字符的大小,是1字节
4. p[0] --> *(p+0) --> *p 就同上一个,1字节
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p + 1));
printf("%d\n", sizeof(&p[0] + 1));
1. 取出 p 的地址,p 是 char* 类型的指针,&p 取出 char* 的地址,是二级指针 char* *。是指针大小就是4/8
2. &p + 1是跳过p变量后的地址,4/8字节

3. p[0] 就是‘a’ , &p[0]就是a的地址,+1,就是b的地址,是地址就是4/8
也可以这样理解:![]()
(2)strlen
printf("%d\n", strlen(p));
printf("%d\n", strlen(p + 1));
1. p 指向 a 的地址,从 a 开始统计长度。6
2. p+1 指向 b 的地址,从 b 开始统计长度。5
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
*p 和 p[0] 都是 ' a ' 非法访问
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p + 1));
printf("%d\n", strlen(&p[0] + 1));

1. &p拿到的是p这个指针变量的起始地址,从这里开始求字符串长度完全是随机值
2. &p+1是跳过p变量的地址,从这里开始求字符串长度也是随机值
3. &p[0] + 1是b的地址,从b的地址向后数字符串的长度是5
四.二维数组
int main()
{int a[3][4] = { 0 };return 0;
}
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0] + 1));
printf("%d\n", sizeof(*(a[0] + 1)));
1. 计算整个数组的大小 3*4 * 4 = 48
2. a[0][0] 的第一行第一个元素。4
3. a[0]是第一行的数组名,数组名单独放在sizeof内部,计算的就是数组(第一行)的大小,16个字节
4. a[0]是第一行的数组名。没有单独放在sizeof内部;没有取地址。表示的就是数组首元素的地址,是a[0][0]的地址。
a[0]+1就是第一行第二个元素的地址,是地址就是4/8个字节
5. *(a[0] + 1)是第一行第2个元素,计算的是元素的大小。4个字节
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));
printf("%d\n", sizeof(&a[0] + 1));
printf("%d\n", sizeof(*(&a[0] + 1)));
printf("%d\n", sizeof(*a));
1. a是二维数组的数组名,数组名表示首元素的地址,就是第一行的地址,a+1就是第二行的地址。
第二行的地址也是地址,是地址就是4/8
a - int (*)[4] a+1--> int(*)[4]
2. a+1是第二行的地址,*(a+1)表示的就是第二行。16 *(a+1)--a[1]
3. &a[0]是第一行的地址,&a[0]+1是第二行的地址,地址的大小就是4/8
4. *(&a[0] + 1) 是对第二行的地址解引用,得到的就是第二行,计算的就是第二行的大小。16
5. a表示首元素的地址,就是第一行的地址,*a就是第一行,计算的就是第一行的大小。 *a -- *(a+0)--a[0]
printf("%d\n", sizeof(a[3]));
类型:int [4] 大小:16
如果数组存在第四行,a[3]就是第四行的数组名,数组名单独放在sizeof内部,计算的是第四行的大小
相关文章:
指针,数组 易混题解析(一)
目录 一.相关知识点 1.数组名是什么? 两个例外: 2.strlen 3.sizeof 4. * ( ) 与 [ ] 的互换 二.一维数组 三.字符数组 1. 字符 (1)sizeof (2)strlen 2.字符串 (1)si…...
Java 基础篇:数组
前言 数组(Array)是 Java 中最基本的数据结构之一,它用于存储相同类型的元素,并且在内存中是连续存储的。数组具有高效的索引访问特点,但长度固定,不能动态调整。 本文将介绍数组的基本概念、声明和初始化方…...
从汽车 BCM 方案看国产 MCU 芯片的突围与挑战
摘要 :汽车车身控制模块(BCM)作为汽车电子系统的核心控制单元,其性能高度依赖于微控制单元(MCU)芯片。随着汽车智能化与电动化的发展,国产 MCU 芯片在 BCM 领域的应用逐渐扩大。本文结合行业数据…...
深入理解 Spring 框架中的 IOC 容器
一、Spring 框架概述 Spring 框架是一个轻量级的 Java 开发框架,由 Rod Johnson 在 2003 年创建。它的诞生旨在简化企业级应用开发的复杂性。Spring 框架提供了诸如 IoC(控制反转)和 AOP(面向切面编程)等核心功能&…...
深入理解 Java 中 instanceof 操作符
目录 1. instanceof 的基本用法 1.1 语法 1.2 示例 2. instanceof 的用途 2.1 类型检查 2.2 类型转换 2.3 多态编程 3. instanceof 的注意事项 3.1 null 检查 3.2 接口检查 3.3 继承关系 3.4 性能问题 4. instanceof 代码示例 4.1 多态处理 4.2 接口检查 4.3 n…...
2025前端面试题记录
vue项目目录的执行顺序是怎么样的? 1、package.json 在执行npm run dev时,会在当前目录寻找package.json文件,此文件包含了项目的名称版本、项目依赖等相关信息。 2、webpack.config.js(会被vue-cli脚手架隐藏) 3、vue.config.js 对…...
复变函数摘记2
复变函数摘记2 3. 级数3.1 复数项级数3.2 复变幂级数3.3 泰勒级数3.4 洛朗级数 3. 级数 \quad 复数项级数的一般项 α n a n i b n \alpha_na_n\text{i}b_n αnanibn 为复数,与高等数学中无穷级数的分析方式类似,也是通过和函数来研究级数的收敛…...
光纤的频率和带宽
光纤通信中的频率和带宽涉及光波的物理特性以及通信系统的设计,以下是详细解释: 1. 光纤的工作频率 光纤通信利用光波作为载波,工作频率主要在近红外波段,具体频段和对应的波长如下: C波段(Conve…...
高频面试题(含笔试高频算法整理)基本总结回顾67
干货分享,感谢您的阅读! (暂存篇---后续会删除,完整版和持续更新见高频面试题基本总结回顾(含笔试高频算法整理)) 备注:引用请标注出处,同时存在的问题请在相关博客留言…...
Kafka--常见问题
1.为什么要使用 Kafka,起到什么作用 Kafka是一个高吞吐量、分布式、基于发布订阅的消息系统,它主要用于处理实时数据流 Kafka 设计上支持高吞吐量的消息传输,每秒可以处理数百万条消息。它能够在处理大量并发请求时,保持低延迟和…...
优选算法的睿智之林:前缀和专题(一)
专栏:算法的魔法世界 个人主页:手握风云 目录 一、前缀和 二、例题讲解 2.1. 一维前缀和 2.2. 二维前缀和 2.3. 寻找数组的中心下标 2.4. 除自身以外数组的乘积 一、前缀和 前缀和算法是一种用于处理数组或序列数据的算法,其核心思想是…...
嵌入式八股文学习——STL相关内容学习
文章目录 map和set的区别与实现1. map和set的区别2. 为什么set的元素和map的key不可修改? map和set的实现1. map的实现原理map的操作:map的特点: 2. set的实现原理set的操作:set的特点: map和set的底层原理(…...
【清华大学】AIGC发展研究(3.0版)
目录 AIGC发展研究报告核心内容一、团队简介二、AI哲学三、国内外大模型四、生成式内容(一)文本生成(二)图像生成(三)音乐生成(四)视频生成 五、各行业应用六、未来展望 AIGC发展研究…...
JavaSE1.0(基础语法之运算符)
算术运算符 基础运算之加 减 乘 除 取余( - * / %) 运算符之相加( ) public static void main(String[] args) {System.out.println("Hello world!");int a 10;int b 20;int c a b;System.out.println(c);//…...
二十五、实战开发 uni-app x 项目(仿京东)- 前后端轮播图
定义了一个名为 Swiper 的Java类,用于表示一个轮播图实体。它使用了 Jakarta Persistence API (JPA) 来映射数据库表,并使用了 Lombok 库来简化代码。以下是对代码的详细讲解: 1. 包声明 package com.jd.jdmall.model; 这行代码声明了该类所在的包路径为 com.jd.jdmall.mode…...
ubuntu设置开机自动运行应用
系统版本:Ubuntu 24.04.1 LTS桌面版 按招网上的资料显示,当前版本主要的实现方式有以下两种, 方式1:通过图形界面的【启动应用程序】设置开机自启动;方式2:配置为服务实现开机自启动。 但是在我的电脑上方…...
蓝桥与力扣刷题(蓝桥 数的分解)
题目:把 2019分解成 3个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺序被视为同一种方法,例如 1000100118和 1001100018 被视为同一种。 解题思…...
用ACM模式模板刷hot100
面试手撕给的模板基础上写 给的模板一般是下面这样 把while内容删除(一般刷hot100题目输入不需要同时输入几组) 第一个方法里写处理输入输出 自己再写一个方法,就是力扣里的核心代码(加上static) 第一个处理输入输…...
Java IO 流:从字节到字符再到Java 装饰者模式(Decorator Pattern),解析与应用掌握数据流动的艺术
在 Java 编程中,IO(输入输出)流是处理数据输入输出的核心工具。无论是读取文件、网络通信,还是处理用户输入,IO 流都扮演着重要角色。本文将深入探讨 Java IO 流的核心概念、分类、经典代码实例及其应用场景࿰…...
爬虫案例-爬取某站视频
文章目录 1、下载FFmpeg2、爬取代码3、效果图 1、下载FFmpeg FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。 点击下载: ffmpeg 安装并配置 FFmpeg 步骤: 1.下载 FFmpeg: 2.访问 FFmpeg 官网。 3.选择 Wi…...
nacos-未经授权创建用户漏洞
1、修改配置文件 vim application.properties# 修改配置项 nacos.core.auth.enabledtrue nacos.core.auth.enable.userAgentAuthWhitefalse2、重启nacos systemctl restart nacos3、验证 打开nacos部署服务器输入命令 curl -XPOST -d “usernametest123&passwordtest!123…...
C++:IO库
一、C IO库的架构 C标准库中的IO系统基于流(Stream)的概念,分为三层结构: 流对象(如cin, cout, fstream)流缓冲区(streambuf,负责底层数据处理)数据源/目的…...
企业级前端架构设计与实战
一、架构设计核心原则 1.1 模块化分层架构 典型目录结构: src/├── assets/ # 静态资源├── components/ # 通用组件├── pages/ # 页面模块├── services/ # API服务层├── store/ # 全局状态管理├── uti…...
从入门到精通【MySQL】 CRUD
文章目录 📕1. Create 新增✏️1.1 单行数据全列插入✏️1.2 单行数据指定列插入✏️1.3 多行数据指定列插入 📕2. Retrieve 检索✏️2.1 全列查询✏️2.2 指定列查询✏️2.3 查询字段为表达式✏️2.4 为查询结果指定别名✏️2.5 结果去重查询 …...
08_双向循环神经网络
双向网络 概念 双向循环神经网络(Bidirectional Recurrent Neural Network, BiRNN)通过同时捕捉序列的正向和反向依赖关系,增强模型对上下文的理解能力。与传统的单向网络不同,BIRNN 能够同时从过去和未来的上下文信息中学习,从而提升模型的…...
JSON数据修改的实现
JSON数据的修改 示例代码如下: using System.Collections; using System.Collections.Generic; using UnityEngine; //C#命名空间(以System开头) using System.IO; using LitJson; public class JsonChange : MonoBehaviour {// Start is called befor…...
2025年Postman的五大替代工具
虽然Postman是一个广泛使用的API测试工具,但许多用户在使用过程中会遇到各种限制和不便。因此,可能需要探索替代解决方案。本文介绍了10款强大的替代工具,它们能够有效替代Postman,成为你API测试工具箱的一部分。 什么是Postman&…...
(四)---四元数的基础知识-(定义)-(乘法)-(逆)-(退化到二维复平面)-(四元数乘法的导数)
使用四元数的原因 最重要的原因是因为传感器的角速度计得到的是三个轴的角速度, 这三个轴的角速度合成一个角速度矢量, 结果就是在微小时间内绕着这个角速度矢量方向为轴旋转一定角度. 截图来源网址四元数 | Crazepony开源四轴飞行器...
汇能感知高品质的多光谱相机VSC02UA
VSC02UA概要 VSC02UA是一款高品质的200万像素的光谱相机,适用于工业检测、农业、医疗等领域。VSC02UA 包含 1600 行1200 列有源像素阵列、片上 10 位 ADC 和图像信号处理器。它带有 USB2.0 接口,配合专门的电脑上位机软件使用,可进行图像采集…...
【SpringBoot】MorningBox小程序的完整后端接口文档
以下是「晨光宅配」小程序的完整接口文档,涵盖了所有12个表的接口。 每个接口包括请求方法、URL、请求参数、响应格式和示例 接口文档 1. 用户模块 1.1 获取用户信息 URL: /user/{userId}方法: GET请求参数: userId (路径参数): 用户ID响应格式:{"userId": 1,&qu…...
