详解------>数组笔试题(必备知识)

news2024/11/15 8:32:30

目录

本章将通过列题进一步了解sizeof 与strlen的区别,加强对数组的理解。

1:一维数组列题

2:字符数组列题

3:二维数组列题


        首先在进行这些习题讲解之前我们需要知道的知识点

                sizeof:是一个关键字,可以计算变量,数据类型,函数所占空间的大小,单位是字节,计算的时候只关心数据类型

                strlen:是一个标准库函数,头文件是   <striing.h>,是用来计算字符串\0前面的字符的个数,strlen(数组名)。

        还有对于数组名的理解:除了2种情况数组名就是首元素的地址,1:单独使用sizeof(数组名),这里的数组名指的是整个数组。2:&数组名,这里的数组名代表的是整个数组,所以&数组名代表的是整个数组的地址,它的指向也是数组的首元素的地址,但是在进行指针加减整数的时候跳过的是整个数组。

1:一维数组列题

        

#include<stdio.h>
int main()
{
    int a[] = {1,2,3,4};

    printf("%d\n",sizeof(a));//这里是特殊的情况,所以计算的是整个数组的大小 16

    printf("%d\n",sizeof(a+0));
    //这里的a是首元素的地址,+0后还是首元素地址,而地址(指针)的大小为4/8

    printf("%d\n",sizeof(*a));
    //a是首元素的地址,所以*a则代表数组中的第一个元素,所以大小为一个int的大小 4
    printf("%d\n",sizeof(a+1));
    //a代表数组首元素的地址,+1则代表指针指向2的地址,还是个地址所以大小为  4/8
    printf("%d\n",sizeof(a[1]));
    //a[1],代表数组中第二个元素即2,所以大小为int的大小   4
    printf("%d\n",sizeof(&a));
    //这里的a是特殊情况,所以a代表整个数组,但是&a还是一个地址  所以大小为 4/8
    printf("%d\n",sizeof(*&a));
    //这里有两种理解方式
    1:&a是代表数组的地址,* &a则代表数组  所以大小为数组的大小  16  *&  相当于没有
    2:&a本质上是数组指针,类型为int (*)[4],解引用后为类型int [4]  还是整个数组  16
    printf("%d\n",sizeof(&a+1));
    //&a+1代表的是地址,所以大小为4/8  但是在内存中表示为指针跳过整个数组,指向数组最后一个元素的后面
    printf("%d\n",sizeof(&a[0]));
    //这里就直接表示为取出第一个元素的地址,大小为  4/8
    printf("%d\n",sizeof(&a[0]+1));
    //这里表示第2个元素的地址,也是4/8,指针加一跳过一个int
}

这是在32位平台下的结果

64位平台下的结果

图解:a,a+1,&a,&a+1,&a[0],&a[0]+1

2字符数组

        形式1:

        

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

printf("%d\n", sizeof(arr));
//这里代表整个数组的大小,为      6
printf("%d\n", sizeof(arr+0));
//这里的arr代表数组的首元素的地址,所以为  4/8
printf("%d\n", sizeof(*arr));
//这里的arr代表数组首元素的地址,所以*arr代表字符'a'   为1
printf("%d\n", sizeof(arr[1]));
//arr[1]代表,'b'    为1
printf("%d\n", sizeof(&arr));
//&arr代表整个数组的地址,所以为     4/8
printf("%d\n", sizeof(&arr+1));
//&arr+1表示跳过数组arr,指向下一个数组   4/8
printf("%d\n", sizeof(&arr[0]+1)); //也等于&arr[1]
//这里代表取出 字符'b'的地址,也是   4/8

   // 关于strlen
printf("%d\n", strlen(arr));
//这里的值为随机值,因为不知道内存中/0在哪
printf("%d\n", strlen(arr+0));
//这里的arr还是指的是数组首元素的地址,而strlen需要一个字符串,所以代码是error的
printf("%d\n", strlen(*arr));
//这里的*arr代表的是'a',而我们strlen需要char* 的参数,而'a'的asc码值为97,则会将代码段区域的 //地址传给strlen,这段代码块不是我们的内存,所以会形成非法访问内存的情况,所以也是error的
printf("%d\n", strlen(arr[1]));
//这里arr[1],代表的是'b',同理也是错误的只是asc变成98了  error
printf("%d\n", strlen(&arr));
//&arr代表的是整个数组的地址,但是它的值还是第一个元素的地址,沿着第一个元素向后寻找,所以也为随机值
printf("%d\n", strlen(&arr+1));
//同理,这是代表跳过数组后的地址,也是随机值,与前面一个相差  6
printf("%d\n", strlen(&arr[0]+1));
//这里代表'b'的地址,与arr差值为1

  32位平台下:

      

