经典数组和指针笔试题解析——C语言

【本节内容】

1. 数组和指针笔试题解析

2. 指针运算笔试题解析

1. 数组和指针笔试题解析

1.1 维数组

#include <stdio.h>
int main()
{int a[] = { 1,2,3,4 };printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(a + 0));printf("%zd\n", sizeof(*a));printf("%zd\n", sizeof(a + 1));printf("%zd\n", sizeof(a[1]));printf("%zd\n", sizeof(&a));printf("%zd\n", sizeof(*&a));printf("%zd\n", sizeof(&a + 1));printf("%zd\n", sizeof(&a[0]));printf("%zd\n", sizeof(&a[0] + 1));return 0;
}
解答:
//数组名的理解
//数组名一般表示数组首元素的地址
//但是有2个例外:
//1.sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节
//2.&数组名,数组名表示整个数组,取出的数组的地址
//除此之外,所有遇到的数组名都是数组首元素的地址
#include <stdio.h>
int main()
{int a[] = { 1,2,3,4 };//数组有四个元素,每个元素是int类型的数据printf("%zd\n", sizeof(a));//sizeof(数组名)计算的是整个数组的大小,所以大小是16printf("%zd\n", sizeof(a + 0));//a表示首元素的地址,a+0还是首元素的地址,x64环境下地址大小是8个字节,// x86环境下地址大小是4个字节,所以大小是4/8printf("%zd\n", sizeof(*a));//a表示的就是数组首元素的地址,*a就是首元素,大小就是4个字节printf("%zd\n", sizeof(a + 1)); //a表示的就是数组首元素的地址,a+1就是第二个元素的地址,x64环境下地址大小是8个字节,// x86环境下地址大小是4个字节,所以大小是4/8printf("%zd\n", sizeof(a[1]));//a[1]是数组第二个元素,大小是4个字节printf("%zd\n", sizeof(&a));//&a取出的数组的地址,但是数组的地址也是地址,是地址,大小就是4/8个字节printf("%zd\n", sizeof(*&a));//sizeof(a)-16//1.&和*抵消//2.&a的类型是数组指针,int(*)[4],*&就是对数组指针解引用访问一个数组的大小,是16个字节printf("%zd\n", sizeof(&a + 1));//&a+1是跳过整个数组后的一个地址,是地址,大小就是4/8个字节printf("%zd\n", sizeof(&a[0]));//&a[0]是数组第一个元素的地址,大小就是4/8个字节printf("%zd\n", sizeof(&a[0] + 1));//&a[0]是数组第一个元素的地址,大小就是4/8个字节return 0;
}

1.2 字符数组

代码1:
#include <stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%zd\n", sizeof(arr));printf("%zd\n", sizeof(arr + 0));printf("%zd\n", sizeof(*arr));printf("%zd\n", sizeof(arr[1]));printf("%zd\n", sizeof(&arr));printf("%zd\n", sizeof(&arr + 1));printf("%zd\n", sizeof(&arr[0] + 1));return 0;
}
解答:
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%zd\n", sizeof(arr));//计算整个数组的大小,有6个char类型的字符,所以大小为6个字节printf("%zd\n", sizeof(arr + 0));//arr+0是数组首元素的地址,地址的大小是4/8个字节printf("%zd\n", sizeof(*arr));//*arr是数组的首元素,这里计算的是首元素的大小 1printf("%zd\n", sizeof(arr[1]));//数组下标为一的元素的大小printf("%zd\n", sizeof(&arr));//&arr - 是数组的地址,数组的地址也是地址,是地址就是4/8个字节printf("%zd\n", sizeof(&arr + 1));//&arr+1,跳过整个数组,指向了数组的后边,4/8printf("%zd\n", sizeof(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 4/8return 0;
}
 代码2:
