探索指针的奇妙世界,程序中的魔法箭头(上)

目录

  • 一.指针是什么
  • 二.指针和指针类型
    • 1.指针加减整数
    • 2.指针的解引用
  • 三.野指针
    • 1.野指针形成的原因
      • (1)指针未初始化
      • 指针越界访问
    • 2.如何规避野指针
      • (1)指针初始化
      • (2)小心指针越界
      • (3)指针指向的空间释放,及时置NULL
      • (4)避免返回局部变量的地址
      • (5)指针使用之前检查有效性
  • 四.指针运算
    • 1.指针加减整数
    • 2.指针减指针
    • 3.指针的关系运算
  • 五.指针和数组
  • 六.二级指针
  • 七.指针数组

一.指针是什么

指针是内存中最小单元(字节)的编号,也就是地址
我们平时口中所说的指针,通常说的是指针变量。
总结:指针就是地址,平时口头说的指针是指针变量

指针变量:我们通过取地址操作符取出变量的内存起始地址,把地址存放到一个变量中,这个变量就是指针变量。

#include<stdio.h>int main()
{int a = 1;int* pa = &a; //pa是专门用来存放地址(指针)的,pa被称为指针变量。return 0;
}

总结:
指针变量就是用来存放地址的变量。(存放在指针中的值都被当成地址处理)
一个内存单元有唯一的地址。
地址的大小在32位平台上是4个字节,在64位平台上是8个字节

二.指针和指针类型

变量有不同的类型,比如整型,浮点型等等。指针也有这样的类型。

1.指针加减整数

#include<stdio.h>int main()
{int a = 0x11223344;int* pa = &a;printf("%p\n", pa);printf("%p\n", pa + 1);return 0;
}

在这里插入图片描述

所以指针的类型决定了指针向前或向后走一步有多大距离

#include<stdio.h>int main()
{char a = 0x11223344;char* pa = &a;printf("%p\n", pa);printf("%p\n", pa + 1);return 0;
}

在这里插入图片描述

2.指针的解引用

#include<stdio.h>int main()
{printf("%d\n", sizeof(char*));printf("%d\n", sizeof(short*));printf("%d\n", sizeof(int*));printf("%d\n", sizeof(long*));printf("%d\n", sizeof(float*));printf("%d\n", sizeof(double*));return 0;
}

在这里插入图片描述

我们通过计算不同类型指针变量的大小,发现在64位平台上均是8个字节。
那么指针类型的意义是什么呢?

在这里插入图片描述
在这里插入图片描述
如果改为char类型,44 33 22 11不会变成00 00 00 00,而是会变成 00 33 22 11

总结:
int*的指针解引用可以访问4个字节
char*的指针解引用可以访问1个字节
所以指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)

三.野指针

指向的位置不可知(随机,不正确,没有明确限制)的指针被称为野指针。

1.野指针形成的原因

(1)指针未初始化

#include<stdio.h>int main()
{int* p; //局部变量指针未初始化,默认为随机值*p = 10; return 0;
}

指针越界访问

#include<stdio.h>int main()
{int arr[10] = { 0 };int* p = arr;int i = 0;for (i = 0; i <= 11; i++){//当指针指向的范围超出数组的范围时,指针就是野指针。*(p++) = i;}return 0;
}

2.如何规避野指针

(1)指针初始化

1.明确知道指针初始化为谁的地址,就直接初始化
2.不知道指针初始化为什么值,暂时初始化为NULL

//指针初始化
#include<stdio.h>
int main()
{int a = 10;int* p1 = &a;int* p2 = NULL;return 0;
}

(2)小心指针越界

(3)指针指向的空间释放,及时置NULL

当释放空间后赶紧置空,避免成为野指针。大街上一条狗脱离主人,要把它栓到一棵树上,避免成为野狗。

(4)避免返回局部变量的地址

(5)指针使用之前检查有效性

if (p != NULL)
{//使用
}

四.指针运算

1.指针加减整数

#include<stdio.h>int main()
{int arr[10] = { 0 };int* p = &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < sz; i++){*p = i;p++;}p = arr;for (i = 0; i < sz; i++){printf("%d\n", *(p + i));}//for (i = 0; i < sz; i++)//{//	printf("%d\n", arr[i]);//}return 0;
}

