【C语言初阶】带你轻松掌握指针基础知识完结篇——野指针,指针运算,指针和数组,二级指针

news2024/10/6 22:24:13

在这里插入图片描述

君兮_的个人主页

勤时当勉励 岁月不待人

C/C++ 游戏开发


Hello,这里是君兮_,今天继续给大家更新0基础入门C语言的内容,我们这次主要更新的依然是初阶指针的基础知识

  • 废话不多说咱们直接开始吧!!

指针基础

  • 一. 野指针
    • 1. 野指针成因
    • 2. 如何规避野指针
  • 二. 指针运算
    • 1.指针+- 整数
    • 2.指针-指针
    • 3.指针的关系运算
  • 三. 指针和数组
  • 四.二级指针
  • 五. 指针数组
  • 总结

一. 野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

1. 野指针成因

    1. 指针未初始化
#include <stdio.h>
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
  *p = 20;
return 0;
}
    1. 指针越界访问
#include <stdio.h>
int main()
{
  int arr[10] = {0};
  int *p = arr;
  int i = 0;
  for(i=0; i<=11; i++)
 {
    //当指针指向的范围超出数组arr的范围时,p就是野指针
    *(p++) = i;
 }
  return 0;
  }
    1. 指针指向的空间释放
  • 这里放在指针进阶篇中动态内存开辟的时候讲解

2. 如何规避野指针

1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放,及时置NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性

第三种情况的使用例子

#include <stdio.h>
int main()
{
  int *p = NULL;//在使用前先把指针置空防止为释放指针之前指向的空间
  //....
  int a = 10;
  p = &a;
  if(p != NULL)
 {
    *p = 20;
 }
  return 0;
  }

二. 指针运算

1.指针± 整数

#define m 5
float values[m];
float* vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[m];)
{
    *vp++ = 0;//把values数组中每个元素都初始化为0,这里指针++表示地址后移
}

2.指针-指针

//计算字符串的长度
int my_strlen(char *s)
{
   char *p = s;
   while(*p != '\0' )
       p++;
   return p-s;//当p中读取到\0时说明该字符串总长度为此时的地址p-首元素地址s
   }

3.指针的关系运算

for(vp = &values[m]; vp > &values[0];)
{
  *--vp = 0;//由于是前置--,最后会与第一元素之前的元素比较
}

  • 上面这段代码有比较明显的缺点,我们来简化一下。
for(vp = &values[m-1]; vp >= &values[0];vp--)
{
  *vp = 0;
}
  • 实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。
  • 标准规定:
  • 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

三. 指针和数组

  • 我们先通过一个例子来建立一下数组与指针之间的联系
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
  printf("%p\n", arr);//打印地址
  printf("%p\n", &arr[0]);
  return 0;

在这里插入图片描述

  • 我们可以发现两者的地址是相同的
  • 可见数组名和数组首元素的地址是一样的。
  • 结论:
  • 数组名表示的是数组首元素的地址。(2种情况除外,在之前的博客中讲过,链接如下:【C语言初阶】带你玩转C语言中的数组,并逐步实现冒泡排序,三子棋,扫雷)
  • 那么这样写代码是可行的:
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr;//p存放的是数组首元素的地址
  • 既然可以把数组名当成地址存放到一个指针中,我们就可以使用指针来访问一个数组。
  • 示例如下:
#include <stdio.h>
int main()
{
  int arr[] = {1,2,3,4,5,6,7,8,9,0};
  int *p = arr; //指针存放数组首元素的地址
  int sz = sizeof(arr)/sizeof(arr[0]);
  int i;
  for(i=0; i<sz; i++)
 {
    printf("&arr[%d] = %p  <====> p+%d = %p\n", i, &arr[i], i, p+i);
    }
    return 0;
 }

在这里插入图片描述

  • 所以 p+i 其实计算的是数组 arr 下标为i的地址。
    那我们就可以直接通过指针来访问数组
  • 示例如下:
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i<sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}

四.二级指针

  • 指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
  • 答案不言而喻—— 二级指针 。

int main()
{
    int a = 10;
    int* p = &a;
    int** pa = &p;
    printf("%d\n", a);
    printf("%d\n", *p);
    printf("%d\n", **pa);
    return 0;
}

在这里插入图片描述

  • 我们可以看出来三者的值是相同的!!

  • 对于二级指针的运算有:

 //*pa通过对pa中的地址进行解引用,这样找到的是p ,*pa 其实访问的就是p .
