「1」指针进阶——详解
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
🐰指针的回顾
🐰字符指针
🐰指针数组
🌸模拟二维数组(整形)
🐰数组指针
🌸数组指针和指针数组的区分
🌸&数组名和数组名的区别
🌸数组指针p,*p等价于arr,*p就是数组名
🌸数组指针的使用
🌸数组参数和指针参数
🐰函数指针-指向函数的指针
🌸函数指针数组
🐰指针的回顾
1.指针是内存中一个最小单元的编号,也就是地址
2.平时口语上所说的指针,通常指的是指针变量,是用来存放地址的变量
3.把内存划分为一个个的内存单元,这个内存单元大小是1字节,从概念上讲:编号 == 地址 == 指针
指针变量:
我们可以通过& (取地址操作符) 取出变量的内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量
4.指针大小(4字节 32位/8字节 64位)
🐰字符指针
#include<stdio.h> int main() {char ch='w';char* pc=&ch;const char* p="abcdef";//"abcdef",是把字符串的首地址放到p中//"abcdef"是常量字符串,是不可以修改的char arr[]="abcdef";//"abcdef",这里的arr的值是可以修改的char *pa=arr;*pa='w';printf("%s\n",arr);//修改的结果为wbcdefreturn 0; }‼️注:常量字符串在内存中只保存一份!!!
#include<stdio.h> int main() {char str1[]="abcdef";char str2[]="abcdef";char* str3="abcdef";//保存的就是常量字符串char* str4="abcdef";//保存的就是常量字符串if(str1==str2)//数组保存的字符串是变量,所以str1!=str2{printf("str1==str2\n");}else{printf("str1!=str2\n");}if(str3==str4)//常量字符串在内存中只保留一份,所以str3==str4{printf("str3==str4\n");}else{printf("str3!=str4\n");}return 0; }结果为:
str1!=str2str3==str4
🐰指针数组
字符数组-存放字符的数组char arr[10];整形数组-存放整形的数组int arr[10];指针数组-存放的就是指针char* arr[10];int* arr[10];#include<stdio.h> int main() {char* arr[]={"abc","bcd","edf"};//指针数组,保存了三个字符串的首地址for(int i=0;i<3;i++){printf("%s\n",arr[i]);}return 0; }结果为:abc
bcd
edf
🌸模拟二维数组(整形)
#include<stdio.h> int main() {int arr1[]={1,2,3,4,5};int arr2[]={1,2,3,4,5};int arr3[]={1,2,3,4,5};int arr4[]={1,2,3,4,5};int* arr5[]={arr1,arr2,arr3,arr4};for(int i=0;i<4;i++){for(int j=0;j<5;j++){printf("%d",*(arr5[i]+j));//printf("%d\n",arr5[i][j]);//结果一样}printf("\n");}return 0; }结果为:
12345
12345
12345
12345
🐰数组指针
整形指针-指向整形的指针int a=10;int* P=&a字符指针-指向字符的指针char ch='w';char* pc=&ch;数组指针-指向数组的指针int arr[10];&arr就是数组的地址int (*pa)[10]=&arr;char arr[10];char(*pc)[10]=&arrint* arr[5];int* (*pa)[5]=&arr//这个数组指针指向的是arr这个指针数组🌸数组指针和指针数组的区分
指针数组->存放指针的数组数组指针->是一种指向数组的指针-存放的是数组的地址🌸&数组名和数组名的区别
数组名是数组首元素地址sizeof(数组名)--这个时候表示的不是首元素的首地址,计算的整个数组的大小&数组名--这里的数组名表示整个数组,取出的是整个数组的地址,从地址角度看和数组首元素的地址一样,他们的类型不一样#include<stdio.h> int main() {int arr[10]={0};printf("arr=%p\n",arr);//数组首元素的地址printf("arr+1=%p\n",arr+1);//数组第二个元素的地址printf("&arr[0]=%p\n",&arr[0]);//数组首元素的地址printf("&arr[0]+1=%p\n",&arr[0]+1);//数组第二个元素的地址printf("&arr=%p\n",&arr);//整个数组的地址printf("&arr+1=%p\n",&arr+1);//数组第最后一个元素的下一个的地址int(*p)[10]=&arr;//数组指针保存整个数组的地址return 0; }结果
r=0x7ffeefbff3c0arr+1=0x7ffeefbff3c4&arr[0]=0x7ffeefbff3c0&arr[0]+1=0x7ffeefbff3c4&arr=0x7ffeefbff3c0&arr+1=0x7ffeefbff3e8🌸数组指针p,*p等价于arr,*p就是数组名
#include<stdio.h> int main() {int arr[10]={1,2,3,4,5,6,7,8,9,10};int (*p)[10]=&arr;for(int i=0;i<10;i++){printf("%d ",*((*p)+i));//*p等价于arr,*p就是数组名}return 0; }结果为:1 2 3 4 5 6 7 8 9 10
🌸数组指针的使用
#include<stdio.h> void print(int (*arr)[5],int r,int c) {for(int i=0;i<r;i++){for(int j=0;j<c;j++){printf("%d ",*(*(arr+i)+j));//arr+i==&arr[i]//printf("%d ",arr[i][j]);}} } int main() {//二维数组的数组名,也表示首元素地址//二维数组的首元素是第一行的地址,是一个一维数组的地址int arr[3][5]={1,2,3,4,5,6,7,8,9,10};print(arr,3,5);return 0; }结果为:
1 2 3 4 5 6 7 8 9 10 0 0 0 0 0二维数组arr
int (*p)[10]=&arr;p等价于arrarr=&arr[i]arr[i]=&arr[i][0]分析代码int arr[5];int *parr1[10];//指针数组int (*parr2)[10];//数组指针int (*parr3[10])[5];//数组中存放的数组指针🌸数组参数和指针参数
一维数组传参一维数组传参,形参可以是数组,可以是指针二维数组传参参数可以是指针,可以是数组,如果是指针,传过去的是第一行的地址函数形参的设计只能省略第一个[]的数字,因为一个二维数组,可以不知道有对少行,但是必须知道一行有多少元素一级指针传参当一个函数的参数部分为一级指针的时候,函数能接收什么参数数组,指针二级指针传参当一个函数的参数部分为二级指针的时候,函数能接收什么参数二级指针变量,一级指针的地址,指针数组
🐰函数指针-指向函数的指针
函数指针存放的是函数的地址,函数也是有地址的‼️注:函数名和取地址函数名 是一样的#include<stdio.h> int Add(int x,int y) {return x+y; } //函数是存在地址 int main() {printf("%p\n",&Add);//0x100003f40printf("%p\n",Add);//0x100003f40int (*pf)(int,int)=Add;//pf就是函数指针int ret=(*pf)(3,5);//函数指针的调用int rat=pf(3,5);//*pf和pf等价//这里的*没有实际的意义,可以不要pf(3,5),可以多加(**pf)(3,5),都不影响结果,*pf)(3,5)是为了方便理解printf("%d %d\n",ret,rat); }结果为:
0x100003ef0
0x100003ef0
8 8
🌸函数指针数组
数组的每个元素是一个函数指针这是利用switch()语句制作的两位数计算器#include<stdio.h> int Add(int x,int y) {return x+y; } int Sub(int x,int y) {return x-y; } int Mul(int x,int y) {return x*y; } int Div(int x,int y) {return x/y; } void menu(void) {printf("**** 两位数的计算器 ****\n");printf("**** 1.Add 2.Sub ****\n");printf("**** 3.Mul 4.Div ****\n");printf("**** 0.exit ****\n"); } int main() {int input=0;do{menu();printf("请选择\n");scanf("%d",&input);int x=0,y=0,ret=0;switch(input){case 1:printf("请输入两个操作数\n");scanf("%d %d",&x,&y);ret=Add(x,y);printf("%d\n",ret);break;case 2:printf("请输入两个操作数\n");scanf("%d %d",&x,&y);ret=Sub(x,y);printf("%d\n",ret);break;case 3:printf("请输入两个操作数\n");scanf("%d %d",&x,&y);ret=Mul(x,y);printf("%d\n",ret);break;case 4:printf("请输入两个操作数\n");scanf("%d %d",&x,&y);ret=Div(x,y);printf("%d\n",ret);break;default:printf("输入错误\n");}}while(input); }结果为:
**** 两位数的计算器 ****
**** 1.Add 2.Sub ****
**** 3.Mul 4.Div ****
**** 0.exit ****
请选择
1
请输入两个操作数
3 8
11
这种算法,太冗余了,不够简洁这是利用函数指针数组制作的两位数计算器#include<stdio.h> int Add(int x,int y) {return x+y; } int Sub(int x,int y) {return x-y; } int Mul(int x,int y) {return x*y; } int Div(int x,int y) {return x/y; } void menu(void) {printf("**** 两位数的计算器 ****\n");printf("**** 1.Add 2.Sub ****\n");printf("**** 3.Mul 4.Div ****\n");printf("**** 0.exit ****\n"); } int main() {int input=0;do{int x=0,y=0;menu();printf("请选择\n");scanf("%d",&input);printf("请输入两个操作数\n");scanf("%d %d",&x,&y);int (*pf[5])(int,int)={0,Add,Sub,Mul,Div};//这里之所以数组元素给了5个,是为了与菜单对应起来if(input<5&&input>=0){int ret=(*pf[input])(x,y);printf("%d\n",ret);}else if(input==0){printf("计算结束\n");break;}else{printf("输入错误\n");}}while(input); }结果为:
**** 两位数的计算器 ****
**** 1.Add 2.Sub ****
**** 3.Mul 4.Div ****
**** 0.exit ****
请选择
1
请输入两个操作数
3 8
11
这种算法,很简洁,逻辑更清晰。
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸
相关文章:
「1」指针进阶——详解
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 🐰指针的回顾 🐰字符指针 🐰指针数组 🌸模…...
JS语法让人困惑的点 “==与===”
在JS中有很多神奇的语法,非常让人困惑,我们就先一一道来,相信你在开发中或多或少都踩过这些坑,或者让人无法理解。 今天我们就来说下【】和【】 这题对于很多没有系统学过前端开发的技术人员来说,算个重点,…...
《狂飙》壁纸大嫂如此惊艳,做成日历壁纸天天看
兄弟们,今年的反腐大剧狂飙都有看吗 ? 话说,名字虽然叫狂飙,但是全剧只有有田一个人在狂飙! 当然,有田虽然亮眼,但是毕竟是个糟老头子,正经人谁看有田啊,当然是看大嫂了…...
手机照片删除了怎么恢复
手机照片删除了怎么恢复?喜欢拍照的小伙伴,都会不定期删除手机上的照片,因为这些爱拍照的人,手机中会存储着很多照片,删除照片是必然的,但在手机删除照片时,如果是一张一张删除太麻烦了,就直接…...
maven pom.xml 依赖的scope属性
maven pom.xml 依赖的scope属性 compile 适用范围 编译期、测试期、运行期 作用 从中央仓库拉取依赖到本地,并编译 打包到结果包中 runtime 适用范围 测试期、运行期 作用 runtime 用在 Class.forName(“com.mysql.jdbc.Driver”) 时,compile 编…...
git 的使用方法 (下 - 远程仓库和图形化)
目录前言:一、什么是协同开发二、Gitee 使用协同开发1. 首先注册一个码云账号2. 新建一个仓库3. 根据下图把新建仓库设置为开源4. 在远端合并分支的方法5. 链接 git 远程6. 提交(同步)远程7. 远程拉取至本地8. 远程分支三、git 图形化的使用1…...
Java基础:拼图小游戏
涉及到的知识: 1.图形用户接口GUI(Graphical User Interface)用图形化的方式显示操作界面 两个体系: AWT包和Swing包 2.界面会用到JFrame类 3.界面中的菜单会用到JMenuBar, JMenu, JMenuItem 4.添加图片 在设置完JLabel的location之后还需要获得展示内容的窗体, 通过setLay…...
一个跟蘑菇结缘的企业老板
记得那是一个很久以前的一家公司了董事长办公室里中的大型盆栽里面长了一个蘑菇董事长认为是祥瑞每天都会浇水后来一个新来的保洁阿姨以为杂草啥的给他掰掉扔垃圾桶了董事长第二天来浇水的时候发现没了就问谁动了他的蘑菇问道之后就跑到楼道大垃圾桶那里把蘑菇找回来种在花盆里…...
【Leetcode 剑指Offer】第 4 天 查找算法(简单)
查找剑指 Offer 03. 数组中重复的数字剑指 Offer 53 - I. 在排序数组中查找数字 I二分法题目链接剑指 Offer 03. 数组中重复的数字 题:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数…...
Jenkins利用docker部署vue项目
Jenkins利用docker部署vue项目一、环境准备1、安装docker2、安装nodejs3、安装cnpm与配置淘宝镜像4、jenkins安装nodejs插件二、jenkins以vue项目1、全局参数配置2、源码配置3、构建环境4、构建三、构建项目四、访问一、环境准备 本次jenkins与部署vue项目在同一台机器&#x…...
【Linux】如何将ntfs硬盘挂载到home目录下并具有读写权限
步骤1. 查看当前挂载的硬盘及其挂载点2. 查看需要挂载到home下的磁盘类型信息3. 在home下新建一个空的文件夹作为该磁盘的新挂载点4. 以ntfs类型的硬盘为例,使用mount命令进行挂载5. 问题1:进程占用了磁盘6. 问题2:磁盘权限为只读的7. 永久挂…...
拖拽删除元素、拖拽排序、拖拽预览图片和拖拽移动元素
介绍 HTML5 提供了专门的拖拽与拖放的 API,目前各浏览器都已支持,包括 IE。HTML 拖放(Drag and Drop)接口使应用程序能够在浏览器中使用拖放功能。例如,用户可使用鼠标选择可拖拽(draggable)元素…...
yarn的global安装命令不生效
问题 yarn全局安装某个依赖完成之后,但依赖没有生效,一般有两种情况导致的。 解决思路 1.yarn命令问题 yarn在全局安装某个依赖时,global要紧接在yarn之后,然后才是add yarn global add xxxx如果出现global在add之后ÿ…...
如何发布自己的npm包?
1 文件组成 package.json文件components文件css样式文件index.js文件 2 package.json配置 description:描述title:题目keywords:搜索关键词typings:指定TypeScript的入口文件main:加载的入口文件module:…...
达梦数据库 闪回查询
当用户操作不慎导致错误的删改数据时,非常希望有一种简单快捷的方式可以恢复数据。闪回技术,就是为了用户可以迅速处理这种数据逻辑损坏的情况而产生的。 闪回技术主要是通过回滚段存储的 UNDO 记录来完成历史记录的还原。如果提交了,还没有…...
java基础学习 day44(多态的优点和劣势)
1. 多态的优势 在多态形式下,右边对象可以实现解耦合(即之后的代码与右边的子类对象不绑定,在更改子类对象后,之后的代码仍可以使用),便于扩展和维护在定义方法的时候,使用父类型作为参数&…...
Guna UI WinForms 2.0.4.4 Crack
Guna.UI2 WinForms is the suite for creating groundbreaking desktop app UI. It is for developers targeting the .NET Windows Forms platform. 50 多个 UI 控件 具有广泛功能的综合组件可帮助您开发任何东西。 无尽的定制 只需拖放即可创建视觉效果命令和体验。 出色的…...
零售航母沃尔玛公布业绩:喜忧参半
2月21日美股盘前,零售巨无霸沃尔玛公布了截至1月的2023财年第四季度业绩报告。财报中不乏可圈可点之处,但是利润迎来六年首降,新财年的利润指引要也比预期低很多,可以说喜忧参半。 一、Q4业绩可圈可点 营收方面:在本…...
Python学习笔记丨while、for、if循环结构基础知识与易错点
Python流程控制 本篇笔记的主要内容是:条件控制和循环控制,包括if语句、while语句、for语句等。 Python条件控制 if (m : 1) > 0: # :是海象运算符,用于在函数内部为变量赋值 print("ok")ok 通过if语句来判断条件是否成立&am…...
【ROS学习笔记1】ROS快速体验输出Hello World
【ROS学习笔记1】ROS快速体验输出Hello World 文章目录【ROS学习笔记1】ROS快速体验输出Hello World1.1 ROS快速体验1.1.1 Hello World快速实现简介1.1.2 Hello World的C实现1.1.3 Hello World的Python实现写在前面,本系列笔记参考的是AutoLabor的教程,具…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
