C:指针学习(1)-学习笔记
目录
前言:
知识回顾:
1、const
1.1 const修饰普通变量
1.2 const修饰指针变量
1.3 总结:
2、指针运算
2.1 指针+-整数
2.2 指针-指针
2.3 指针的关系运算
3、指针的使用
结语:
前言:
距离上一次更新关于初识指针的内容已经有一段时间了,本文旨在继续深入探讨指针的相关知识。在引入新的知识点之前,让我们先对之前介绍过的内容进行一个简要的回顾。
上一篇中我们主要介绍了内存和地址,什么是指针、指针变量,指针类型以及void*的用法
知识回顾:
1.内存和地址:内存类似宿舍楼,房间是内存单元,数据是房间里的人,门牌号是地址,计算机通过地址管理内存,编址由硬件设计完成。
2.指针变量和地址:通过(&)取地址操作符获取地址,可将地址存储在指针变量中,指针类型如int ,解引用操作符(*)用于操作指针指向的对象,指针变量大小取决于地址大小,与指针类型无关。
3.指针变量类型的意义:指针类型决定了解引用时的权限和指针移动的距离。
4.void*指针:可以接受任意类型地址,但不能直接进行指针运算,常用于存放地址并通过强制类型转换进行解运算。
接下来这篇文章将会讲到一个关键字const,指针运算,以及指针的使用和传址调用
1、const
const是一个关键字,一般用来做两件事:
- const修饰普通变量
- const修饰指针变量
1.1 const修饰普通变量
#include <stdio.h>
int main()
{int n = 0;//变量初始化n = 20;//修改变量的值printf("%d\n", n);return 0;
}
结果:原来是0的值可以修改为20.这就是变量
如果加上const呢?const int n = 0;

当被const修饰后,该程序就无法实现了,为什么呢?
const被称为长属性—被const修饰后的变量就具有长属性,长属性的意思就是不能被修改。
但是如果我们不修改变量的值,直接使用是否可以?
int main()
{const int n = 0;//n = 20;printf("%d\n", n);return 0;
}

结果肯定是可以的,被const修饰的变量可以打印,但是当你要修改它的值的时候,程序就无法实现了。
那么被const修改后的变量被认为是变量还是常量呢?
在C语言中,被const修饰后的变量被称为长变量,它的本质还是变量,因为有const修饰,编译器在语法上不允许修改这个变量。
在c++语言中,被const修饰后的变量被称为常量。
知道这个有什么用呢?

在C99之前,编译器是不支持变长数组作为数组大小的,因此,这里由于n的本质还是变量,因此无法实现(在C语言上)
如果我们改为c++呢?

当我们将文件后缀改为c++后,由于在c++中,被const修饰的变量的本质是常量,所以这里数组的大小就可以使用 n 来表示。
作用:当以后你写一个变量但是不希望别人修改的话,就可以使用const来修饰
注意:const位置放在函数类型(int)的前面或者后面都是可行的,不过习惯上我们都放在前面。
1.2 const修饰指针变量
前面我们说被const修饰后的变量不能被修改,但是如果我们就想要去修改并且还并不想删去const,该怎么办呢?
#include <stdio.h>
int main()
{const int n = 0;//n = 20;int* p = &n;*p = 20;printf("%d\n", n);return 0;
}
上诉代码中,我们通过取到n的地址来修改n的值,是否可行呢?

