【C语言进阶(4)】指针和数组笔试题

文章目录

  • Ⅰ 一维数组
  • Ⅱ 字符数组
    • 题型 1
    • 题型 2
    • 题型 3
  • Ⅲ 二维数组

数组名的意义

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示的是整个数组,取出的是整个数组的地址。
  3. 除了上述两种情况之外,所有的数组名表示的都是数组首元素的地址。

Ⅰ 一维数组

int a[] = { 1,2,3,4 };printf("%zd\n", sizeof(a));			//16		
//sizeof(数组名),计算的是整个数组的大小printf("%zd\n", sizeof(a + 0));		//4/8	
//此处的 a + 0 表示数组首元素的地址,是地址就是 4/8 个字节printf("%zd\n", sizeof(*a));		//4
//*a 中的 a 是数组首元素的地址,*a 就是对首元素的地址解引用;
//找到的就是首元素,首元素的大小就是 4 个字节printf("%zd\n", sizeof(a + 1));		//4/8
//a + 1 表示数组第二个元素(2)的地址,所以计算结果是 4/8 个字节printf("%zd\n", sizeof(a[1]));		//4
//计算第二个元素的大小printf("%zd\n", sizeof(&a));		//4/8
//&a 取出的是整个数组的地址,数组的地址它还是个地址,是地址就是 4/8 个字节printf("%zd\n", sizeof(*&a));		//16
//* 与 & 相互抵消,就成了 sizeof(a) 计算整个数组的大小printf("%zd\n", sizeof(&a + 1));	//4/8
//&a 取出整个数组的地址,&a 的类型 是 int(*)[4];
//&a + 1是从数组 a 的地址向后,跳过了一个 4 个整型元素的数组的大小;
//&a + 1 还是地址,是地址就是 4/8 个字节printf("%zd\n", sizeof(&a[0]));		//4/8
//计算的是第一个元素的地址printf("%zd\n", sizeof(&a[0] + 1));	//4/8
//&a[0] + 1 是第二个元素的地址

Ⅱ 字符数组

题型 1

char arr[] = { 'a','b','c','d','e','f' };//整个数组 6 个元素

1. 用 sizeof 求结果

char arr[] = { 'a','b','c','d','e','f' };printf("%zd\n", sizeof(arr));			//6
//整个数组的大小为 6 个字节printf("%zd\n", sizeof(arr + 0));		//4/8
//不是 sizeof(单个数组名)这种情况,arr + 0 表示首元素地址,地址都是 4/8 个字节printf("%zd\n", sizeof(*arr));			//1
//*arr 就是数组的首元素,大小事 1 字节printf("%zd\n", sizeof(arr[1]));		//1
//计算的是数组第二个元素的大小,'b' 的大小为 1 字节printf("%zd\n", sizeof(&arr));			//4/8
//计算整个数组的地址,是地址就是 4/8 字节printf("%zd\n", sizeof(&arr + 1));		//4/8
//&arr + 1 指向了 'f' 的后面,但它还是个地址printf("%zd\n", sizeof(&arr[0] + 1));	//4/8
//计算第二个元素的地址,地址的大小都是 4/8 个字节

2. 用 strlen 求结果

char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));			随机值
//strlen 会计算 '\0' 之前有几个字符,arr 里面并没有 '\0';
//strlen 会一直往后找 '\0',直到碰巧碰到 '\0' 才停止工作。printf("%d\n", strlen(arr + 0));		随机值
//arr 还是首元素地址,指向 'a',这玩意不是 '\0',strlen 自然要往后猛找 '\0'printf("%d\n", strlen(*arr));			程序报错(野指针问题)
//站在 strlen 这个函数的角度看,传给它的都应该是地址,然而 *arr 是 'a'(97);
//相当于 strlen(97),把 97 作为一个地址传给 strlen,那肯定会出 BUGprintf("%d\n", strlen(arr[1]));			程序报错(野指针问题)
//和上面类似,相当于 strlen(98),把 98 当做地址传给 strlen,不出 BUG 才有问题printf("%d\n", strlen(&arr));			随机值
//数组的地址从 'a' 开始,还是没有 '\0',strlen 又要吭哧吭哧往后找了printf("%d\n", strlen(&arr + 1));		随机值 - 6
//传过去的地址指向 'f' 后面,从 'f' 后面开始往后找 '\0',那必定是个随机值了。
//又因为是从 'f' 后面开始往后找,没有算入 arr 数组内的 6 个字符所以随机值会少 6printf("%d\n", strlen(&arr[0] + 1));	随机值 -1
//从 'b' 的地址处开始往后找,没有算入 'a' 这一个字符的个数

题型 2

char arr[] = "abcdef";//这个数组有 a b c d e f \0 7 个元素

1. 用 sizeof 求结果

