再识C语言 DAY15 【指针(中)理论结合实践】

2024-02-07 09:20

本文主要是介绍再识C语言 DAY15 【指针(中)理论结合实践】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、补充
  • 二、数组与指针
    • 指针运算
  • 注意事项
  • 指针的应用
    • 传递参数(指针的间接访问)
    • 指针输出参数
  • 如果您发现文章有错误请与我留言,感谢


前言

本文章总结于此视频


一、补充

指针即指针变量,用于存放其他数据单元(变量/数组/结构体/函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针。指向了这个数据单元,若指针存放的值是0,则这个指针为空指针

如图所示:
在这里插入图片描述

另外,在一个系统上指针所占用的字节是确定不变的
在这里插入图片描述

我们这里使用的64位系统都是占八个字节,这是一个很关键的信息

二、数组与指针

数组与指针可以说是非常相似,数组是一些相同数据类型的变量组成的集合,其数组名及为指向该数据类型的指针。当你在写一个数组arr[]不写[ ],此时的arr就等效于指针,

如图所示

在这里插入图片描述

我们尝试一下

在这里插入图片描述

指针运算

当然,这里也涉及到了运算
在这里插入图片描述

注意:如果只是一个单独的变量就不要使用加或减,因为此时会指向非法的区域

我们可以取变量的地址来直观的学习
在这里插入图片描述

我们可以直观地观察到他们的不同,int数据类型的地址增加了四个字节char数据类型的地址增加了一个字节

所以为什么要移动一个数据类型的长度,我们前面知道指针记录的是首地址,实际上他们的类型是int 和char,我们可以想想对于int类型的数组,比如说他第一个数据地址是1,2,3,4,如果他只移动一个地址,那么你认为第二个数的地址是2,3,4,5,但实际上第二个数的地址是5,6,7,8

在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f4c04b3e7311476db2956159641522b0.jpeg#pic_center)

在这里插入图片描述

图片出处

如上图所示表示数组中5个元素在内存中的存储,其中p1指向第一个元素的地址p2表示第五个元素的地址,代码中用p2-p1,就表示的是两个指针之间的元素个数,很清楚的看到是4个元素,所以打印出来结果为4

注意事项

• 在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误
•同级指针之间才能相互赋值,跨级赋值将会导致编译器报错或警告

什么是同级指针
在这里插入图片描述
比如说变量在和指针之间赋值时,当变量加上取地址&,就是正确的,或者指针加上*

如果不是同级指针,赋值时将会报错。

在这里插入图片描述

int a=1;
int* p;
*p=a;//或者
P=&a;

指针的应用

传递参数(指针的间接访问)

传递参数时,我们分为值传递和指针传递

当我们传递的参数容量很大时,我们尽量使用指针传递

因为使用指针传递大容量的参数时,主函数和子函数使用的是同一套数据,避免了参数传递过程中的数据复制,提高了运行效率,减少了内存占用

我们举一个例子,让他更直观一些:我们假设主函数是一个学霸,我们创建新函数是一个学渣,把主函数内的一个变量假设为作业的话,如果学渣想要抄学霸作业,得到这个变量,但是主函数学霸是不会将变量直接给学渣函数的,他会先把作业抄一遍,把这个复制的作业给学渣,这样就算学渣在这个复制体作业上更改数值,也不会影响到主函数学霸的变量

作业如果是选择题还好说,但如果是作文的话,复制一份既费时又费力,这里我们就可以引用指针传递

比如说我们现在想传递一个数组,数组就属于大容量变量

#include<stdio.h>
int FindMax(int* arr,int Count)
{int i;int j=arr[0];for(i=1;i<Count;i++){if(j<arr[i]);{j=arr[i];}                      }return j;
}
int main()
{int max;int arr[5]={10,20,30,40,50};
max = FindMax(arr,5);
printf ("%d",max);return 0;
}

输出

在这里插入图片描述

但是此时我们发现,我们是可以通过改变变量的值来影响主函数中变量的值
在这里插入图片描述
这时我们就想到之前学的常量指针,当我们在其他函数中改变变量的值时,编译器就会报错警告我们, 所以使用常量指针是我们指针传递中的一个保护措施
在这里插入图片描述
相比较,值传递隔离,数据安全,但是当遇到大容量的数据是会占用较多的空间和时间。指针传递可以处理大容量的数据。为了使数据更安全,我们可以使用常量指针。

指针输出参数

使用指针传递输出参数,利用主函数和子函数使用同一套数据的特性,实现数据的返回,可实现多返回值函数的设计
我们发现第一个应用是避免主函数与子函数使用同一套数据,而第二个应用是反过来的,我们要利用主函数和子函数使用同一套数据,实现多返回值

因为C语言有一个弊端,那就是只能有一个返回值,当我们要返回多个值时,就需要用到指针的这个特征

例题:找到数组中最大的数,和其出现的次数。

#include<stdio.h>
int FindMax(int* max,int* count,int* arr,int lenght)
{int i;*max=arr[0];*count=1;for(i=1;i<lenght;i++){if(*max<arr[i]){*max =arr[i];*count=1;}       else if(*max==arr[i]){(*count)++;}               }
}
int main()
{int MAX,Max;int Count;int arr[5]={10,50,30,40,50};
MAX = FindMax(&Max,&Count,arr,5);
printf ("%d\n",Max);
printf ("%d",Count);return 0;
}

运行:

在这里插入图片描述
所以说指针打破了C语言的只能有一个返回值,理论上我们可以用指针写出无数个返回值


如果您发现文章有错误请与我留言,感谢

这篇关于再识C语言 DAY15 【指针(中)理论结合实践】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/687266

相关文章

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()