64位平台下:

形式2:

int main()
{
	char arr[] = "abcdef";//字符串中多了一个 '\0'

	printf("%d\n", sizeof(arr));
    //这里的arr代表整个数组,所以 大小为               7
	printf("%d\n", sizeof(arr + 0));
    //arr代表数组首元素地址 所以为                    4/8
	printf("%d\n", sizeof(*arr));
    //arr代表数组首元素,*arr则代表数组中的第一个元素   1
	printf("%d\n", sizeof(arr[1]));
    //arr[1]代表 'b',所以值为                        1
	printf("%d\n", sizeof(&arr));
    //&arr代表整个数组的地址    大小                  4/8
	printf("%d\n", sizeof(&arr + 1));
    //&arr+1代表跳过一个数组的地址,                  4/8
	printf("%d\n", sizeof(&arr[0] + 1));  
    //这里表示指向'b'的地址                           4/8

	printf("%d\n", strlen(arr));//strlen求得是字符串'/0'前面的元素个数
    //arr,表示数组的首元素地址,                      6
	printf("%d\n", strlen(arr + 0));
    //arr还是数组首元素的地址                         6
	printf("%d\n", strlen(*arr));
    //*arr代表的是'a',asc为97,strlen需要char* 所以改语句是error的
	printf("%d\n", strlen(arr[1]));
    //这个arr[1]代表数组的第2个元素即'b'同理,也会error
	printf("%d\n", strlen(&arr));
    //表示数组的地址,但是值还是与&arr[0]相等          6
	printf("%d\n", strlen(&arr + 1));
    //这个为随机值,&arr+1代表跳过整个数组后的地址   随机值
	printf("%d\n", strlen(&arr[0] + 1));
    这个代表的是'b'的地址,所以值为                    5
}

32位平台:

64位平台下:

为了理解上面的两个字符串的差异,我们可以通过画图来理解:

常量字符串:

        

char *p = "abcdef";//首先这个代码的理解是在代码段中存储着"abcdef"这个字符串,而p则是代表存储着这个字符串的地址

printf("%d\n", sizeof(p));
//这里的p是一个字符指针,所以大小为                        4/8
printf("%d\n", sizeof(p+1));
//指针加1且为char*指针,p+1代表指向b的地址                 4/8
printf("%d\n", sizeof(*p));
//char*指针解引用只访问1个字节内容,*p代表 'a'              1   
printf("%d\n", sizeof(p[0]));
//p[0]表示*(p+0)-->*p    'a'                              1
printf("%d\n", sizeof(&p));
//&p代表的是指向p地址的指针,是一个char**指针               4/8
printf("%d\n", sizeof(&p+1));
//&p+1是跳过1个字符指针的指针                              4/8
printf("%d\n", sizeof(&p[0]+1)); 
//即&p[1]-->&(p+1),也就是b的地址                          4/8


printf("%d\n", strlen(p));
//p的值为a的地址                                          6
printf("%d\n", strlen(p+1));
//p+1代表'b'的地址                                        5
printf("%d\n", strlen(*p));
//error的*p为 'a'
printf("%d\n", strlen(p[0]));
//error  p[0],代表的是'a'
printf("%d\n", strlen(&p));
//随机值,这里的&p代表的是存储p的地址                       随机值
printf("%d\n", strlen(&p+1));
//这里是跳过一个二级字符指针后面的地址                      随机值
printf("%d\n", strlen(&p[0]+1));
//这里代表首元素地址+1,表示'b'的地址所以值为                5

     

3:二维数组 

        

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

