零基础学指针(上)

系列文章目录

🎈 🎈 我的CSDN主页:OTWOL的主页,欢迎!!!👋🏼👋🏼
🎉🎉我的C语言初阶合集:C语言初阶合集,希望能帮到你!!!😍
😍 👋🏼🎉🎊创作不易,欢迎大家留言、点赞加收藏!!! 🥳😁😍


文章目录

  • 系列文章目录
  • 前言
  • 一、内存中变量的存储
  • 二、指针变量的定义和语法
    • (1)指针变量的定义
    • (2)指针变量的语法
  • 三、指针的运算符
    • (1)取地址运算符(&)
    • (2)取值运算符(*)
  • 四、指针变量的运算
    • (1)指针的加减运算
      • (1.1)指针变量加减整数
      • (1.2)指针变量 减 指针变量
    • (2)指针的比较运算
  • 总结


前言

这篇博客是指针系列 的第一篇
将从内存中变量的存储和指针变量的语法和定义,指针的俩个运算符,分别是取值运算符(*)和取地址运算符(&),
然后还会介绍指针变量的运算。


一、内存中变量的存储

在内存中,每个变量都有一个唯一的地址。
当你声明一个变量时,比如int a = 5;,编译器会在内存中为a分配一个空间,并存储值5
同时,a 也有一个内存地址,这个地址可以通过 指针 来访问。

这里的指针是 指针变量 的简称。

  • 例如:

代码如下(示例):

#include<stdio.h>int main()
{//定义一个整型变量 aint a = 5;//输出变量 a的地址printf("&a = %p\n", &a);return 0;
}
  • 结果如图:

  • 内存的分布图(示例)

解释:变量a是整型,在内存中占4个字节(连续的,输出 &a 只会输出首地址);
内存 在分配时是 随机的。(即每次运行时,产生的地址结果是不同的)

注:0X代表的是十六进制数

二、指针变量的定义和语法

(1)指针变量的定义

指针变量是一种特殊的变量,它存储的不是数据本身,而是数据在内存中的地址。
你可以把指针变量想象成一个“箭头”,它指向了内存中存储数据的那个位置。

(2)指针变量的语法

  • 在C语言中,定义指针变量的语法如下:
数据类型 *指针变量名;

1. 数据类型:指针所指向的数据的类型。

比如,如果你有一个指向整数的指针,那么数据类型就是int

2. *:星号表示这是一个指针变量。

3. 指针变量名:你给这个指针变量起的名字,比如pptr等。

  • 例如:

代码如下(示例):

#include <stdio.h>int main() {int a = 10; // 定义一个整数变量 a,并赋值为 10int* p; // 定义一个指向整数的指针变量 pp = &a; // 将变量a的地址赋给指针变量 pprintf("a的值是: %d\n", a); // 输出 a的值printf("a的地址是: %p\n", &a); // 输出 a的地址printf("指针p的值(即a的地址)是: %p\n", p); // 输出指针 p的值,也就是a的地址printf("通过指针p访问a的值是: %d\n", *p); // 通过指针 p访问a的值return 0;
}
  • 结果如图:

三、指针的运算符

(1)取地址运算符(&)

取地址运算符& 用于获取变量的内存地址。

  • 例如:

代码如下(示例):

#include<stdio.h>int main()
{//定义一个整型变量 aint a = 10;int* p; // 声明一个指向 int 的指针变量 pp = &a; // 将变量 a 的地址赋给指针 p//输出变量 a 的地址printf("&a = %p\n", &a);printf("p = %p\n", p);return 0;
}
  • 结果如图:

  • 内存的分布图(示例)

在这里插入图片描述

(2)取值运算符(*)

取值运算符*用于通过指针访问它所指向的内存地址中的值。

  • 例如:

代码如下(示例):

#include<stdio.h>int main()
{//定义一个整型变量 aint a = 10;int* p = &a; // 声明一个指向 int 的指针变量 p,p 指向 a 的地址int b = *p; // 通过指针 p 获取 a 的值,并赋给 b//输出变量a的值printf("a = %d\n", a);//输出变量b的值printf("b = %d\n", b);return 0;
}
  • 结果如图:

四、指针变量的运算

因为指针是一个变量,但它存储的不是普通的数据值,而是另一个变量的内存地址
指针的运算其实就是内存单元(地址)之间的运算
指针的运算主要包括 指针的 加减运算 和 指针的 比较运算

(1)指针的加减运算

(1.1)指针变量加减整数

指针的加减整数运算 实际上是对指针所指向的内存地址进行加减。
由于指针指向的是某种类型的数据,所以加减运算的 步长是这种类型数据的大小。

  • 例如:

代码如下(示例):

#include <stdio.h>int main() {//定义一个整型的一维数组,大小是 5,里面存放着 1,2,3,4,5int a[5] = { 1, 2, 3, 4, 5 };int* p = &a[0]; // p指向数组 a的第一个元素// 指针与整数相加:跳过数组中的元素p = p + 2; // p现在指向arr[2],因为从arr[0]开始加了2个整型类型的大小printf("*p = %d\n", *p); // 输出3// 指针与整数相减:回到之前的元素p = p - 2; // p现在指向arr[0],因为从arr[2]开始减了2个整型类型的大小printf("*p = %d\n", *p); // 输出1return 0;
}
  • 结果如图:

(1.2)指针变量 减 指针变量

当你执行两个指针变量的减法运算时,你实际上是在计算它们所指向的内存地址之间的差值,
但这个差值并不是以字节为单位,而是以指针所指向的数据类型的大小为单位
实际上就是 两个指针之间相隔的元素个数

注意:两个指针变量的减法运算只能在指向同一数组或连续内存块的指针之间进行。
如果两个指针不指向同一数组或连续内存块,
那么减法运算的结果是未定义的, 可能会导致程序崩溃或产生不可预测的行为。

#include <stdio.h>int main() {int arr[5] = { 10, 20, 30, 40, 50 }; // 定义一个整数数组int* p1 = &arr[1]; // 定义一个指向 arr[1]的指针int* p2 = &arr[4]; // 定义一个指向 arr[4]的指针// 计算两个指针之间的差值int dif = p2 - p1; // 这将计算 p2 和 p1 之间相隔的元素个数// 输出结果printf("dif: %d\n", dif);// 输出: dif is: 3// 验证通过指针算术访问数组元素printf("p1: %d\n", *p1); // 输出:p1: 20printf("p1 + dif: %d\n", *(p1 + dif)); // 输出: p1 + dif: 50,这里 p1 + dif 实际上等于 p2return 0;
}
  • 结果如图:

(2)指针的比较运算

指针的比较运算通常用于比较两个指针是否指向 同一个内存地址 或比较 它们在内存中的相对位置。

  • 例如:

代码如下(示例):

#include<stdio.h>int main()
{//定义一个整型变量 a,初始化为 10int a = 10;//定义一个整型变量 b,初始化为 20int b = 20;// 声明一个指向 int 的指针变量 p1,p1 指向 a 的地址int* p1 = &a;	// 声明一个指向 int 的指针变量 p2,p2 指向 b 的地址int* p2 = &b;//判断if (p1 == p2) {// 这两个指针指向不同的地址,所以不会执行这里的代码}else {// 这两个指针指向不同的地址,所以执行这里的代码printf("hehe\n");}return 0;
}
  • 结果如图:

总结

1. 指针是一个变量,用于存储另一个变量的内存地址。

2. 取地址运算符 & 用于获取变量的内存地址。

3. 取值运算符 * 用于通过指针访问它所指向的内存地址中的值。

4. 指针的运算包括加减运算和比较运算,用于操作 指针所指向的内存地址。

5. 指针类型的意义
(1)指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:char*的指针解引用就只能访问一个字节,
int* 的指针解引用能访问四个字节
(2)指针的类型决定了指针向前或者向后走一步有多大(距离)。