#include <stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };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));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));return 0; 
}
解答:
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));//随机值printf("%d\n", strlen(arr + 0));//随机值//'a'-97//printf("%d\n", strlen(*arr));//err//                   //'b'-98//printf("%d\n", strlen(arr[1]));//errprintf("%d\n", strlen(&arr));//随机值printf("%d\n", strlen(&arr + 1));//随机值printf("%d\n", strlen(&arr[0] + 1));//随机值return 0;
}

代码3:
#include <stdio.h>
int main()
{char arr[] = "abcdef";printf("%zd\n", sizeof(arr));printf("%zd\n", sizeof(arr + 0));printf("%zd\n", sizeof(*arr));printf("%zd\n", sizeof(arr[1]));printf("%zd\n", sizeof(&arr));printf("%zd\n", sizeof(&arr + 1));printf("%zd\n", sizeof(&arr[0] + 1));return 0;
}
解答:
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";printf("%zd\n", sizeof(arr));//计算字符串大小(包括\0),长度为7printf("%zd\n", sizeof(arr + 0));//arr+0是数组首元素的地址,地址的大小是4/8个字节printf("%zd\n", sizeof(*arr));//*arr是数组的首元素,这里计算的是首元素的大小 1printf("%zd\n", sizeof(arr[1]));//1printf("%zd\n", sizeof(&arr));//&arr - 是数组的地址,数组的地址也是地址,是地址就是4/8个字节printf("%zd\n", sizeof(&arr + 1));//&arr+1,跳过整个数组,指向了数组的后边,4/8printf("%zd\n", sizeof(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 4/8return 0;
}
代码4:
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";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));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));return 0;
}
解答:
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";printf("%zd\n", strlen(arr));//arr也是数组首元素的地址 6printf("%zd\n", strlen(arr + 0));//arr + 0是数组首元素的地址,6printf("%zd\n", strlen(*arr));//?传递是'a'-97,//errprintf("%zd\n", strlen(arr[1]));//?'b'-98//errprintf("%zd\n", strlen(&arr));//6, &arr虽然是数组的地址,但是也是指向数组的起始位置printf("%zd\n", strlen(&arr + 1));//随机值printf("%zd\n", strlen(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 - 5return 0;
}
代码5:
#include <stdio.h>
int main()
{
char *p = "abcdef";
printf("%zd\n", sizeof(p));
printf("%zd\n", sizeof(p+1));
printf("%zd\n", sizeof(*p));
printf("%zd\n", sizeof(p[0]));
printf("%zd\n", sizeof(&p));
printf("%zd\n", sizeof(&p+1));
printf("%zd\n", sizeof(&p[0]+1));
return 0;
}
解答:
#include <stdio.h>
int main()
{char* p = "abcdef";printf("%zd\n", sizeof(p));//4/8 计算的指针变量的大小printf("%zd\n", sizeof(p + 1));//p + 1是'b'的地址,是地址大小就是4/8个字节printf("%zd\n", sizeof(*p));//*p就是'a',大小是1个字节printf("%zd\n", sizeof(p[0]));//p[0]--> *(p+0) - *p //1字节printf("%zd\n", sizeof(&p));//&p也是地址,是指针变量p的地址,大小也是4/8个字节printf("%zd\n", sizeof(&p + 1));//&p + 1是指向p指针变量后面的空间,也是地址,是4/8个字节printf("%zd\n", sizeof(&p[0] + 1));//&p[0]+1是'b'的地址,是地址就是4/8个字节return 0;
}
代码6:
#include <stdio.h>
#include <string.h>
int main()
{char* p = "abcdef";printf("%d\n", strlen(p));printf("%d\n", strlen(p + 1));printf("%d\n", strlen(*p));printf("%d\n", strlen(p[0]));printf("%d\n", strlen(&p));printf("%d\n", strlen(&p + 1));printf("%d\n", strlen(&p[0] + 1));return 0;
}
解答:
#include <stdio.h>
#include <string.h>
int main()
{char* p = "abcdef";printf("%zd\n", strlen(p));//6printf("%zd\n", strlen(p + 1));//5printf("%zd\n", strlen(*p));//errprintf("%zd\n", strlen(p[0]));//p[0]--*(p+0)-->*p //errprintf("%zd\n", strlen(&p));//随机值printf("%zd\n", strlen(&p + 1));//随机值printf("%zd\n", strlen(&p[0] + 1));//5return 0;
}

