指针,数组 易混题解析(一)

news2025/3/25 15:18:33

目录

一.相关知识点

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));//2
	printf("%d\n", s);//5

	return 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内部,计算的是第四行的大小

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

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

相关文章

2025前端面试题记录

vue项目目录的执行顺序是怎么样的&#xff1f; 1、package.json   在执行npm run dev时&#xff0c;会在当前目录寻找package.json文件&#xff0c;此文件包含了项目的名称版本、项目依赖等相关信息。 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 αn​an​ibn​ 为复数&#xff0c;与高等数学中无穷级数的分析方式类似&#xff0c;也是通过和函数来研究级数的收敛…

高频面试题(含笔试高频算法整理)基本总结回顾67

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

Kafka--常见问题

1.为什么要使用 Kafka&#xff0c;起到什么作用 Kafka是一个高吞吐量、分布式、基于发布订阅的消息系统&#xff0c;它主要用于处理实时数据流 Kafka 设计上支持高吞吐量的消息传输&#xff0c;每秒可以处理数百万条消息。它能够在处理大量并发请求时&#xff0c;保持低延迟和…

优选算法的睿智之林:前缀和专题(一)

专栏&#xff1a;算法的魔法世界 个人主页&#xff1a;手握风云 目录 一、前缀和 二、例题讲解 2.1. 一维前缀和 2.2. 二维前缀和 2.3. 寻找数组的中心下标 2.4. 除自身以外数组的乘积 一、前缀和 前缀和算法是一种用于处理数组或序列数据的算法&#xff0c;其核心思想是…

【清华大学】AIGC发展研究(3.0版)

目录 AIGC发展研究报告核心内容一、团队简介二、AI哲学三、国内外大模型四、生成式内容&#xff08;一&#xff09;文本生成&#xff08;二&#xff09;图像生成&#xff08;三&#xff09;音乐生成&#xff08;四&#xff09;视频生成 五、各行业应用六、未来展望 AIGC发展研究…

JavaSE1.0(基础语法之运算符)

算术运算符 基础运算之加 减 乘 除 取余&#xff08; - * / %&#xff09; 运算符之相加&#xff08; &#xff09; 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);//…

蓝桥与力扣刷题(蓝桥 数的分解)

题目&#xff1a;把 2019分解成 3个各不相同的正整数之和&#xff0c;并且要求每个正整数都不包含数字 2 和 4&#xff0c;一共有多少种不同的分解方法&#xff1f; 注意交换 3 个整数的顺序被视为同一种方法&#xff0c;例如 1000100118和 1001100018 被视为同一种。 解题思…

Java IO 流:从字节到字符再到Java 装饰者模式(Decorator Pattern),解析与应用掌握数据流动的艺术

在 Java 编程中&#xff0c;IO&#xff08;输入输出&#xff09;流是处理数据输入输出的核心工具。无论是读取文件、网络通信&#xff0c;还是处理用户输入&#xff0c;IO 流都扮演着重要角色。本文将深入探讨 Java IO 流的核心概念、分类、经典代码实例及其应用场景&#xff0…

爬虫案例-爬取某站视频

文章目录 1、下载FFmpeg2、爬取代码3、效果图 1、下载FFmpeg FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。 点击下载: ffmpeg 安装并配置 FFmpeg 步骤&#xff1a; 1.下载 FFmpeg&#xff1a; 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系统基于流&#xff08;Stream&#xff09;​的概念&#xff0c;分为三层结构&#xff1a; ​流对象​&#xff08;如cin, cout, fstream&#xff09;​流缓冲区​&#xff08;streambuf&#xff0c;负责底层数据处理&#xff09;​数据源/目的…

企业级前端架构设计与实战

一、架构设计核心原则 1.1 模块化分层架构 典型目录结构&#xff1a; src/├── assets/ # 静态资源├── components/ # 通用组件├── pages/ # 页面模块├── services/ # API服务层├── store/ # 全局状态管理├── uti…

从入门到精通【MySQL】 CRUD

文章目录 &#x1f4d5;1. Create 新增✏️1.1 单行数据全列插入✏️1.2 单行数据指定列插入✏️1.3 多行数据指定列插入 &#x1f4d5;2. Retrieve 检索✏️2.1 全列查询✏️2.2 指定列查询✏️2.3 查询字段为表达式✏️2.4 为查询结果指定别名✏️2.5 结果去重查询 &#x1f…

08_双向循环神经网络

双向网络 概念 双向循环神经网络&#xff08;Bidirectional Recurrent Neural Network, BiRNN&#xff09;通过同时捕捉序列的正向和反向依赖关系&#xff0c;增强模型对上下文的理解能力。与传统的单向网络不同,BIRNN 能够同时从过去和未来的上下文信息中学习,从而提升模型的…

2025年Postman的五大替代工具

虽然Postman是一个广泛使用的API测试工具&#xff0c;但许多用户在使用过程中会遇到各种限制和不便。因此&#xff0c;可能需要探索替代解决方案。本文介绍了10款强大的替代工具&#xff0c;它们能够有效替代Postman&#xff0c;成为你API测试工具箱的一部分。 什么是Postman&…

(四)---四元数的基础知识-(定义)-(乘法)-(逆)-(退化到二维复平面)-(四元数乘法的导数)

使用四元数的原因 最重要的原因是因为传感器的角速度计得到的是三个轴的角速度, 这三个轴的角速度合成一个角速度矢量, 结果就是在微小时间内绕着这个角速度矢量方向为轴旋转一定角度. 截图来源网址四元数 | Crazepony开源四轴飞行器

汇能感知高品质的多光谱相机VSC02UA

VSC02UA概要 VSC02UA是一款高品质的200万像素的光谱相机&#xff0c;适用于工业检测、农业、医疗等领域。VSC02UA 包含 1600 行1200 列有源像素阵列、片上 10 位 ADC 和图像信号处理器。它带有 USB2.0 接口&#xff0c;配合专门的电脑上位机软件使用&#xff0c;可进行图像采集…

Blazor+PWA技术打造全平台音乐播放器-从音频缓存到离线播放的实践之路

开局三张图… 0.起源 主要是自己现在用的是苹果手机&#xff0c;虽然手机很高级&#xff0c;但是想听自己喜欢的歌曲确是不容易&#xff0c;在线app都要付费&#xff0c;免费的本地播放器都不太好用&#xff08;收费的也不太行&#xff09;&#xff0c;基础功能都不满足。此外…

使用LangChain开发智能问答系统

代码地址见文末 1. 项目配置 1.1 Neo4j 数据库配置 1. 安装与环境变量 解压路径:将neo4j-community-5.x.x.zip解压至D:\neo4j-community-5.x.x环境变量: NEO4J_HOME: D:\neo4j-community-5.x.xJAVA_HOME: D:\neo4j-community-5.x.x\jdk(注意:需指向 JDK 目录)Path 变量…