当前位置: 首页 > 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 ) 六.笔试题( …...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

PL0语法,分析器实现!

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

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...