char arr[] = "abcdef";printf("%zd\n", sizeof(arr));			//7
//'f' 的后面藏了个 '\0',所以整个数组的大小是 7 个字节printf("%zd\n", sizeof(arr + 0));		//4/8
//sizeof 内不是单个数组名这种情况,所以 arr + 0 表示的首元素的地址,地址就是 4/8 字节
printf("%zd\n", sizeof(*arr));			//1
//arr 是首元素地址,对首元素地址解引用就得到了 'a',这个字符的大小就是 1 字节printf("%zd\n", sizeof(arr[1]));		//1
//arr[1] 是字符 'b','b' 的大小位 1 字节printf("%zd\n", sizeof(&arr));			//4/8
//这个数组的地址还是地址,是地址就是 4/8 字节printf("%zd\n", sizeof(&arr + 1));		//4/8
//&arr + 1 指向了 '\0' 的后面,即使指向 '\0' 后面它还是个地址printf("%zd\n", sizeof(&arr[0] + 1));	//4/8
//&arr[0] 是 a 的地址,a 的地址 + 1,成了 b 的地址,来来去去算的还是地址

2. 用 strlen 求结果

char arr[] = "abcdef";printf("%d\n", strlen(arr));			//6
//这个数组里 '\f' 的后面就有 '\0' 了printf("%d\n", strlen(arr + 0));		//6
//从首元素地址开始往后找 '\0'printf("%d\n", strlen(*arr));			程序错误
//strlen(*arr) -> strlen ('a') -> strlen(97),把 97 作为地址肯定出问题printf("%d\n", strlen(arr[1]));			程序错误
//strlen(98),将 98 作为地址传给 strlenprintf("%d\n", strlen(&arr));			//6
//&arr 整个数组的地址也是从 'a' 的地址开始的;
//还是传了 'a' 的地址给 strlen,往后找 '\0' 的结果是一样的printf("%d\n", strlen(&arr + 1));		随机值
//从 '\0' 后面开始找 '\0',那什么时候碰到 '\0' 就全看运气了printf("%d\n", strlen(&arr[0] + 1));	//5
//从 'b' 开始往后找 '\0'

题型 3

char* p = "abcdef";//将常量字符串首字符 a 的地址赋给 p

在这里插入图片描述

1. 用 sizeof 求结果

char* p = "abcdef";printf("%zd\n", sizeof(p));			//4/8
//p 是个指针,指针不管指向的是什么东西,指针本身的大小都是 4/8 字节printf("%zd\n", sizeof(p + 1));		//4/8
//让指针 + 1 指向了 'b' ,p + 1 他还是个指针printf("%zd\n", sizeof(*p));		//1
//计算 p 指向的字符 'a' 的大小printf("%zd\n", sizeof(p[0]));		//1
//p[0] <--> *(p + 0) <--> *pprintf("%zd\n", sizeof(&p));		//4/8
//虽然是取出 p 的地址,相当于二级指针,二级指针也是个指针,printf("%zd\n", sizeof(&p + 1));	//4/8
//&p + 1 还是个地址,不过这个地址指向了 '\0' 的后面printf("%zd\n", sizeof(&p[0] + 1));	//4/8
//计算的是 'b' 的地址

2. 用 strlen 求结果

char* p = "abcdef";printf("%d\n", strlen(p));			//6
//p 里存着的是 'a' 的地址,从 'a' 开始往后找 '\0'printf("%d\n", strlen(p + 1));		//5
//p + 1 是 'b' 的地址,从 'b' 开始找 '\0'printf("%d\n", strlen(*p));			程序错误
//*p == 'a',strlen(*p) <--> strlen('a') <--> strlen(97)printf("%d\n", strlen(p[0]));		程序错误
//p[0] <--> *p,和上面情况一样printf("%d\n", strlen(&p));			随机值
//&p 是 p 本身的地址,和常量字符串的地址完全不是一码事,从 p 的地址开始往后随机找 '\0'printf("%d\n", strlen(&p + 1));		随机值
//从 p 之后往后找 '\0',printf("%d\n", strlen(&p[0] + 1));	//5
//&p[0] + 1 指向 'b',从 'b' 开始往后找 '\0'

Ⅲ 二维数组

int a[3][4] = { 0 };					//该二维数组有 12 个元素

在这里插入图片描述

