当前位置: 首页 > news >正文

【C语言】指针和数组笔试题解析

大家好,我是苏貝,本篇博客带大家了解指针和数组笔试题解析,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • 1.前言
  • 2.一维数组
  • 2.字符数组
    • 2.1
    • 2.2
    • 2.3
    • 2.4
    • 2.5
    • 2.6

1.前言

本篇文章是讲述在不同数组和指针的条件下,使用sizeof和strlen,让我们对数组和指针的理解更深。

数组名一般表示首元素地址,除以下2种情况:
1.sizeof(数组名),括号里面只有数组名,此时数组名表示整个数组,计算的是整个数组的大小
2.&数组名,数组名表示整个数组,取出的是整个数组的地址

指针变量的大小为4/8byte:
1.在32位机器下,每个地址有32个比特位,即32/8=4个字节,所以指针变量的大小也为4个字节
2.在64位机器下,每个地址有64个比特位,即64/8=8个字节,所以指针变量的大小也为8个字节

2.一维数组

思考下面代码的结果:

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//1
printf("%d\n",sizeof(a+0));//2
printf("%d\n",sizeof(*a));//3
printf("%d\n",sizeof(a+1));//4
printf("%d\n",sizeof(a[1]));//5
printf("%d\n",sizeof(&a));//6
printf("%d\n",sizeof(*&a));//7
printf("%d\n",sizeof(&a+1));//8
printf("%d\n",sizeof(&a[0]));//9
printf("%d\n",sizeof(&a[0]+1));//10

结果:
1.16byte;sizeof(数组名),括号里面只有数组名,此时数组名表示整个数组,计算的是整个数组的大小=4*sizeof(int)=16
2.4/8byte;sizeof后面括号内不止有数组名,所以该数组名代表首元素地址而非整个数组,首元素地址+0=首元素地址,是地址就是4/8byte
3.4byte;a是首元素地址,*a表示对首元素地址解引用找到首元素,首元素类型为int,所以sizeof(int)=4
4.4/8byte;a是首元素地址,a+1是第二个元素的地址,是地址就是4/8byte
5.4byte;a[1]是第二个元素,元素类型为int,所以sizeof(int)=4
6.4/8byte;&a表示取出的是整个数组的地址,是地址就是4/8byte
7.16byte;&a表示取出的是整个数组的地址,再对整个数组的地址解引用找到整个数组,整个数组的大小为16byte
8.4/8byte;&a表示取出的是整个数组的地址,&a+1表示跳过整个数组后的地址(如下图),是地址就是4/8byte
9.4/8byte;&a[0]表示取出首元素地址,是地址就是4/8byte
10.4/8byte;&a[0]表示取出首元素地址,+1表示第二个元素的地址,是地址就是4/8byte

在这里插入图片描述


2.字符数组

2.1

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//1
printf("%d\n", sizeof(arr+0));//2
printf("%d\n", sizeof(*arr));//3
printf("%d\n", sizeof(arr[1]));//4
printf("%d\n", sizeof(&arr));//5
printf("%d\n", sizeof(&arr+1));//6
printf("%d\n", sizeof(&arr[0]+1));//7

结果:
1.6byte;sizeof(arr)表示整个数组的大小=6*sizeof(char)=6
2.4/8byte;sizeof后面括号内不止有数组名,所以该数组名代表首元素地址而非整个数组,首元素地址+0=首元素地址,是地址就是4/8byte
3.1byte;arr是首元素地址,*arr表示对首元素地址解引用找到首元素,首元素类型为char,所以sizeof(char)=1
4.1byte;arr[1]是第二个元素,元素类型为char,所以sizeof(char)=1
5.4/8byte;&arr表示取出的是整个数组的地址,是地址就是4/8byte
6.4/8byte;&arr表示取出的是整个数组的地址,&arr+1表示跳过整个数组后的地址(如上图),是地址就是4/8byte
7.4/8byte;&arr[0]表示取出首元素地址,+1表示第二个元素的地址,是地址就是4/8byte

2.2

char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));//1
printf("%d\n", strlen(arr + 0));//2
printf("%d\n", strlen(*arr));//3
printf("%d\n", strlen(arr[1]));//4
printf("%d\n", strlen(&arr));//5
printf("%d\n", strlen(&arr + 1));//6
printf("%d\n", strlen(&arr[0] + 1));//7