printf("%d\n",sizeof(a));
//这里的a代表的是整个数组,所以值为                                     48
printf("%d\n",sizeof(a[0][0]));
//a[0][0]代表第一个元素                                                4
printf("%d\n",sizeof(a[0]));
//a[0]可以看作二维数组的首元素为一个一维数组                            16
printf("%d\n",sizeof(a[0]+1));
//a[0]表示一维数组名,表示一维数组的首元素的地址+1表示 指向a[0][1]的地址,4/8  
printf("%d\n",sizeof(*(a[0]+1)));
//表示a[0][1]这个元素                                                 4
printf("%d\n",sizeof(a+1));
//a表示首元素的地址,即1维数组的地址  int(*)[4],+1则代表指向第二个一维数组的地址   4/8   
printf("%d\n",sizeof(*(a+1)));
//表示第二个一维数组    大小为                                         16
printf("%d\n",sizeof(&a[0]+1));
//&a[0]表示一维数组的地址,类型为int(*)[4],+1则代表指向第二个二维数组的地址   4/8
printf("%d\n",sizeof(*(&a[0]+1)));
//第二个二维数组的大小                                                     16
printf("%d\n",sizeof(*a));
//a代表首元素的地址,即一维数组的地址,*a则代表一位数组                     16
printf("%d\n",sizeof(a[3]));
//a[3],虽然数组存在越界,但是sizeof只关注类型,所以a[3]                   16

 32位平台下:

 64位平台下:

总而言之,我们需要知道核心的知识点才不会被题目带偏。

        感谢观看!

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

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

相关文章

KMP--高效字符串匹配算法(Java)

KMP算法 KMP算法算法介绍代码演示: KMP算法 KMP算法是为了解决这一类问题,给定一个字符串str1,和一个字符串str2,如果str2属于str1d的字串,则返回字串第一个出现位置的下标,不存在返回-1. 注意: 子串是连续的. 举个例子 str1 “abc123abs” str1 长度假设m str2 “123”; str2…

pycharm汉化

安装pycharm 不多说了&#xff0c;直接下载安装即可 汉化 file -setting plugins 输入chinese进行搜索 点击 进行安装&#xff0c;等待安装完成 安装完成需要重启&#xff0c;点击重启&#xff0c;等待重启完成即可 出现上图&#xff0c;说明汉化成功了

【计算机视觉】YOLOv8的测试以及训练过程(含源代码)

文章目录 一、导读二、部署环境三、预测结果3.1 使用检测模型3.2 使用分割模型3.3 使用分类模型3.4 使用pose检测模型 四、COCO val 数据集4.1 在 COCO128 val 上验证 YOLOv8n4.2 在COCO128上训练YOLOv8n 五、自己训练5.1 训练检测模型5.2 训练分割模型5.3 训练分类模型5.4 训练…

Mybatis-xml和动态sql

xml映射方式 除了之前那种 select(语句) public void ...();通过注解定义sql语句&#xff0c;还可以通过xml的方式来定义sql语句 注意 在resource创建的是目录&#xff0c;要用斜线分隔 创建出文件后 先写约束 <?xml version"1.0" encoding"UTF-8"…

第4集丨JavaScript 使用原型(prototype)实现继承——最佳实战2

目录 一、临时构造器方式1.1 代码实现1.2 代码分析 二. 增加uber属性&#xff0c;用于子对象访问父对象2.1 实现分析2.2 代码实现 三. 将继承封装成extend()函数3.1 代码实现3.1.1 临时构造器实现extend()3.1.2 原型复制实现extend2() 3.2 代码测试3.2.1 测试extend()函数3.2.1…

uniapp打包嵌入app,物理返回键的问题

问题描述&#xff1a;将uniapp开发的应用打包成wgt包放入app后&#xff0c;发现手机自带的返回键的点击有问题&#xff0c;比如我从app原生提供的入口进入了uniapp的列表页&#xff0c;然后我又进入了详情页&#xff0c;这时候在详情页点击物理返回键的话&#xff0c;它直接就返…

C语言—最大公约数和最小公倍数

作者主页&#xff1a;paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《算法详解》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心…

过河卒

题目描述 棋盘上 A 点有一个过河卒&#xff0c;需要走到目标 B 点。卒行走的规则&#xff1a;可以向下、或者向右。同时在棋盘上 C 点有一个对方的马&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示&#xff…

云同步盘 vs 普通网盘:选择哪种更适合你?区别解析与选购指南!

云同步盘是一种基于云存储的在线服务&#xff0c;主要用于将本地文件存储到云端&#xff0c;并通过客户端软件实现文件的自动同步&#xff0c;从而保持本地和云端文件的同步更新。用户可以在任何设备上访问和共享这些文件。 云同步盘和普通云盘都是云存储服务&#xff0c;可以让…