int a[3][4] = { 0 };					//该二维数组有 12 个元素printf("%zd\n", sizeof(a));				//48
//数组名单独放在 sizeof 内部,计算的是整个数组的大小,为 3 * 4 * 4 = 48 字节printf("%zd\n", sizeof(a[0][0]));		//4
//计算第一行第一列的元素的大小,printf("%zd\n", sizeof(a[0]));			//16
//a[0] 表示的是二维数组的第一行,第一行的大小为 4 * 4 = 16 个字节 printf("%zd\n", sizeof(a[0] + 1));		//4/8
//此处的 a[0] 不是单独放在 sizeof 内部,此时 a[0] 表示的是首行首列的地址
//所以 a[0] + 1 <--> &a[0][0] + 1 <--> &a[0][1],这玩意就是个地址printf("%zd\n", sizeof(*(a[0] + 1)));	//4
//*(a[0] + 1) <--> *&a[0][1],* 和 & 相互抵消,就是计算 a[0][1] 的大小printf("%zd\n", sizeof(a + 1));			//4/8
//a 虽然是二维数组的地址,但是并没有单独放在 sizeof 内部,也没取地址;
//此时 a 表示首元素的地址,二维数组的首元素是它的第一行,a 就是第一行的地址;
//a + 1 就是跳过第 1 行,表示的是第二行的地址,是地址就是 4/8 字节printf("%zd\n", sizeof(*(a + 1)));		//16
//对第二行的地址解引用,相当于访问整个第二行,第二行的大小当然是 16 个字节了printf("%zd\n", sizeof(&a[0] + 1));		//4/8
//&a[0] 表示整个第一行的地址,&a[0] + 1 表示第二行的地址,与sizeof(a + 1) 等同printf("%zd\n", sizeof(*(&a[0] + 1)));	//16
//对第二行的地址解引用,访问整个第二行,与 sizeof(*(a + 1)) 等同printf("%zd\n", sizeof(*a));			//16
//a 没有单独放在 sizeof 内部,所以此时的 a 表示的是首元素(第一行)的地址
//*a 相当于访问整个第一行,第一行的大小为 4 * 4 = 16 字节printf("%zd\n", sizeof(a[3]));			//16
//虽然第 4 行不存在,但第 4 行的类型和前 3 行也没什么区别;
//对于 sizeof 来说,只要知道类型就能计算大小,不会真的去访问越界得内容

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

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

相关文章

2023年03月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;和数 给定一个正整数序列&#xff0c;判断其中有多少个数&#xff0c;等于数列中其他两个数的和。 比如&#xff0c;对于数列1 2 3 4, 这个问题的答案就是2, 因为3 2 1, 4 1 3。 时间限制&#xff1a;10000 内存限制&#xff1a;65536 输入 共两行&#x…

AMBA总线协议(6)——AHB(四):传输细节

一、前言 在之前的文章中&#xff0c;我们已经讲述了AHB传输中的两种情况&#xff0c;基本传输和猝发传输。我们进行一个简单的回顾&#xff0c;首先&#xff0c;开始一次传输之前主机需要向仲裁器申请获得总线的使用权限&#xff0c;然后主机给出地址和控制信号&#xff0c;根…

【JavaEE进阶】SpringMVC

文章目录 一. 简单认识SpringMVC1. 什么是SpringMVC?2. SpringMVC与MVC的关系 二. SpringMVC1. SpringMVC创建和连接2. SpringMVC的简单使用2.1 RequestMapping 注解介绍2.2 RequestMapping支持的请求类型2.3 GetMapping 和 PostMapping 3. 获取参数3.1 传递单个参数3.2 传递对…

【linux】2 Linux编译器-gcc/g++和Linux调试器-gdb

文章目录 一、Linux编译器-gcc/g使用1.1 背景知识1.2 gcc如何完成1.3 函数库1.4 gcc选项 二、linux调试器-gdb使用2.1 背景2.2 开始使用 总结 ヾ(๑╹◡╹)&#xff89;" 人总要为过去的懒惰而付出代价ヾ(๑╹◡╹)&#xff89;" 一、Linux编译器-gcc/g使用 1.1 背景…

/root/.ssh/config line 2: Bad protocol 2 host key algorithms ‘+ssh-rsa‘.

文章目录 1、问题2、查看openssh版本3、解决问题4、重新生成密钥5、查看是否可连接工蜂 1、问题 ssh访问工蜂报错&#xff1a; [rootlocalhost .ssh]# ssh -T gitgit.code.tencent.com /root/.ssh/config line 2: Bad protocol 2 host key algorithms ‘ssh-rsa’. 2、查看o…

升级Qt后VS项目不能使用

错误场景&#xff1a; 如果你的QT卸载了装了新版,那么VS你原来设置的项目就不能跑了. 问题 升级Qt后&#xff36;&#xff33;项目不能使用 跟我一起开始挽救自己的项目 升级Qt后&#xff36;&#xff33;项目不能使用 假如你从5.14.6 升级到 Qt6.2并删除了原来的QT 你在VS里…

Java网络编程(一)网络基础

概述 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递 网络分类 局域网(LAN) 局域网是一种在小区域内使用的,由多台计算机组成的网络,覆盖范围…

春秋云镜 CVE-2019-16692