每天都在学习的路上!
On The Way Of Learning

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

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

相关文章

shell编程之sed

sed 是一种流编辑器&#xff0c;它是文本处理中非常有用的工具&#xff0c;能够完美的配合正则表达式使用&#xff0c;处理时&#xff0c;把当前处理的行存储在临时缓冲区中&#xff0c;称为模式空间&#xff0c;接着用sed 命令处理缓冲区中的内容&#xff0c;处理完成 后&…

一文学习开源框架OkHttp

OkHttp 是一个开源项目。它由 Square 开发并维护&#xff0c;是一个现代化、功能强大的网络请求库&#xff0c;主要用于与 RESTful API 交互或执行网络通信操作。它是 Android 和 Java 开发中非常流行的 HTTP 客户端&#xff0c;具有高效、可靠、可扩展的特点。 核心特点 高效…

多目标优化算法:多目标极光优化算法(MOPLO)求解ZDT1、ZDT2、ZDT3、ZDT4、ZDT6,提供完整MATLAB代码

一、极光优化算法 极光优化算法&#xff08;Polar Lights Optimization, PLO&#xff09;是2024年提出的一种新型的元启发式优化算法&#xff0c;它从极光这一自然现象中汲取灵感。极光是由太阳风中的带电粒子在地球磁场的作用下&#xff0c;与地球大气层中的气体分子碰撞而产…

【贪心算法第二弹——2208.将数组和减半的最小操作数】