1.3 二维数组

代码:
#include <stdio.h>
int main()
{int a[3][4] = { 0 };printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(a[0][0]));printf("%zd\n", sizeof(a[0]));printf("%zd\n", sizeof(a[0] + 1));printf("%zd\n", sizeof(*(a[0] + 1)));printf("%zd\n", sizeof(a + 1));printf("%zd\n", sizeof(*(a + 1)));printf("%zd\n", sizeof(&a[0] + 1));printf("%zd\n", sizeof(*(&a[0] + 1)));printf("%zd\n", sizeof(*a));printf("%zd\n", sizeof(a[3]));return 0;
}
解答:
#include <stdio.h>
int main()
{//二维数组也是数组,之前对数组名理解也是适合int a[3][4] = { 0 };printf("%zd\n", sizeof(a));//12*4 = 48个字节,数组名单独放在sizeof内部printf("%zd\n", sizeof(a[0][0]));//4printf("%zd\n", sizeof(a[0]));//a[0]是第一行这个一维数组的数组名,数组名单独放在sizeof内部了//计算的是第一行的大小,单位是字节,16个字节printf("%zd\n", sizeof(a[0] + 1));//a[0]第一行这个一维数组的数组名,这里表示数组首元素//也就是a[0][0]的地址,a[0] + 1是a[0][1]的地址 4/8printf("%zd\n", sizeof(*(a[0] + 1)));//a[0][1] - 4个字节printf("%zd\n", sizeof(a + 1));//a是二维数组的数组名,但是没有&,也没有单独放在sizeof内部//所以这里的a是数组收元素的地址,应该是第一行的地址,a+1是第二行的地址//大小也是4/8 个字节printf("%zd\n", sizeof(*(a + 1)));//*(a + 1) ==> a[1] - 第二行的数组名,单独放在sizeof内部,计算的是第二行的大小//16个字节printf("%zd\n", sizeof(&a[0] + 1));//&a[0]是第一行的地址,&a[0]+1就是第二行的地址,4/8printf("%zd\n", sizeof(*(&a[0] + 1)));//访问的是第二行,计算的是第二行的大小,16个字节//int(*p)[4] = &a[0] + 1;//printf("%zd\n", sizeof(*a));//这里的a是第一行的地址,*a就是第一行,sizeof(*a)计算的是第一行的大小-16//*a --> *(a+0) --> a[0]printf("%zd\n", sizeof(a[3]));//这里不存在越界//因为sizeof内部的表达式不会真实计算的//计算的是第四行的大小-16return 0;
}
数组名的意义:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。

2. 指针运算笔试题解析

2.1 题目1:

#include <stdio.h>
int main()
{int a[5] = { 1, 2, 3, 4, 5 };int *ptr = (int *)(&a + 1);printf( "%d,%d", *(a + 1), *(ptr - 1));return 0;
}
//程序的结果是什么?
运行结果:

解析:

2.2 题目2  

//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥?
struct Test
{int Num;char *pcName;short sDate;char cha[2];short sBa[4];
}*p = (struct Test*)0x100000;
int main()
{printf("%p\n", p + 0x1);printf("%p\n", (unsigned long)p + 0x1);printf("%p\n", (unsigned int*)p + 0x1);return 0;
}
运行结果:

解析:
//在X86环境下
//假设结构体的大小是20个字节
//程序输出的结果是啥?
#include <stdio.h>
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}* p = (struct Test*)0x100000;
//
//指针+整数
//
int main()
{printf("%x\n", p + 0x1); //0x100000+20 == 0x100014printf("%x\n", (unsigned long)p + 0x1);//0x100000+1 == 0x100001printf("%x\n", (unsigned int*)p + 0x1);//0x100000+1 == 0x100004return 0;
}