我们发现可以修改了。
不过,虽然我们得到了想要的结果,但是你们有没有觉得上诉代码有一些奇怪?
我们为什么要在变量n前面加上const呢?不就是为了防止变量n的值被修改吗?但是这里我们又通过指针的方式将n的值修改。这就像现实生活中,我这里有一个房子,你不能翻窗户进去,只能从正门进去,但是某一天呢,我有事不在家,就把房门锁上了,你无法从正门进去了,于是你把窗户砸了,从窗户爬进去了。
上面通过指针的操作就破坏了const修饰变量的目的。
为了防止这种情况,我们就需要用const来修饰指针变量。
我们应该怎么做呢?
const修饰指针变量有三种方式:
int * pconst可以放在*的左边,也可以放在*的右边,也可以左右两边都放上const
不管是const int * p 还是int const * p 都算放在*的左边
三种情况:
1.const放在*的左边:int const * p2.const放在*的右边:int * const p
3.comst放在*的两边:const int * const p
1. const放在*的左边:int const * p
关于对 p 的理解
int n = 10;
int* p = &n;
p里存放的是n的起始地址,通过p可以找到n,如果像修改n的值,我们无非就是两种方式
一种通过修改p的值来修改n:p = &m ,通过将m的地址给到p,然后修改n的值
另一种通过p找到n来直接修改n的值:*p = 200;
当我们能够对p有这样的理解后,我们在来看 const放在*的左边的时候,限制的是p变量本身,还是p指向的内容。
代码展示:
#include <stdio.h>
int main()
{const int n = 0;int m = 100;const int* p = &n;p = &m; //可行*p = 100;//不可行printf("%d\n", n);return 0;
}

可以看到p = &m;是可执行的,而*p = 100;则会报错。
所以当const放在*的左边的时候,限制的是*p,也就是说不能通过p找到n的值来修改n的值
const放在*的左边的意思是:表示指针指向的内容,不能通过指针来改变了,按时指针变量本身的值是可以改的。
2. const放在*的右边:int * const p
int main()
{const int n = 0;int m = 100;int* const p = &n;p = &m; //不可行*p = 100;//可行printf("%d\n", n);return 0;
}

当const放在*的右边后, p = &m是无法执行的。而*p = 100则是可以执行的。说明const放在*的右边限制的是p本身。
const放在*的右边的意思:表示指针变量p本身不可以修改了,但是指针指向的内容是可以通过指针变量来改变的。
如果想限制p,就放在*的右边,如果想限制p所指向的内容,就放在*的左边。
3 .comst放在*的两边:const int * const p
这个意思就是指针变量p不能被修改,指针变量p指向的内容也不能被修改。

1.3 总结:
- const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。 但是指针变量本身的内容可变。
- const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指 向的内容,可以通过指针改变。
2、指针运算
指针的基本运算分为三类,分别是:
- 指针+-整数
- 指针-指针
- 指针的关系运算
2.1 指针+-整数
数组在内存中是连续存放的,因此,只要知道第⼀个元素的地址,顺藤摸瓜就能找到后面的所有元素。

当我们拿到首元素地址,我们可以将后面的都拿到吗?

int main()
{int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int* p = &arr[0];//获得第一个元素的地址int sz = sizeof(arr) / sizeof(arr[0]);//求元素个数for (int i = 0; i < sz; i++){printf("%d ", *(p + i));//指针+整数}return 0;
}
打印结果:

当我们知道数组第一个元素的地址,就可以通过指针加减整数的方式得到其它的元素。
2.2 指针-指针
指针就是地址,所以指针减指针就是地址减地址,那指针减指针有什么用处呢?
指针-指针得到的是两个指针间的元素个数
int main()
{int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; printf("%d ", &arr[9]-&arr[0]);return 0;
}
结果展示;

指针式分大小的,大的指针减小的指针得到的是正数,小的减大的是负数
总结:指针-指针的绝对值是两指针间的元素个数。
前提条件:两个指针指向同一块空间才能相减。也就是需要指向同一个数组才能相减。
2.3 指针的关系运算
在前面介绍数组的时候,有说过一个知识点:数组随着下标的增长,地址是由低到高变化的
比如说我们想打印下面这个数组中的元素
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]);while (p < &arr[sz])//p是起始地址,随着下标增长,地址也会变高,因此起始地址肯定低于后面的地址{printf("%d ", *p);p++;} return 0;
}
通过大小关系我们可以打印出该数组的所以元素。