1.题目解析 题目来源 2208.将数组和减半的最小操作数——力扣 测试用例 2.算法原理(贪心策略) 3.实战代码 class Solution { public:int halveArray(vector<int>& nums) {priority_queue<double> hash;double sum 0.0;for(auto e : nums){hash.push(e);sum …

2024最新python使用yt-dlp

2024最新python使用yt-dlp下载YT视频 1.获取yt的cookie1&#xff09;google浏览器下载Get cookies.txt LOCALLY插件2&#xff09;导出cookie 2.yt-dlp下载[yt-dlp的GitHub地址](https://github.com/yt-dlp/yt-dlp?tabreadme-ov-file)1&#xff09;使用Pycharm(2024.3)进行代码…

深入理解下oracle 11g block组成

深层次说&#xff0c;oracle数据库的最少组成单位应该是块&#xff0c;一般默认情况下&#xff0c;oracle数据库的块大小是8kb&#xff0c;其中存储着我们平常所需的数据。我们在使用过程中&#xff0c;难免会疑问道&#xff1a;“oracle数据块中到底是怎样组成的&#xff0c;平…

2024年12月Gesp七级备考知识点拾遗第一期(图的定义及遍历)

目录 总序言 知识点拾遗​编辑 度数 环 二叉树 图的遍历 深度优先 广度优先 连通与强连通 有什么不同 构成分别至少需要几条边&#xff08;易错题&#xff09;&#xff1f; 无向连通图 有向强连通图 完全图 什么是完全图 无向完全图最少边数 有向完全图最少边…

家庭智慧工程师:如何通过科技提升家居生活质量

在今天的数字化时代&#xff0c;家居生活已经不再只是简单的“住”的地方。随着物联网&#xff08;IoT&#xff09;、人工智能&#xff08;AI&#xff09;以及自动化技术的快速发展&#xff0c;越来越多的家庭开始拥抱智慧家居技术&#xff0c;将他们的家变得更加智能化、便捷和…

图像处理实验报告

实验一 图像处理的MATLAB基础 实验目的&#xff1a;熟悉数字图象处理的基本软件工具和操作 实验内容&#xff1a;Matlab应用复习&#xff0c;矩阵产生、操作&#xff1b;矩阵运算以及字符运算。 1.利用增量产生向量[0,2,4,6,8,10]。 2.利用magic(n)函数产生7维魔鬼矩阵A&am…

SpringBoot+SpringCloud面试题整理附答案

什么是SpringBoot&#xff1f; 1、用来简化spring初始搭建和开发过程使用特定的方式进行配置(properties或者yml文件) 2、创建独立的spring引用程序main方法运行 3、嵌入Tomcat无需部署war包&#xff0c;直接打成jar包nohup java -jar – & 启动就好 4、简化了maven的配置 …

Linux之管道,system V的共享内存,消息队列和信号量

Linux之管道&#xff0c;systemV共享内存和信号量 一.进程间通信1.1进程间通信的目的1.2进程间通信的方式 二.管道2.1管道的概念2.2匿名管道2.3命名管道 三.system V3.1共享内存3.2消息队列3.3信号量 一.进程间通信 在我们之前有关Linux指令的学习时我们使用过“|”这个命令&a…

Figma入门-基本操作制作登录页

Figma入门-基本操作制作登录页 前言 在之前的工作中&#xff0c;大家的原型图都是使用 Axure 制作的&#xff0c;印象中 Figma 一直是个专业设计软件。 最近&#xff0c;很多产品朋友告诉我&#xff0c;很多原型图都开始用Figma制作了&#xff0c;并且很多组件都是内置的&am…

Django实现智能问答助手-数据库方式读取问题和答案

扩展 增加问答数据库&#xff0c;通过 Django Admin 添加问题和答案。实现更复杂的问答逻辑&#xff0c;比如使用自然语言处理&#xff08;NLP&#xff09;库。使用前端框架&#xff08;如 Bootstrap&#xff09;增强用户界面 1.注册模型到 Django Admin&#xff08;admin.py…

SQL注入--文件读写注入--理论

什么是文件读写注入&#xff1f; MySQL中有 读取文件的函数&#xff1a;load_file() 写入文件的函数&#xff1a;Into outfile&#xff08;能写入多行&#xff0c;按格式输出&#xff09;和 into dumpfile&#xff08;只能写入一行且没有输出格式&#xff09; 利用这些函数在S…

《最小生成树算法详解:Kruskal的优雅实现》

前置知识和本篇介绍 前置知识&#xff1a; 数据结构-优先级队列&#xff0c; 数据结构-并查集。 Kruskal算法不需要建图&#xff0c; 因此不会建图的模板也没事。 本篇介绍一最小生成树的概念和Kruskal算法。 有关prim算法&#xff08;另一种最小生成树的算法&#xff09;&am…

云计算-华为HCIA-学习笔记

笔者今年7月底考取了华为云计算方向的HCIE认证&#xff0c;回顾从IA到IE的学习和项目实战&#xff0c;想整合和分享自己的学习历程&#xff0c;欢迎志同道合的朋友们一起讨论&#xff01; 第二章&#xff1a;服务器基础 服务器是什么&#xff1f; 服务器本质上就是个性能超强的…

uniapp接入高德地图

下面代码兼容安卓APP和H5 高德地图官网&#xff1a;我的应用 | 高德控制台 &#xff0c;绑定服务选择《Web端(JS API)》 /utils/map.js 需要设置你自己的key和安全密钥 export function myAMap() {return new Promise(function(resolve, reject) {if (typeof window.onLoadM…

C++:探索AVL树旋转的奥秘

文章目录 前言 AVL树为什么要旋转&#xff1f;一、插入一个值的大概过程1. 插入一个值的大致过程2. 平衡因子更新原则3. 旋转处理的目的 二、左单旋1. 左单旋旋转方式总处理图2. 左单旋具体会遇到的情况3. 左单旋代码总结 三、右单旋1. 右单旋旋转方式总处理图2. 右单旋具体会遇…

文小言1:

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

uni-app 界面TabBar中间大图标设置的两种方法

一、前言 最近写基于uni-app 写app项目的时候&#xff0c;底部导航栏 中间有一个固定的大图标&#xff0c;并且没有激活状态。这里记录下实现方案。效果如下&#xff08;党组织这个图标&#xff09;&#xff1a; 方法一&#xff1a;midButton的使用 官方文档&#xff1a;ta…