当前位置: 首页 > article >正文

再识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语言的只能有一个返回值,理论上我们可以用指针写出无数个返回值


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


http://www.kler.cn/a/230225.html

相关文章:

  • Day 27 贪心算法 part01
  • 【11-20期】Java面试进阶:深入解析核心问题与实战案例
  • CGAL CGAL::Polygon_mesh_processing::self_intersections解析
  • HTML5和CSS3新增特性
  • ubuntu搭建k8s环境详细教程
  • Http 请求协议
  • 无人机激光雷达标定板
  • 限制Unity帧率的方式
  • 【QT】opcuaServer 的构建
  • ELAdmin 新增Module
  • vite打包原理
  • 4、安全开发-Python-蓝队项目流量攻击分析文件动态监控图片隐写技术
  • Golang 学习(一)基础知识
  • iOS平台RTMP|RTSP播放器如何实时回调YUV数据
  • 使用NLTK进行自然语言处理:英文和中文示例
  • c#cad 创建-多线段(三)
  • 市场复盘总结 20240206
  • 人工智能:数据分析之数据预处理、分析模型与可视化
  • MIT-Missing Semester_Topic 6:Version Control (Git) 练习题
  • 华为OD机试真题C卷-篇3
  • OS X(MACOS) C/C++ 程序链接静态库限制。
  • 2023-总结
  • LeetCode 丑数
  • 【实验3】统计某电商网站买家收藏商品数量
  • 企业微信会话存档:大文件拉取、加密、上传
  • (十三)springboot实战——springboot前后端分离方式项目集成spring securtity安全框架