2.指针减指针

我们知道指针实际上就是地址,指针减指针也就是地址减去地址

>#include<stdio.h>int main()
{int arr[10] = { 0 };printf("%d\n", &arr[9] - &arr[0]);printf("%d\n", &arr[0] - &arr[9]);return 0;
}

在这里插入图片描述

结论:指针减去指针得到的数值的绝对值是两个指针之间的元素个数
指针和指针相减的前提是两个指针指向同一块空间

//计算字符串长度
#include<stdio.h>//int length(char* p) 
//{
//	int count = 0;
//	while (*p != '\0')
//	{
//		count++;
//		p++;
//	}
//	return count;
//}//int length(char* p)
//{
//	if (*p == '\0')
//		return 0;
//	else
//		return 1 + length(p + 1);
//}int length(char* p)
{char* start = p;while (*p != '\0'){p++;}return p - start;
}int main()
{char arr[] = "abcdef";int len = length(arr);printf("%d\n", len);return 0;
}

3.指针的关系运算

指针的关系运算就是指针与指针之间比大小。

看这样一段代码

#define N 5
float v[N];
float* vp;
for (vp = &v[N]; vp > &v[0]; )
{*--vp = 0;
}

在这里插入图片描述

将上述代码稍作修改

#define N 5
float v[N];
float* vp;
for (vp = &v[N]; vp >= &v[0]; vp--) //这里变成了大于等于
{*vp = 0;
}

在这里插入图片描述

这段代码没什么问题也更容易理解。但是标准规定允许指向数组元素的指针与指向数组最后一个元素后面位置的指针比较,但是不允许与指向第一个元素前面位置的指针比较
在这里插入图片描述

五.指针和数组

我们通常所说的指针是指针变量,不是数组,是专门用来存放地址的。
数组是一块连续的空间,用来存放相同类型的数据。
联系:数组名是数组首元素的地址,地址就是指针。当我们知道数组首元素的地址,又因为数组是连续存放的,所以可以通过指针访问数组

//通过指针访问数组
#include<stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < sz; i++){printf("%d\t%d\n", *(p + i), arr[i]);}return 0;
}

在这里插入图片描述

我们可以看到 *(p + i)与arr[i]是等价的

六.二级指针

#include<stdio.h>
int main()
{int a = 10;int* p = &a;return 0;
}

在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
int main()
{int a = 10;int* p = &a;int** pp = &p;//pp就是二级指针变量return 0;
}

在这里插入图片描述
二级指针变量就是用来存放一级指针变量的地址
一级指针变量用来存放变量的地址,这里就是a的地址

在这里插入图片描述

七.指针数组

指针数组就是存放指针的数组,也就是说指针数组是数组,并不是指针。

#include<stdio.h>
int main()
{char arr1[] = "ni hao";char arr2[] = "hello";char arr3[] = "happy";char* parr[] = {arr1,arr2,arr3};//指针数组return 0;
}

在这里插入图片描述

打印这三个字符串

	int i = 0;for (i = 0; i < 3; i++){printf("%s\n", parr[i]);}

在这里插入图片描述

数组parr里面有3个元素,分别是数组arr1,arr2,arr3
通过指针数组,将这3个数组联系起来了

#include<stdio.h>int main()
{int arr1[] = { 11,12,13,14,15 };int arr2[] = { 21,22,23,24,25 };int arr3[] = { 31,32,33,34,35 };int* parr[] = { arr1,arr2,arr3 };int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){printf("%d ", parr[i][j]);}printf("\n");}return 0;
}

这里类似于二维数组,并不是真正的二维数组。真正的二维数组的存储在内存中是连续的。

上述代码的结果:
在这里插入图片描述

这很像是二维数组打印出来的结果,区别:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