3、指针的使用
指针是一种用于存储变量地址的特殊变量,通过它可以间接访问和操作所指向的内存空间中的数据。
通过前面的学习我们也了解了指针的一些相关知识,那么指针的使用包含哪几个方面呢?
1.声明指针:使用特定的类型声明指针变量,比如 int * p;表示声明一个指向整数的指针。
2.赋值:可以将变量的地址赋值给指针,比如 *p = &n;表示将n的地址赋给p,从而改变指针p所指向的值。
3.解引用:通过解引用指针可以访问指针所指向的变量,例如*p = 100;表示将指针所指向的整数赋值为100.
4.指针运算:可以对指针进行加减运算,以移动指针指向不同的内存位置。
结语:
本篇文章主要介绍了一个关键字const修饰变量的作用,以及指针的运算和指针的使用。关于指针的传址调用的介绍,在函数篇那里就已经介绍的比较完善了,如果有想了解了可以看一看。
C语言函数:编程世界的魔法钥匙(1)-学习笔记-CSDN博客
下期再见!!!
相关文章:
C:指针学习(1)-学习笔记
目录 前言: 知识回顾: 1、const 1.1 const修饰普通变量 1.2 const修饰指针变量 1.3 总结: 2、指针运算 2.1 指针-整数 2.2 指针-指针 2.3 指针的关系运算 3、指针的使用 结语: 前言: 距离上一次更新关于初…...
【LVS】负载均衡之NAT模式
一、LVS概念 LVS(Linux Virtual Server)是一个基于Linux操作系统的虚拟服务器技术,用于实现负载均衡和高可用性。LVS通过将客户端的请求分发到多台后端服务器上,从而提高整体服务的处理能力和可靠性。 二、LVS优势 高性能&…...
ASP.NET Core 基础 - 入门实例
一. 下载 1. 下载vs2022 Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 (microsoft.com) 学生,个人开发者选择社区版就行,免费的. 安装程序一直下一步下一步就行,别忘了选择安装位置,如果都放在C盘的话,就太大了. 2. 选择工作负荷 准备工作完成 二. 创建新项目 三…...
机器人主板维修|ABB机械手主板元器件故障
【ABB机器人电路板故障原因诊断】 针对上述故障现象,我们需要对ABB机器人IO板进行详细的故障诊断。以下是一些可能的故障原因: 1. 元器件老化或损坏:ABB机械手安全面板上的元器件在长期使用过程中可能出现老化、损坏或接触不良等问题…...
大数据Flink(一百零六):什么是阿里云实时计算Flink版
文章目录 什么是阿里云实时计算Flink版 一、产品概述 二、产品架构 三、产品优势 什么是阿里云实时计算Flink版 阿里云实时计算Flink版是一套基于Apache Flink构建的⼀站式实时大数据分析平台,提供端到端亚秒级实时数据分析能力,并通过标准SQL降低业…...
ERCOT中的专业术语解释
在ERCOT中,ECRSM 代表的是 “Emergency Contingency Resource Supplementary Market”。这个术语涉及到紧急备用资源市场,用于应对电力需求或供应的紧急情况。在ERCOT电网中,当系统面临极端情况或资源不足时,ECRSM 可以帮助确保电…...
Python酷库之旅-第三方库Pandas(069)
目录 一、用法精讲 276、pandas.Series.dt.is_quarter_start属性 276-1、语法 276-2、参数 276-3、功能 276-4、返回值 276-5、说明 276-6、用法 276-6-1、数据准备 276-6-2、代码示例 276-6-3、结果输出 277、pandas.Series.dt.is_quarter_end属性 277-1、语法 …...
基于hutools的国密SM2、3、4
文章目录 前言一. 代码 前言 最近还要深度研究hutools底层实现,一定要搞透澈,本章将会是持续更新 参考资料: Java代码实现SM2算法以及注意点总结(踩坑记录) 国密算法工具Smutil 一. 代码 import cn.hutool.core.uti…...
进程的等待(非阻塞轮询+阻塞)和替换控制详解
引言 在Linux系统中,进程管理是核心功能之一。理解进程的创建、执行和终止是系统编程中的基础。本文将深入探讨Linux中的进程控制机制,包括进程的生命周期、父子进程的交互、以及进程状态的管理 1. 进程创建:fork()函数 在Linux操作系统中…...
24/8/6算法笔记 支持向量机
支持向量机(Support Vector Machine, SVM)是一种监督学习算法,主要用于分类和回归任务。它基于统计学习理论中的结构风险最小化原理,通过找到数据点之间的最优边界来实现模型的泛化能力。 import numpy as np import matplotlib.…...
测试用例等级划分
基本等级(Level 1或P0):这类用例设计系统基本功能,执行失败会导致多处重要功能无法运行。例如,单表维护中的增加功能、最平常的业务使用等,这些是发生概率较高的功能用例。这类用例在每一…...
打造Perl编译器前端:自定义语言处理的魔法
打造Perl编译器前端:自定义语言处理的魔法 Perl是一种强大而灵活的编程语言,它提供了丰富的文本处理能力,使其成为实现自定义编译器前端的理想选择。编译器前端通常负责源代码的词法分析、语法分析和语义分析。本文将详细介绍如何在Perl中实…...
Visual Studio 和 Visual Studio Code 的比较与应用偏向
Visual Studio 和 Visual Studio Code(VS Code)是微软开发的两个不同的开发工具,各有特点和优势,适用于不同的开发需求。下面是详细的比较和在实际应用中的偏向。 功能和特性 Visual Studio 完整的IDE:支持多种编程…...
Python打开JSON/CSV文件的正确方式(针对UnicodeDecodeError)
前言 我们在使用python的过程中,经常需要它完成一些数据处理的工作,其中尤以json/csv文件为常见。今天,博主针对UnicodeDecodeError异常进行试验,因为这个是新手最容易犯错的地方。 Q:如何应对 UnicodeDecodeError 读…...
深入解析TikTok广告开户白名单:规范与申请指南
在TikTok的广告平台上,白名单(Whitelist)系统作为一种重要的审核和管理机制,对广告账户的开设与运营起着至关重要的作用。 一、什么是TikTok广告开户白名单? 白名单的定义 白名单是一种预先批准的账户或广告内容列表…...
CSS技巧专栏:一日一例 19 -纯CSS实现超酷的水晶按钮特效
CSS技巧专栏:一日一例 19 -纯CSS实现超酷的水晶按钮特效 今天给大家分享一个纯CSS按钮水晶按钮,效果很赞,希望对大家有所帮助。 本例图片 案例分析 这个按钮看起来效果很赞,我们分析一下它由几个层组成: 1. 按钮本体:渐变层+按钮文字 2.用before伪元素实现高光层+内…...
ArcGIS基础:基于数据图框实现地理坐标系下不同投影转换的可视化效果
ArcGIS默认以第一次加载数据的坐标系决定整个工程的坐标系 可以通过改变数据框的投影坐标系,对地理数据进行快速投影变换,以可视化展示不同投影坐标系下的地理数据形状和形态 对数据框坐标系的改变,只是针对的显示参数的改变,并…...
⚡4. Kubernetes核心资源管理操作实战
文章目录 kubectl [command] [TYPE] [NAME] [flags]kubectl run 资源名称 --image镜像名称 --port端口号kubectl create -f 配置文件名称.yaml kubectl apply -f 配置文件名称.yaml快速编写yaml文件,通过命令导出新的yaml文件Kubernetes常见资源类型和缩写 kubectl …...
【Wireshark 抓 CAN 总线】Wireshark 抓取 CAN 总线数据的实现思路
最近看到一个帖子 Wireshark 对接 Windows 系统命名管道,抓取数据 我突然想到一个很有意思的方式 你没看错 用 Wireshark 来抓取 CAN 总线数据 【其实 Wireshark 上有 CAN 总线的的解码器,不信你可以在表达式栏打 can 试下,是有这个解码器的】…...
Linux网络编程3
并发服务器 1.TCP多进程并发服务器 服务器端: 客户端: 2.TCP多线程服务器 服务器端: 客户机端: 需要学习的函数还有 1. send() 函数 send() 函数用于在套接字上发送数据。它是网络编程中发送数据到对端的主要函数之一。 函数…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