结果:
1.随机值;strlen计算的是’\0’之前的字符个数,arr是首元素地址,strlen(arr)表示从首元素开始,一直向后直至找到’\0’,由于数组arr中没有’\0’,所以strlen一直会找到数组外我们不确定的某一位置停下,所以为随机值
2.随机值;arr+0表示的是首元素地址,然后同上
3.错误(如下图);arr表示的是首元素地址,* arr表示对首元素地址解引用找到首元素’a’,字符在内存中存储的是字符的ASCII码值,a的ASCII码值=97。strlen函数的参数为const char * str是指针,站在strlen的角度,是将实参’a’–97当作地址,直接进行访问,这是非法访问,会报错
4.错误(如下图);同3
5.随机值;&arr的类型为char(*)[6],而strlen函数的参数类型为const char * ,所以将&arr强制类型转化为const char * 类型即为首元素地址,然后同1
6.随机值;&arr+1的类型为char( *)[6],然后同5
7.随机值;&arr[0] + 1是第二个元素的地址,然后同1
在这里插入图片描述

2.3

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//1
printf("%d\n", sizeof(arr+0));//2
printf("%d\n", sizeof(*arr));//3
printf("%d\n", sizeof(arr[1]));//4
printf("%d\n", sizeof(&arr));//5
printf("%d\n", sizeof(&arr+1));//6
printf("%d\n", sizeof(&arr[0]+1));//7

结果:
1.7byte;arr数组里面的元素实际为 ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘\0’,sizeof(数组名)=整个数组所占空间的大小=7*sizeof(char)=7
2.4/8byte;sizeof里面不止有arr,所以此时的arr是首元素地址,arr+0也是首元素地址,是地址就是4/8byte
3.1byte;sizeof里面不止有arr,所以此时的arr是首元素地址,再对地址进行解引用找到首元素,sizeof(首元素)=1byte
4.1byte;
5.4/8byte;&arr表示取出的是整个数组的地址,是地址就是4/8byte
6.4/8byte;&arr表示取出的是整个数组的地址,&arr+1表示跳过整个数组后的地址,是地址就是4/8byte
7.4/8byte;&arr[0]表示取出首元素地址,+1表示第二个元素的地址,是地址就是4/8byte

2.4

char arr[] = "abcdef";
printf("%d\n", strlen(arr));//1
printf("%d\n", strlen(arr+0));//2
printf("%d\n", strlen(*arr));//3
printf("%d\n", strlen(arr[1]));//4
printf("%d\n", strlen(&arr));//5
printf("%d\n", strlen(&arr+1));//6
printf("%d\n", strlen(&arr[0]+1));//7

结果:
1.6byte;arr数组里面的元素实际为 ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘\0’,strlen计算的是’\0’之前的元素个数,arr是首元素地址,所以从首元素开始往后数,直到遇见’\0’停止,‘\0’之前有6个元素
2.6byte;arr数组里面的元素实际为 ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,’\0’,strlen计算的是’\0’之前的元素个数,arr+0表示的是首元素地址,所以从首元素开始往后数,直到遇见’\0’停止,‘\0’之前有6个元素
3.错误;arr表示的是首元素地址,* arr表示对首元素地址解引用找到首元素’a’,字符在内存中存储的是字符的ASCII码值,a的ASCII码值=97。strlen函数的参数为const char * str是指针,站在strlen的角度,是将实参’a’–97当作地址,直接进行访问,这是非法访问,会报错
4.错误;arr[1]表示的是第二个元素’b’,字符在内存中存储的是字符的ASCII码值,b的ASCII码值=98。strlen函数的参数为const char * str是指针,站在strlen的角度,是将实参’b’–98当作地址,直接进行访问,这是非法访问,会报错
5.6byte;&arr的类型为char(*)[6],而strlen函数的参数类型为const char * ,所以将&arr强制类型转化为const char * 类型即为首元素地址,然后同1
6.随机值;&arr+1的类型为char( *)[6],表示跳过整个数组后的地址,然后同5
7.5byte;&arr[0] + 1是第二个元素的地址,然后同1

2.5

char *p = "abcdef";
printf("%d\n", sizeof(p));//1
printf("%d\n", sizeof(p+1));//2
printf("%d\n", sizeof(*p));//3
printf("%d\n", sizeof(p[0]));//4
printf("%d\n", sizeof(&p));//5
printf("%d\n", sizeof(&p+1));//6
printf("%d\n", sizeof(&p[0]+1));//7

结果:
1.4/8byte;“abcdef”是常量字符串,指针变量p里面存的是字符’a’的地址,而非整个常量字符串的地址。是指针(地址)就是4/8byte
2.4/8byte;“abcdef”是常量字符串,指针变量p里面存的是字符’a’的地址,而非整个常量字符串的地址,p+1指向的是字符’a’的下一位即字符’b’,是指针(地址)就是4/8byte
3.1byte;指针变量p里面存的是字符’a’的地址,所以对p解引用找到字符’a’,a所占空间大小为1byte
4.1byte;p[0]= * (p+0)=‘a’,a所占空间大小为1byte
5.4/8byte;sizeof里面的是指针变量的地址,是指针(地址)就是4/8byte
6.4/8byte;&p+1表示跳过指针变量p的下一个地址,是地址就是4/8byte
7.4/8byte;&p[0]+1==& * (p+0)+1==字符’b’的地址,是地址就是4/8byte