第七回 林教头刺配沧州道 鲁智深大闹野猪林-FreeBSD/Linux图形界面安装配置

高俅定林冲&#xff1a;手持利刃&#xff0c;故入节堂&#xff0c;杀害本官的罪名&#xff0c;将林冲押解去开封府&#xff0c;暗示开封府将林冲处决。 开封府负责办案的叫孙定&#xff0c;他为人刚正不阿&#xff0c;宅心仁厚。在他的据理力争之下&#xff0c;开封府尹最终对…

【计算机网络】TCP握手与挥手:三步奏和四步曲

这里写目录标题 前言三次握手四次挥手三次握手和四次挥手的作用TCP三次握手的作用建立连接防止已失效的连接请求建立连接防止重复连接 TCP四次挥手的作用&#xff1a;安全关闭连接避免数据丢失避免半开连接 总结&#xff1a; 总结 前言 TCP&#xff08;传输控制协议&#xff09…

终极解决Flutter项目运行ios项目报错Without CocoaPods, plugins will not work on iOS or macOS.

前言 最近在开发Flutter项目&#xff0c;运行ios环境的时候报错没有CocoaPods&#xff0c;安卓环境可以正常运行&#xff0c;当时一脸懵逼&#xff0c;网上搜索了一下&#xff0c;有给我讲原理的&#xff0c;还有让我安装这插件那插件的&#xff0c;最终把电脑搞得卡死&#x…

25计算机考研408专业课复习计划

点击蓝字&#xff0c;关注我们 今天要分享的是25计算机考研408专业课复习计划。 以下内容供大家参考&#xff0c;大家要根据自己的复习情况进行适当调整。 统考与自命题 统考科目是指计算机学科专业基础综合&#xff08;408&#xff09;&#xff0c;满分150分&#xff0c;试…

鸿蒙开发环境配置-Windows

背景 入局鸿蒙开发&#xff0c;发现在 Windows 下面配置安装相关环境并没有像 Mac 一样简单&#xff0c;过程中遇到了一些问题记录一下。 Devceo Studio 下载安装 目前鸿蒙的 IDE 最新版是 4.0&#xff0c;通过这个连接可以下载&#xff0c;鸿蒙4.0下载连接。选择符合我们电…

【设计模式】责任连模式怎么用?

我将通过一个贴近现实的故事——请假审批流程&#xff0c;带你了解和掌握责任链模式。 什么是责任链模式&#xff1f; 责任链模式是一种行为设计模式&#xff0c;它让你可以避免将请求的发送者与接收者耦合在一起&#xff0c;让多个对象都有处理请求的机会将这个对象连成一条…

Qt拖拽事件简单实现

1.相关说明 重写resizeEvent(这个按需重写)、dragEnterEvent(拖拽事件函数)、dropEvent(放下事件函数)&#xff0c;可以将本地图片拖拽到label标签中 2.相关界面 3.相关代码 #include "widget.h" #include "ui_widget.h" #include <QDragEnterEvent>…

【cucumber】cluecumber-report-plugin生成测试报告

cluecumber为生成测试报告的第三方插件&#xff0c;可以生成html测报&#xff0c;该测报生成需以本地json测报的生成为基础。 所以需要在测试开始主文件标签CucumberOptions中&#xff0c;写入生成json报告。 2. pom xml文件中加入插件 <!-- 根据 cucumber json文件 美化测…

beego API 自动化文档

API 全局设置 必须设置在 routers/router.go 中&#xff0c;文件的注释&#xff0c;最顶部&#xff1a; // APIVersion 1.0.0 // Title mobile API // Description mobile has every tool to get any job done, so codename for the new mobile APIs. // Contact astaxiegmai…

Unity中ShaderGraph下获取主灯

文章目录 前言一、ShaderGraph获取主灯1、创建ShaderGraph2、创建一个自定义方法&#xff08;Custom Function&#xff09;节点3、新建两个 Vector3 类型的输出变量4、选择自定义节点程序体为 string 类型5、编写程序体6、我们输出主光方向看看效果7、我们输出主光颜色看看效果…