2.3 题目3

#include <stdio.h>
int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5) };int *p;p = a[0];printf( "%d", p[0]);return 0;
}
运行结果:

解析:

2.4 题目4

//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{int a[5][5];int(*p)[4];p = a;printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);return 0;
}
运行结果:

解析: 

2.5 题目5 

#include <stdio.h>
int main()
{int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int *ptr1 = (int *)(&aa + 1);int *ptr2 = (int *)(*(aa + 1));printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));return 0;
}
运行结果: 

解析:

2.6 题目6

#include <stdio.h>
int main()
{char *a[] = {"work","at","alibaba"};char**pa = a;pa++;printf("%s\n", *pa);return 0;
}
运行结果:

解析:

PS:看到这里了,码字不易,给个一键三连鼓励一下吧!有不足或者错误之处欢迎在评论区指出!  

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

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

相关文章

自动从Android上拉取指定文件

需求场景 利用Mac中的脚本编辑器实现从连接的Android设备中获取指定的文件。 环境 macOS Monterey 版本 12.7.1脚本编辑器adb环境&#xff08;如果没有的话&#xff0c;可以网上搜下Mac配置adb&#xff09; 实现方案 1、打开脚本编辑器&#xff1b; 2、新建一个脚本文件&…

【string一些函数用法的补充】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 string类对象的修改操作 我们来看 c_str 返回c格式的字符串的操作&#xff1a; 我们来看 rfind 和 substr 的操作&#xff1a; string类非成员函数 我们来看 r…

如果利用AOP/Aspect来修改方法的入参

问题描述&#xff1a; 最近项目代码过三方测试&#xff08;国企项目&#xff09;&#xff0c;在一系列代码扫描审计检查下&#xff0c;代码发现一部分修改&#xff0c;例如请求参数发生了编码/加密&#xff0c;导致后台需要对请求的参数进行解码/解密&#xff0c;后端那么接口&…

Material UI 5 学习03-Text Field文本输入框

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Text Field文本输入框 一、最基本的本文输入框1、基础示例2、一些表单属性3、验证 二、多行文本 一、最基本的本文输入框 1、基础示例 import {Box, TextField} from "…

【嵌入式】字体极限瘦身术:Fontmin在嵌入式UI中的魔法应用(附3500常用汉字)

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方…

C++类和对象一

#include <iostream> using namespace std;//设计一个学生类 class CStudent {public: //公有成员void InputData(){cout << "请输入学号";cin >> sno;cout << "请输入姓名";cin >> sname;cout << "请输入分…

Go——数组

Golang Array和以往认知的数组有很大的。 数组是同一种数据类型的固定长度的序列。数组定义&#xff1a;var a[len] int&#xff0c;比如&#xff1a;var a [5]int&#xff0c;数组长度必须是常量&#xff0c;且类型的组成部分。一旦定义&#xff0c;长度不能变。长度是数组类…

微服务之商城系统

文章目录 一、商城系统建立之前的一些配置1、nacos2、Mysql3、consul【暂时不使用consul注册服务】这个可以跳过4、redis 二、grpc环境搭建三、微服务架构使用的protobuf1、查看proto的版本号2、安装protoc-gen-go和protoc-gen-go-grpc3、生成protobuff以及grpc的文件 一、商城…

定档!首届百度智能云全球生态大会,4月9日成都见!

为了加快人工智能的发展步伐&#xff0c;进一步推动大模型产业的实际落地&#xff0c;促进AI原生应用的全面繁荣&#xff0c;百度智能云将于2024年4月9日在成都举办首届“百度智能云GENERATE全球生态大会”。 大会将带来百度智能云在大模型时代的全新生态战略&#xff0c;以及针…