2.6

char *p = "abcdef";
printf("%d\n", strlen(p));//1
printf("%d\n", strlen(p+1));//2
printf("%d\n", strlen(*p));//3
printf("%d\n", strlen(p[0]));//4
printf("%d\n", strlen(&p));//5
printf("%d\n", strlen(&p+1));//6
printf("%d\n", strlen(&p[0]+1));//7

结果:
1.6byte;常量字符串在结尾处有一个隐藏的’\0’,所以常量字符串实际为"abcdef\0",指针变量p里面存的是字符’a’的地址,strlen计算的是’\0’之前的元素个数,所以从字符’a’开始往后数,直到遇见’\0’停止,‘\0’之前有6个元素
2.5byte;p+1指向的是字符’a’的下一位即字符’b’,从字符’b’开始往后数,直到遇见’\0’停止,‘\0’之前有5个元素
3.错误;指针变量p里面存的是字符’a’的地址,对p解引用找到字符’a’,字符在内存中存储的是字符的ASCII码值,a的ASCII码值=97。strlen函数的参数为const char * str是指针,站在strlen的角度,是将实参’a’–97当作地址,直接进行访问,这是非法访问,会报错
4.错误;p[0]== * (p+0)== ‘a’,站在strlen的角度,是将实参’a’–97当作地址,直接进行访问,这是非法访问,会报错
5.随机值;&p表示取出指针变量p的地址,从指针变量p开始往后数,直到遇见’\0’停止,但是我们并不知道什么时候能遇见’\0’,所以为随机值
6.随机值;&p+1表示跳过指针变量p后的地址,从跳过指针变量p后的地址所存的字符开始往后数,直到遇见’\0’停止,但是我们并不知道什么时候能遇见’\0’,所以为随机值
7.5byte;&p[0]+1 == & * (p+0)+1==字符’b’的地址,从字符’b’开始往后数,直到遇见’\0’停止,'\0’之前有5个元素


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

相关文章:

【C语言】指针和数组笔试题解析

大家好,我是苏貝,本篇博客带大家了解指针和数组笔试题解析,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 1.前言2.一维数组2.字符数组2.12.22.32.42.52.6 1.前言 本篇文章是讲述在不同数…...

Vue的模板语法(下)

一.事件处理 事件修饰符 Vue通过由点(.)表示的指令后缀来调用修饰符, .stop, .prevent,.capture,.self,.once .stop:阻止事件冒泡。当一个元素触发了事件,并且该元素包含嵌套的父元素时&#…...

Zookeeper客户端——I0Itec-zkClient

dubbo使用了zkClient而不是使用zookeeper本身的客户端与zookeeper进行交互,为什么呢? 先看看zookeeper本身自带的客户端的问题。 1)ZooKeeper的Watcher是一次性的,用过了需要再注册; 2) session的超时后…...

火山引擎 ByteHouse:ClickHouse 如何保证海量数据一致性

背景 ClickHouse是一个开源的OLAP引擎,不仅被全球开发者广泛使用,在字节各个应用场景中也可以看到它的身影。基于高性能、分布式特点,ClickHouse可以满足大规模数据的分析和查询需求,因此字节研发团队以开源ClickHouse为基础&…...

hashmap使用

