指针面试题详解

目录

前言(数组名的总结):

一、int 型数组和 sizeof 的组合

sizeof计算原理

 二、char类型和strlen()组合

三、char*类型和sizeof()组合(有 '\0' 版本)

四、char*类型和strlen()组合(有 '\0' 版本)

五、二维数组和sizeof()组合


前言(数组名的总结):

因为本文章大部分与数组名有关,我们首先温习一下数组名的知识,数组名通常都表示数组的首元素地址,但是有两个例外:

  • &数组名,这里的数组名就表示整个数组的地址
  • sizeof(数组名),这里的数组名也表示整个数组的地址

除上述两种特殊情况外,其余我们见到的数组名都表示数组的首元素地址。

一、int 型数组和 sizeof 的组合

	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));

此时的数组名就是表示整个数组的地址,所以计算结果就是4*4=16

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

此时的数组名不是两种特殊情况,因此就表示数组的首元素地址,+0无效果,所以最终还是数组的首元素地址,因此答案4/8个字节(指针的大小)

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

此时数组名也表示数组的首元素地址,然后解引用*就是数组的第一个元素,也就是4个字节

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

 这个数组名也表示数组的首元素地址,然后+1,因为a是int *类型,+1就跳过一个int类型的大小,所以a+1就表示数组的第二个元素的地址,答案是4/8(指针大小)

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

 此时的数组名确实表示整个数组的地址,但他本质上还是一个指针,不能在门缝里看指针,把指针看扁了,无论什么类型的指针,他的大小都是4/8个字节!

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

* 和 & 是两个相逆的运算,相当于求导和求微分的意思,所以这两个在一起,就可以抵消。

因此*&a==a

而我们上面已经讲过,答案就是4*4

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

&a+1 相较于 &a 跳过了整个数组,但本质上还是地址,所以结果是4/8

sizeof计算原理

sizeof只需要知道数据类型是什么,不需要访问内存去计算,甚至sizeof(int),这样的表达式也是可以的 

 二、char类型和strlen()组合

首先我们明确,strlen计算字符串的长度,计算的是\0之前出现的字符的个数

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

注意这一种初始化方式,内存中存储的是

a b c d e f

后面内容未知,前面内容也未知。

	strlen(arr);

因为arr里面没有存放\0,所以strlen会一直向后寻找,直到找到为止,而后面存储的内容我们是未知的,因此最后结果就是随机值。

	strlen(arr + 0);

表示的仍然是首元素的地址,跟第一个一样,因此结果也是随机值

	strlen(*arr);

这样写是非法的!

因为strlen()需要的参数是字符指针类型,而我们将*arr也就是数组的第一个元素 'a' 作为参数传递进去,转换为97,而strlen会将97作为地址访问,而97并不是我们的地址,所以就造成了非法访问内存了。

	strlen(arr[1]);

这一题跟上一题一样,都是非法访问内存,是错误的。

	strlen(&arr);

我们首先需要明确&arr,和数组的首元素的地址值是一样的。

但是类型不一样,前者是 char (*) [ ],后者是 char* 。

但是我们将地址传到strlen之后,函数会将地址自动转换为想要的const char* 

因此,还是会从数组的首元素开始访问,答案也就是随机值

	strlen(&arr + 1);

这题表示跳过了整个数组,答案也就是随机值,并且跟上一题的结果有联系,相差6,因为跳过整个数组,数组的6个字符元素。

三、char*类型和sizeof()组合(有 '\0' 版本)

	char* p[] = { "abcdef" };//字符串已经含有'\0'

把字符串首元素a的地址赋给arr。 

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

注意这里的p不是数组名,他本质上就是一个指针变量,所以结果就是4/8个字节

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

首先表示字符串第二个元素的地址,因为 p是char* 类型,所以p+1就跳过一个字符的大小,所以就是b的地址。是地址就是4/8个字节

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

因为p存储的是字符串首元素的地址,所以解引用就是字符串的首元素,因此结果就是一个字符的大小——1

	printf("%d\n", &p + 1);

答案是显而易见的,仍然是地址(4/8),但这题的关键在于&p+1到底指向哪里?

我们首先明确&p的类型是char **,p的类型是char*。

+1就跳过char*的内容,而char*的内容指向的是p,所以+1就跳过p,最终指向的是p后面

注意字符串首元素的地址和p的地址是两码事,是两块不同的内存空间

四、char*类型和strlen()组合(有 '\0' 版本)

	char* p[] = { "abcdef" };//字符串已经含有'\0'
	printf("%d\n", strlen(p));

到\0前面停止,就是6个字符

	printf("%d\n", strlen(p + 1));

p是a的地址,+1就是b的地址,所以结果就是6-1=5

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

此时输入是非法的,因为*p就是把a传进去,而strlen需要一个字符指针。

	printf("%d\n", strlen(&p));

p的地址和字符串存的地址没有任何关系,也是随机值

	printf("%d\n", strlen(&p + 1));

也是随机值,但与&p有没有关系呢?

其实并没有关系,因为p是一个地址,4/8个字节,我们并不能确定这4~8个字节里面是否含有\0,如果有,那这两者无任何关系

五、二维数组和sizeof()组合

	int arr[3][4] = { 0 };

 

二维数组在内存中的存储方式就是这样的。

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

注意此时的数组名直接放在了sizeof里面,所以就是表示整个数组3*4*4=48

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

 TIP:

在二维数组中,我们认为第一行就是第一个元素

arr[0]:二维数组第一行这个一维数组的数组名

arr[1]:二维数组第二行这个一维数组的数组名

arr[2]:二维数组第三行这个一维数组的数组名

以此类推……