使用 Docker 部署 Next Terminal 轻量级堡垒机

1&#xff09;Next Terminal 介绍 官网&#xff1a;https://next-terminal.typesafe.cn/ GitHub&#xff1a;https://github.com/dushixiang/next-terminal 想必经常玩服务器的都了解过 堡垒机&#xff0c;类似于跳板机&#xff0c;但与跳板机的侧重点不同。堡垒机的主要功能是…

【SSM】任务列表案例 基本CRUD SSM整合

文章目录 一、案例功能预览二、接口分析三、前端工程导入四、后端程序实现和测试4.1 准备4.2 功能实现4.2.1 分页查询显示4.2.2 添加计划4.2.2 删除计划4.2.3 修改计划 4.3 前后联调 一、案例功能预览 Github 地址 &#xff1a; ssm-integration-part 二、接口分析 学习计划…

Python 合并两张图片

发现一个很有意思的图片处理包PIL&#xff0c;可以将两张图片合并成一张&#xff0c;而且很好看。代码如下 from PIL import Image# 打开两张图片 image1 Image.open("1.jpg").convert("RGBA") image2 Image.open("2.jpg").convert("RGB…

【数据结构与算法】:插入排序与希尔排序

&#x1f525;个人主页&#xff1a; Quitecoder &#x1f525;专栏: 数据结构与算法 欢迎大家来到初阶数据结构的最后一小节&#xff1a;排序 目录 1.排序的基本概念与分类1.1什么是排序的稳定性&#xff1f;1.2内排序与外排序内排序外排序 2.插入排序2.1实现插入排序2.3稳定性…

C#操作像素替换图片中的指定颜色

待处理的图片&#xff0c;其特征是包含有限数量颜色&#xff0c;不同的颜色相互交叉使用&#xff0c;相同颜色并未完全连贯&#xff0c;需要将图片中的指定颜色替换为另一颜色。虽然很多图片处理工具都支持类似操作&#xff0c;最后还是自己动手编写简单的处理程序。   程序的…

grafana table合并查询

注&#xff1a;本文基于Grafana v9.2.8编写 1 问题 默认情况下table展示的是一个查询返回的多个field&#xff0c;但是我想要的数据在不同的metric上&#xff0c;比如我需要显示某个pod的读写IO&#xff0c;但是读和写这两个指标存在于两个不同的metirc&#xff0c;需要分别查…

Kotlin/Java中String的equals和==

Kotlin/Java中String的equals和 在Java中&#xff0c;如果定义一个常量String和new出一个String对象&#xff0c;是不同的&#xff1a; String s1 "zhang" String s2 new String("zhang") 因为在Java看来&#xff0c;s1只是一个常量&#xff0c;会放在…

ruoyi-vue插件集成websocket

链接&#xff1a;插件集成 | RuoYi WebSocketServer.java&#xff1a;补充代码 /*** 此为广播消息* param message 消息内容*/public void sendAllMessage(String message) {LOGGER.info("【websocket.sendAllMessage】广播消息:"message);try {for(String sessionI…

爬虫案例1

通过get请求直接获取电影信息 目标页面: https://spa6.scrape.center/在network中可以看到是通过Ajax发送的请求&#xff0c;这个请求在postman中也可以直接请求成功&#xff0c;这只是一个用来练习爬虫的&#xff0c;没有达到js逆向的过程&#xff0c;需要通过分析js 代码来获…

GPT出现Too many requests in 1 hour. Try again later.

换节点 这个就不用多说了&#xff0c;你都可以上GPT帐号了&#xff0c;哈…… 清除cooki 然后退出账号&#xff0c;重新登录即可

考研失败, 学点Java打小工——Day3

1 编码规范——卫语句 表达异常分支时&#xff0c;少用if-else方式。   比如成绩判断中对于非法输入的处理&#xff1a; /*>90 <100 优秀>80 <90 良好>70 <80 一般>60 <70 及格<60 不及格*/Testpu…