春秋云镜 CVE-2019-16692 phpIPAM 1.4 - SQL Injection 靶标介绍 phpIPAM 1.4后台存在SQL Injection。 启动场景 漏洞利用 后台SQL注入&#xff0c;admin/admin888登陆成功。 exp POST /app/admin/routing/edit-bgp-mapping-search.php HTTP/1.1 Host: xxx.com Content-Le…

mysql从传统模式切到GTID模式后启动主从,主从异常报错1236

一 前言 MySQL 的主从复制作为一项高可用特性&#xff0c;用于将主库的数据同步到从库&#xff0c;在维护主从复制数据库集群的时候&#xff0c;作为专职的MySQL DBA&#xff0c;笔者相信大多数人都会遇到“Got fatal error 1236 from master when reading data from binary …

MySQL数据库:内置函数

日期函数 规定&#xff1a;日期&#xff1a;年月日 时间&#xff1a;时分秒 函数名称作用描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳date(datetime)返回datetime参数的日期部分date_add(date,interval d_value_type)在date中添加…

仿mudou高性能高并发服务器

"这个结局是我的期待&#xff0c;我会一直为你祝福。" 项目实现目标: 仿muduo库One Thread One Loop式主从Reacto模型实现高并发服务器。通过实现高并发服务器组件&#xff0c;简洁快速完成搭建一个高性能服务器。并且&#xff0c;通过组件内提供的不同应⽤层协议⽀…

Kafka基本使用

查看Kafka的进程是否在运行 #命令行终端中运行如下命令 ps -ef | grep kafkafind / -iname kafka-server-start.shcd /usr/local/kafka/bin/#启动kafka ./kafka-server-start.sh -daemon /usr/local/kafka/config/server.propertiesKafka默认使用9092端口提供服务&#xf…

九、Linux下,如何在命令行进入文本编辑页面?

1、文本编辑基础 说到文本编辑页面&#xff0c;那就必须提到vi和vim&#xff0c;两者都是Linux系统中&#xff0c;常用的文本编辑器 2、三种工作模式 3、使用方法 &#xff08;1&#xff09;在进入Linux系统&#xff0c;在输入vim text.txt之后&#xff0c;会进入文本编辑中&…

Android学习之路(9) Intent

Intent 是一个消息传递对象&#xff0c;您可以用来从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信&#xff0c;但其基本用例主要包括以下三个&#xff1a; 启动 Activity Activity 表示应用中的一个屏幕。通过将 Intent 传递给 startActivity()&…

简单计算器的实现(含转移表实现)

文章目录 计算器的一般实现使⽤函数指针数组的实现&#xff08;转移表&#xff09; 计算器的一般实现 通过函数的调用&#xff0c;实现加减乘除 # define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int Add(int x, int y) {return x y; }int Sub(int x, int y) {retur…

服务注册中心 Eureka

服务注册中心 Eureka Spring Cloud Eureka 是 Netflix 公司开发的注册发现组件&#xff0c;本身是一个基于 REST 的服务。提供注册与发现&#xff0c;同时还提供了负载均衡、故障转移等能力。 Eureka 有 3 个角色 服务中心&#xff08;Eureka Server&#xff09;&#xff1a;…

vue项目配置git提交规范

vue项目配置git提交规范 一、背景介绍二、husky、lint-staged、commitlint/cli1.husky2.lint-staged3.commitlint/cli 三、具体使用1.安装依赖2.运行初始化脚本3.在package.json中配置lint-staged4.根目录新增 commitlint.config.js 4.提交测试1.提示信息格式错误时2.eslint校验…

线程池的实现v2.0(可伸缩线程池)

目录 前言 可伸缩线程池原理 可伸缩线程池实现 完整程序 前言 本篇可伸缩线程池的实现是在静态线程池上拓展而来&#xff0c;对于静态线程池的实现&#xff0c;请参考&#xff1a; 线程池的实现全过程v1.0版本&#xff08;手把手创建&#xff0c;看完必掌握&#xff01;&…

Java课题笔记~Element UI

Element&#xff1a;是饿了么公司前端开发团队提供的一套基于 Vue 的网站组件库&#xff0c;用于快速构建网页。 Element 提供了很多组件&#xff08;组成网页的部件&#xff09;供我们使用。例如 超链接、按钮、图片、表格等等~ 如下图左边的是我们编写页面看到的按钮&#…

5G与4G的RRC协议之异同

什么是无线资源控制&#xff08;RRC&#xff09;&#xff1f; 我们知道&#xff0c;在移动通信中&#xff0c;无线资源管理是非常重要的一个环节&#xff0c;首先介绍一下什么是无线资源控制&#xff08;RRC&#xff09;。 手机和网络通过无线信道相互通信&#xff0c;彼此交…