int b = 20;
*pa = &b;//等价于 p = &b;
//**pa 先通过* pa 找到 p, 然后对 p 进行解引用操作:*p ,那找到的是 a .
**pa = 30;
//等价于*p = 30;
//等价于a = 30;

五. 指针数组

  • 指针数组是指针还是数组?
  • 是数组。是存放指针的数组。

数组我们已经知道整形数组,字符数组。

int arr1[5];
char arr2[6];
  • 那指针数组是怎样的?
int* arr3[5];//是什么?
  • arr3是一个数组,有五个元素,每个元素是一个整形指针。
    在这里插入图片描述
  • 还有一种指针类型叫做数组指针,是指针,这两种情况我都会放在指针进阶篇中介绍。

总结

  • 今天的内容到这里就全部结束了,我们今天把指针基础部分全部介绍完了,其中主要包括野指针的定义以及如何避免,指针运算的几种形式以及指针与数组的关系和二级指针,希望大家把博客中的代码都弄懂哦!

  • 好了,如果你有任何疑问欢迎在评论区或者私信我提出,大家下次再见啦!

新人博主创作不易,如果感觉文章内容对你有所帮助的话不妨三连一下这个新人博主再走呗。你们的支持就是我更新的动力!!!

**(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)**

在这里插入图片描述

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

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

相关文章

运输层:TCP报文段的首部格式

1.运输层&#xff1a;TCP报文段的首部格式 笔记来源&#xff1a; 湖科大教书匠&#xff1a;TCP报文段的首部格式 声明&#xff1a;该学习笔记来自湖科大教书匠&#xff0c;笔记仅做学习参考 为了实现可靠传输&#xff0c;TCP采用了面向字节流的方式。 但TCP在发送数据时&#…

CSS:选择器的各种类型和用法(含有例子和部分动态效果)

目录 css 基本语法一、基本选择器元素选择器 E{}特殊的 * 所有元素选择器属性选址器 E[attr]{}# id选择器. class选择器也可以结合着用selector1 selector2 包含选择器> 子选择器~兄弟选择器选择器组合 二、伪元素选择器第一个字加样式&#xff1a;第一行加样式&#xff1a;…

基于深度学习的高精度猴子检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度猴子检测识别系统可用于日常生活中或野外来检测与定位猴子目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的猴子目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型…

改进 Elastic Stack 中的信息检索:对段落检索进行基准测试

作者&#xff1a;Grgoire Corbire, Quentin Herreros, Thomas Veasey 在之前的博客文章中&#xff0c;我们讨论了信息检索的常见方法&#xff0c;并介绍了模型和训练阶段的概念。 在这里&#xff0c;我们将检查基准解决方案&#xff0c;以公平的方式比较各种方法。 请注意&…

基于高精度三维机器视觉的螺丝锁付系统应用

Part.1 行业背景 随着社会经济的发展、科技的进步及工业水平的提高&#xff0c;智能工业发展模式在全球范围内备受关注。螺丝锁付作为最常用的装配连接方式&#xff0c;在加工制造的各个环节得到了广泛应用&#xff0c;如&#xff1a;玩具、电子产品、塑胶、汽车零部件、通讯设…

freemark生成pdf