Kubernetes CoreDNS

Kubernetes CoreDNS 1、DNS服务概述 coredns github 地址&#xff1a; https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base service 发现是 k8s 中的一个重要机制&#xff0c;其基本功能为&#xff1a;在集群内通过服务名…

TL-ER2260T获取SSH密码并登录后台

TL-ER2260T获取SSH密码并登录后台 首先需要打开诊断模式 打开Ubuntu&#xff0c;通过如下指令计算SSH密码&#xff0c;XX-XX-XX-XX-XX-XX是MAC地址echo -n "XX-XX-XX-XX-XX-XX" | tr -d - | tr [a-z] [A-Z] | md5sum | cut -b 1-16SSH登录ssh -oKexAlgorithmsdiffie…

硬件打样和小批量生产

PCB 打样和小批量生产过程 包括PCB 定型、生产文件制作、元器件准备、装配图制作、贴片、全流程测试。 打样一般是 几块PCB 手工进行焊接。 其中生产文件根据加工厂 一般提供PCB或者Gerber。 元器件准备设计公司的物料管理&#xff0c;这里假设已经拿到了所需的物料。 装…

微信小程序开发22__在列表中 高亮选中某一项

思考一个问题: 在一个列表中&#xff0c;怎样实现高亮选中 某一项呢? 我们先看要实现的效果图 <!-- 这里data-index 用于点击时传递参数, 在js取时写法&#xff1a; e.target.dataset.index --> <view wx:for"{{info}}" class"{{indexnum?active:…

UTOPIA Automatic Generation of Fuzz Driver using Unit Tests

UTOPIA: Automatic Generation of Fuzz Driver using Unit Tests 这篇论文主要由三星研究院发表于2023 IEEE Symposium on Security and Privacy (SP)会议上 论文获取链接&#xff1a; https://gts3.org/assets/papers/2023/jeong:utopia.pdf 背景 模糊测试分为两种&#xf…

整理FTP协议相关知识,撰写FTP服务器文件列表展示、文件上传、文件下载等代码案例和实现步骤细节;

1、FTP简介&#xff1a; FTP 是File Transfer Protocol&#xff08;文件传输协议&#xff09;的英文简称&#xff0c;而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时&#xff0c;它也是一个应用程序&#xff08;Application&#xff09;。基于不同的操作…

Redis-Desktop-Manager连接时出现Can’t connect to redis-server

目录 1. Redis-Desktop-Manager连接需要四个参数 2.修改数据库配置文件 3.关闭防火墙 4.此时连接Redis-Desktop-Manager 1. Redis-Desktop-Manager连接需要四个参数 Name&#xff1a;自定义连接名 Host&#xff1a;redis服务器地址&#xff0c;在CentOS终端中使用命令&…

dubbo入门

Dubbo概述 官网&#xff1a; https://dubbo.apache.org Dubbo快速入门 1 安装zk 参考 https://blog.csdn.net/qq_34914039/article/details/131614771 2 实现步骤

人体扫描新技术:手机扫描生成3D人体模型

人体扫描是一种新兴的技术&#xff0c;它可以通过数字化的方式&#xff0c;再现人体的内部结构。这种模型的应用范围广泛&#xff0c;不仅可以应用于医学领域&#xff0c;还可以用于虚拟现实、游戏开发等各个领域。通过人体扫描生成模型&#xff0c;我们可以实时地观察人体内部…

【网络】TCP协议详解

目录 TCP协议格式 感性理解TCP报头 认识报头中的字段 序号和确认序号 4位首部长度 窗口大小 标记位 确认应答机制 超时重传机制 TCP协议格式 感性理解TCP报头 linux内核是用C语言写的&#xff0c;所以报头实际上就是一种结构化的数据对象&#xff0c;用伪代码可表示为…

23种设计模式总结

设计模式的本质是&#xff1a;“找到变化&#xff0c;封装变化” 设计模式的类型分为&#xff1a; 创建型&#xff1a;负责提供创建对象的机制 结构型&#xff1a;将对象或类组合成更大的结构&#xff0c;同时保持对外结构的不变&#xff0c;对内结构的灵活 行为型&#xff1a…