hashmap作为dao对象存储数据库数据 list是把每一个数据库的字段都映射了,而hashmap则是唯一id:数据库字段作为key hashmap遍历方式 public class Main {//使用迭代器(Iterator)EntrySetpublic static void main(String[] args) {// 创建并赋…...

Centos7配置国内yum源

目录 备份原系统中的repo文件配置国内开源镜像重新生成yum缓存 备份原系统中的repo文件 cd /etc/yum.repos.d/mkdir repo_bakmv *.repo repo_bak/配置国内开源镜像 到网易和阿里开源镜像站点下载系统对应版本的repo文件 curl -O http://mirrors.aliyun.com/repo/Centos-7.re…...

C#中async/await的线程ID变化情况

一、简单的起步 Console.WriteLine($"主线程开始ID:{Thread.CurrentThread.ManagedThreadId}");//aawait Task.Delay(100);//cConsole.WriteLine($"主线程结束ID:{Environment.CurrentManagedThreadId}");//b 结果: …...

网络安全—黑客技术—自学笔记

目录梗概 一、自学网络安全学习的误区和陷阱 二、学习网络安全的一些前期准备 三、网络安全学习路线 四、学习资料的推荐 想自学网络安全(黑客技术)首先你得了解什么是网络安全!什么是黑客! 网络安全可以基于攻击和防御视角来…...

功夫再高也怕菜刀。多年经验,会独立开发的机器视觉工程师,技术太强,但是找工作能力差劲

功夫再高也怕菜刀,专业的事情交给专业的人去做。 今年7月份中旬的时候,遇到一位老朋友,向我咨询某公司的信息,其实我根本不了解这家公司的情况与实力,向他说了,抱歉,我查下,等我晚上…...

numpy的多项式函数: `poly1d`

Python numpy.poly1d() numpy.poly1d()函数有助于定义一个多项式函数。它使得在多项式上应用 "自然操作 "变得容易。 语法: numpy.poly1d (arr, root, var) 参数 : arr : [array_like] 多项式系数按照幂的递减顺序给出。如果第二个参数(根)被…...

Python灰帽编程——错误异常处理和面向对象

文章目录 1. 错误和异常1.1 基本概念1.1.1 Python 异常 1.2 检测(捕获)异常1.2.1 try except 语句1.2.2 捕获多种异常1.2.3 捕获所有异常 1.3 处理异常1.4 特殊场景1.4.1 with 语句 2. 内网主机存活检测程序2.1 scapy 模块2.1.1 主要功能2.1.2 scapy 安装…...

【20230919】win11无法删除Chrome注册表项

win11无法删除Chrome注册表项 删除以下注册表项发生错误: 计算机\HKEY_LOCAL_MACHINE\SOFTWAR\Google计算机\HKEY_CURRENT_USER\Software\Google 尝试了很多删除注册表方法(例如:编辑remove.reg文件),都不行。 无法…...

TCP/IP客户端和服务器端建立通信过程

客户端和服务器端建立通信过程 使用Qt提供的类进行基于TCP的套接字通信需要用到两个类: QTcpServer:服务器类,用于监听客户端连接以及和客户端建立连接。 QTcpSocket:通信的套接字类,客户端、服务器端都需要使用。服务…...

Python ---使用Fake库向clickhouse造数据小案例

每次insert太麻烦了 先在clickhosue中建表 test_user表 CREATE TABLE dwh.test_user (name String,age Int32,address String,phone String,email String ) ENGINE MergeTree() ORDER BY name; 此时表中暂无数据 用Python脚本来造一些数据 from faker import Faker from c…...

09MyBatisX插件

MyBatisX插件 在真正开发过程中对于一些复杂的SQL和多表联查就需要我们自己去编写代码和SQL语句,这个时候可以使用MyBatisX插件帮助我们简化开发 安装MyBatisX插件: File -> Settings -> Plugins -> 搜索MyBatisx插件搜索安装然后重启IDEA 跳转文件功能 由于一个项…...

使用 Messenger 跨进程通信

什么是Messenger Messenger 也是IPC的方案之一,是基于消息的跨进程通信。基于消息是什么意思?Handler是我们最常用的消息机制,所以 Messenger 对于使用者来说就像是使用 Handler。实际上 Messenger 就是 AIDL 的上层封装而已,它们…...

Spring Cloud Gateway

路由谓词工厂 Route Predicate Factory 1. The After Route Predicate Factory spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After2017-01-20T17:42:47.789-07:00[America/Denver]# 用日期时间匹配 2. The Before Route Pr…...

JVM 优化技术

文章目录 JVM 优化技术概述方法内联优化说明优点内联条件 栈帧之间数据共享说明优点栈帧之间数据共享条件 JVM 优化技术 概述 JVM常见的优化技术: 方法内联优化。栈帧之间数据共享。 方法内联优化 说明 方法内联(Method Inlining)是JVM…...

【MySQL系列】- MySQL自动备份详解

【MySQL系列】- MySQL自动备份详解 文章目录 【MySQL系列】- MySQL自动备份详解一、需求背景二、Windows mysql自动备份方法2.1 复制date文件夹备份实验备份环境创建bat直接备份脚本 2 .2 mysqldump备份成sql文件创建mysqldump备份脚本 2 .3 利用WinRAR对MySQL数据库进行定时备…...

指针笔试题讲解-----让指针简单易懂(2)

目录 回顾上篇重点 : 一.笔试题 ( 1 ) 二.笔试题 ( 2 ) 科普进制知识点 (1) 二进制 (2) 八进制 (3)十六进制 三.笔试题( 3 ) 四.笔试题( 4 ) 五.笔试题( 5 ) 六.笔试题( …...

接口测试中缓存处理策略

在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...