所以此时的arr[0]就是二维数组第一行的数组名,既然又是数组名,那么就仍表示整个数组

4*4=16

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

首先arr[0]并没有单独放在sizeof()内部,也没有&arr,所以此时的arr[0]就表示数组第一行的首元素地址,也就是arr[0][0]的地址,再+1就表示arr[0][1]的地址,结果是4/8个字节

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

arr是表示数组的首元素地址,但这是二维数组,所以首元素也就是二维数组的第一行的地址

再+1就表示第二行整体的地址,是地址就是4/8个字节、

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

第一种思路:

*(arr+1)==arr[1],这两者互相转换,所以我们把arr[1]单独放在sizeof()内部就表示整个第二行的数组,所以就是4*4

第二种思路:

上一题我们讲过arr+1就是数组的第二行元素的地址,类型是int (*) []是数组指针,而我们对数组指针解引用,访问的就是整个数组。4*4

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

&arr[0]表示的二维数组第一行的地址,再+1就表示第二行的地址。4/8

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

我们由上一题已经直到&arr[0]+1就表示数组的第二行地址,再解引用就是整个第二行元素的大小4*4

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

因为数组名没有单独放在sizeof(),也没有&,所以就表示数组的首元素地址,在二维数组中也就是第一行的地址,然后解引用,计算整个第一行,4*4

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

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

相关文章

LC-931 下降路径最小和(记忆化搜索 ==> 动态规划)

931. 下降路径最小和 难度中等247 给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列…

从小白到大神之路之学习运维第58天--------Firewalld防火墙

第三阶段基础 时 间:2023年7月12日 参加人:全班人员 内 容: Firewalld防火墙 目录 Firewalld防火墙 一、防火墙 1、netfilter和防火墙管理工具 2、防火墙配置模式 3、Firewalld数据流处理的方式 4、firewalld区域类型 1&#x…

python常用库之colorama (python命令行界面打印怎么加颜色)

文章目录 python常用库之colorama (python命令行界面打印怎么加颜色)背景colorama介绍colorama使用colorama打印红色闪烁打印颜色组合 python常用库之colorama (python命令行界面打印怎么加颜色) 背景 在Python开发项目过程中,为了方便调试代码,经常会…

fastapi初使用,构建自己的api

文章目录 1、安装2、api实现2.1、 app.get("/1)2.2、app.get("/{a})2.3、app.get("/{a}{b}")2.4、函数和api分离 3、运行 原文链接:https://wangguo.site/posts/d98bb3c9.html fastapi 是一个基于 Python 的 API 构建框架,简单且易用…

LLM - DataCollatorForLanguageModeling 样本生成 by transformers

目录 一.引言 二.生成样本 By API 1.样本处理样式 2.DataCollatorForLanguageModeling 2.1 样本准备 2.2 API 生成 三.生成样本 By DIY 1.样本准备 2.data_colloator 实现 3.使用自定义 data_colloator 四.总结 一.引言 前面我们讲了 Baichuan7B 的 lora 微调步骤&a…

详解sentinel使用

目录 1.概述 2.下载安装 3.应用托管 4.流量控制 4.1.流控规则 4.2.流控模式 4.2.1.直接模式 4.2.2.关联模式 4.2.3.链路模式 4.3.流控效果 4.3.1.预热 4.3.2.排队等待 5.降级 5.1.降级规则 5.2.降级策略 5.2.1.RT 5.2.2.异常比例 5.2.3.异常数 1.概述 senti…

直播 | SDS 容灾方案,让制品数据更安全

近日,腾讯 CODING WePack 制品管理系统 V1 以及腾讯 CODING DevOps 研发效能管理平台 V7 与 XSKY 星辰天合的统一数据平台 XEDP 及天合翔宇分布式存储系统完成互相兼容认证,在数据层面满足了共同客户敏捷开发的高可用建设合规要求。 联合解决方案可以帮…

【动手学深度学习】层和块

层和块 简单介绍 块:描述单个层,由多个层组成的组件或整个模型本身。使用块进行抽象的一个好处是可以将一些块组合成更大的组件,这一过程通常是递归的 简单入门 import torch from torch import nn from torch.nn import functional as F# …

【GitHub】腾讯这一款设计神器,开源了!PAG 动效组件

作为一个资深的互联网用户,我们经常会在各种产品上看到十分酷炫的动画效果。比如,短视频中有趣的虚拟场景、直播间粉丝打榜的 “火箭”、“轮船” 等等。 如今,优质的动效不仅可以使用户更容易地理解产品功能和操作方式,减少用户…

一套完全开源,支持多租户,界面配置单点的后端框架JVS

JVS的多租户体系统 在IT系统中,“租户”(tenant)通常用于指代一种多租户架构(multi-tenancy),它是一种软件架构模式,允许多个用户或组织共享相同的应用程序或系统实例,但彼此之间的…

lwip-2.1.3自带的httpd网页服务器使用教程(一)从SD卡读取网页文件并显示

概述 本教程使用的单片机是STM32F103ZE,有线网口芯片为ENC28J60。 本教程里面的网页由于需要兼容Windows XP系统的IE8浏览器,所以采用HTML 4.01编写,不使用任何前端框架。笔者使用的网页设计软件是Adobe Dreamweaver CS3。 开发板PCB文件是公…

运维小知识(一)——centos系统安装(小白入门级)

目录 1.制作系统U盘 2.安装centos系统 3.系统配置 3.1【语言】配置​编辑 3.2【软件选择】配置 3.3【安装位置】配置 3.4【主机名、root密码、网络】配置 1.制作系统U盘 首先下载软件ventoy,制作系统U盘,买个新U盘。先在笔记本电脑安装ventoy软件&a…