freemark生成pdf 字体库 simsun.ttc 解决中文问题 /*** 生成pdf* param params* param templPath* param ftlName* param htmlPath* param pdfPath* param fontPath* return*/public String processPdf(Map<String, Object> params, String templPath, String ftlName,…

CodeMirror 对 XML 文档熟悉及元素控制自定义

CodeMirror 是一个网络代码编辑器组件。它可以在网站中用于实现支持多种编辑功能的文本输入字段&#xff0c;并具有丰富的编程接口以允许进一步扩展。 本文为 xml 格式的代码提示约束格式规范的自定义示例内容。 先看效果&#xff0c;如下&#xff1a; 官方 Demo 的完整代码如…

【MATLAB第52期】#源码分享 | 基于MATLAB的高斯过程GPR超参数(sigma)自动优化算法 时间序列预测模型 五折交叉验证

【MATLAB第52期】#源码分享 | 基于MATLAB的高斯过程GPR超参数&#xff08;sigma&#xff09;自动优化算法 时间序列预测模型 五折交叉验证 后台私信回复“52期”即可免费获取数据及代码。 一、效果展示 二、优化思路 1.数据 一列时间序列数据 &#xff0c;滑动窗口尺寸为15。…

《前端开发 实践之 Webstorm 学习》

目录 Webstorm 简介官方下载地址安装记录-教程下载其他版本方法 是否推送数据统计许可证激活插件功能版本控制查看代码责任人插件(annotate) Webstorm 简介 作为 jetbrains 公司旗下一款 JavaScript 开发工具&#xff0c;Web前端开发神器之一 个人博客地址&#xff1a; 官方下载…

网络安全自学黑客入门(超详细)

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01; 却不知道从哪里开始学起&#xff01;怎么学&#xff1f;如何学&#xff1f; 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xf…

银河麒麟服务器V10 SP1 .Net6.0 开机自动启动

开机自动启动&#xff0c;折腾了一小天&#xff0c;设置/etc/init.d/ 、update-rc.d&#xff0c;可能刚开始用&#xff0c;经验不多吧&#xff0c;尝试多种方式我的服务怎么都启动不起来&#xff0c;根据之前nginx和redis的自动启动经验&#xff0c;使用systemd管理服务&#x…

【EXCEL】给数据添加图表(数据条、柱状图、折线图等),快速分析功能图文详解

目录 0.环境 1.背景简介 2.具体实现 2.1 给数据添加数据条 实现效果&#xff1a; 具体操作&#xff1a; 2.2 给数据添加柱状图图表 实现效果&#xff1a; 具体操作&#xff1a; 2.3 给数据添加迷你图&#xff08;在表格中的折线图&#xff09; 实现效果&#xff1a; …

基于PyQt5的桌面图像调试仿真平台开发(13)图像边缘显示

系列文章目录 基于PyQt5的桌面图像调试仿真平台开发(1)环境搭建 基于PyQt5的桌面图像调试仿真平台开发(2)UI设计和控件绑定 基于PyQt5的桌面图像调试仿真平台开发(3)黑电平处理 基于PyQt5的桌面图像调试仿真平台开发(4)白平衡处理 基于PyQt5的桌面图像调试仿真平台开发(5)…

JavaWeb学习笔记1

目录 web标准 三个组成部分 HTML 标题标签 水平线标签 换行标签 图片标签 布局标签&#xff1a; 超链接标签 属性&#xff1a; 视频标签&#xff1a; 音频标签&#xff1a; 段落标签&#xff1a; 文本加粗标签&#xff1a; 表格标签 表单标签 表单项 CSS Css引入方式…

1.6 OSI 七层参考模型

OSI 参考模型 OSI参考模型解释的通信过程OSI参考模型数据封装与通信过程物理层功能数据链路层功能网络层的功能传输层功能会话层功能表示层功能应用层功能 开放系统互连 (OSI)参考模型是由国际标准化组织 (ISO) 于1984年提出的分层网络体系结构模型目的是支持异构网络系统的互联…

数学建模--TOPSIS

代码 topsis.m Positivization.m inter2Max.m Mid2Max.m Min2Max.m

C++学习 函数

目录 函数 函数的定义 函数的调用 值传递 常见的样式 函数的声明 函数的分文件编写 1.创建后缀.h的头文件 2.创建后缀.cpp的源文件 3.头文件中写函数声明 4.源文件中写函数定义 5.函数调用 函数 作用&#xff1a; C中的函数充当了组织和重用代码的重要工具&#xff0c;提供了抽…

8-js高级-3

JavaScript 进阶 - 3 了解构造函数原型对象的语法特征&#xff0c;掌握 JavaScript 中面向对象编程的实现方式&#xff0c;基于面向对象编程思想实现 DOM 操作的封装。 编程思想构造函数原型综合案例 编程思想 学习 JavaScript 中基于原型的面向对象编程序的语法实现&#xff…

大胜归来!妙记多这份「高考填志愿」指南请收好!

2023年高考已经落下帷幕&#xff0c;上周和本周多个省份就要公布高考分数了&#xff0c;志愿填报还会远吗&#xff1f; 不知道自己的分数能报什么院校&#xff1f; 不知道目标院校的王牌专业有哪些&#xff1f; 不知道目标专业的就业方向&#xff1f; 不知道有哪些志愿填报小…

C# 简述.NET中堆和栈的区别

目录 一&#xff0c;引言 二&#xff0c;.NET的堆栈 三&#xff0c;.NET中的托管堆 四&#xff0c;.NET中的非托管堆 五、堆栈、托管堆和非托管堆的比较 六&#xff0c;总结 一&#xff0c;引言 .NET提供了垃圾回收机制&#xff0c;使程序员从内存管理中被解放出来。但这…