1.11马原

同一性是事物存在和发展的前提&#xff0c;一方的发展以另一方的发展为条件 同一性使矛盾双方相互吸收有利于自身的因素&#xff0c;在相互作用中各自得到发展 是事物发展根本规律&#xff0c;唯物辩证法的实质和核心 揭示了事物普遍联系的根本内容和变化发展的内在动力 是贯…

Visual Studio 设置编辑框(即代码编辑器)的背景颜色

在Visual Studio 中设置编辑框&#xff08;即代码编辑器&#xff09;的背景颜色&#xff0c;可以按照以下步骤进行&#xff1a; 打开Visual Studio。在菜单栏上找到并点击“工具”(Tools)选项。在下拉菜单中选择“选项”(Options)。在“选项”对话框中&#xff0c;导航至“环境…

设计模式-资源库模式

设计模式专栏 模式介绍模式特点应用场景资源库模式与关系型数据库的区别代码示例Java实现资源库模式Python实现资源库模式 资源库模式在spring中的应用 模式介绍 资源库模式是一种架构模式&#xff0c;介于领域层与数据映射层&#xff08;数据访问层&#xff09;之间。它的存在…

Django REST Framework入门之序列化器

文章目录 一、概述二、安装三、序列化与反序列化介绍四、之前常用三种序列化方式jsonDjango内置Serializers模块Django内置JsonResponse模块 五、DRF序列化器序列化器工作流程序列化&#xff08;读数据&#xff09;反序列化&#xff08;写数据&#xff09; 序列化器常用方法与属…

Flink(十四)【Flink SQL(中)查询】

前言 接着上次写剩下的查询继续学习。 Flink SQL 查询 环境准备&#xff1a; # 1. 先启动 hadoop myhadoop start # 2. 不需要启动 flink 只启动yarn-session即可 /opt/module/flink-1.17.0/bin/yarn-session.sh -d # 3. 启动 flink sql 的环境 sql-client ./sql-client.sh …

力扣每日一题---1547. 切棍子的最小成本

//当我们将棍子分段之后&#xff0c;我们是不是想到了怎么组合这些棍子 //并且这些棍子有一个性质就是只能与相邻的进行组合 //暴力搜索的话复杂度很高 //在思考暴力搜索的时候&#xff0c;我们发现一个规律 //比如棍子长度1 2 1 1 2 //那么与最后一个2组合的棍子有&#xff0c…

【大数据分析与挖掘技术】Mahout推荐算法

目录 一、推荐的定义与评估 &#xff08;一&#xff09;推荐的定义 &#xff08;二&#xff09;推荐的评估 二、Mahout中的常见推荐算法 &#xff08;一&#xff09;基于用户的推荐算法 &#xff08;二&#xff09;基于物品的推荐算法 &#xff08;三&#xff09;基于S…

SQL注入实战:http报文包讲解、http头注入

一&#xff1a;http报文包讲解 HTTP(超文本传输协议)是今天所有web应用程序使用的通信协议。最初HTTP只是一个为获取基于文本的静态资源而开发的简单协议&#xff0c;后来人们以各种形式扩展和利用它.使其能够支持如今常见的复杂分布式应用程序。HTTP使用一种用于消息的模型:客…

NLP论文阅读记录 - 2021 | WOS 使用预训练的序列到序列模型进行土耳其语抽象文本摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作2.1 预训练的序列到序列模型2.2 抽象文本摘要 三.本文方法3.1 总结为两阶段学习3.1.1 基础系统 3.2 重构文本摘要 四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结…

maven 基本知识/1.17

maven ●maven是一个基于项目对象模型(pom)的项目管理工具&#xff0c;帮助管理人员自动化构建、测试和部署项目 ●pom是一个xml文件&#xff0c;包含项目的元数据&#xff0c;如项目的坐标&#xff08;GroupId,artifactId,version )、项目的依赖关系、构建过程 ●生命周期&…