C语言-指针初学速成

1.指针是什么

C语言指针是一种特殊的变量,用于存储内存地址。它可以指向其他变量或者其他数据结构,通过指针可以直接访问或修改存储在指定地址的值。指针可以帮助我们在程序中动态地分配和释放内存,以及进行复杂的数据操作。在C语言中,指针操作是一项重要的基本操作,掌握指针的使用对于编写高效的C语言程序非常重要。

说通俗点:

1.指针是内存中一个最小单元的编号,也就是地址2.平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量总结:指针就是地址,口语中说的指针通常指的是指针变量。(把内存单元的编号就称为地址(地址也叫指针)指针其实就是地址,地址就是编号指针就是内存单元的编号)

指针和指针变量:

    

2.指针和指针类型

  • int p; -- 这是一个普通的整型变量
  •  int *p; -- 首先从 p 处开始,先与 * 结合,所以说明 p 是一个指针, 然后再与 int 结合, 说明指针所指向的内容的类型为 int 型。所以 p 是一个返回整型数据的指针。
  •  int p[3] -- 首先从 p 处开始,先与 [] 结合,说明 p 是一个数组, 然后与 int 结合, 说明数组里的元素是整型的, 所以 p 是一个由整型数据组成的数组。
  •  int *p[3]; -- 首先从 p 处开始, 先与 [] 结合,因为其优先级比 * 高,所以 p 是一个数组, 然后再与 * 结合, 说明数组里的元素是指针类型, 然后再与 int 结合, 说明指针所指向的内容的类型是整型的, 所以 p 是一个由返回整型数据的指针所组成的数组。
  •  int (*p)[3]; -- 首先从 p 处开始, 先与 * 结合,说明 p 是一个指针然后再与 [] 结合(与"()"这步可以忽略,只是为了改变优先级), 说明指针所指向的内容是一个数组, 然后再与int 结合, 说明数组里的元素是整型的。所以 p 是一个指向由整型数据组成的数组的指针。
  •  int **p; -- 首先从 p 开始, 先与 * 结合, 说是 p 是一个指针, 然后再与 * 结合, 说明指针所指向的元素是指针, 然后再与 int 结合, 说明该指针所指向的元素是整型数据。由于二级指针以及更高级的指针极少用在复杂的类型中, 所以后面更复杂的类型我们就不考虑多级指针了, 最多只考虑一级指针。
  •  int p(int); -- 从 p 处起,先与 () 结合, 说明 p 是一个函数, 然后进入 () 里分析, 说明该函数有一个整型变量的参数, 然后再与外面的 int 结合, 说明函数的返回值是一个整型数据。
  •  int (*p)(int); -- 从 p 处开始, 先与指针结合, 说明 p 是一个指针, 然后与()结合, 说明指针指向的是一个函数, 然后再与()里的 int 结合, 说明函数有一个int 型的参数, 再与最外层的 int 结合, 说明函数的返回类型是整型, 所以 p 是一个指向有一个整型参数且返回类型为整型的函数的指针。
  •  int *(*p(int))[3]; -- 可以先跳过, 不看这个类型, 过于复杂从 p 开始,先与 () 结合, 说明 p 是一个函数, 然后进入 () 里面, 与 int 结合, 说明函数有一个整型变量参数, 然后再与外面的 * 结合, 说明函数返回的是一个指针, 然后到最外面一层, 先与[]结合, 说明返回的指针指向的是一个数组, 然后再与 * 结合, 说明数组里的元素是指针, 然后再与 int 结合, 说明指针指向的内容是整型数据。所以 p 是一个参数为一个整数据且返回一个指向由整型指针变量组成的数组的指针变量的函数。


3. 尚未初始化的指针的含义

未初始化的指针变量就是“野”指针,它指向的是无效的地址。
出现野指针最典型的情形就是在定义指针变量之后没有对它进行初始化

指针指向某个对象之后,当这个对象的生命周期已经结束,对象已经消亡后,仍使用指针访问该对象,将出现运行时错误。考察如下程序。

#include <stdio.h>
int main(){
int*p;//指针未初始化,默认就是随机值printf("p=%d\n",*p);
//p是一个野指针,现在给他赋值可能会把它指向的内存区域数据破坏//会出现原本有用的内存数据被打乱 了。
*p=10;
printf("p=%d\n",*p);      return 0;

4. 指针运算

指针运算是针对指针(变量存储地址的变量)进行的运算操作。在程序中,指针可以通过加减操作来改变其值,这种操作就是指针运算。常见的指针运算有以下几种:

  1. 指针加法运算:可以将指针的值增加或减少若干个单位。例如,p + n 表示指针 p 的值增加 n 个单位,而 p - n 则表示指针 p 的值减少 n 个单位。

  2. 指针的自增和自减运算:可以将指针的值增加或减少一个单位。例如,p++ 表示指针 p 的值增加一个单位,而 p-- 则表示指针 p 的值减少一个单位。

  3. 指针的比较运算:可以比较两个指针的大小关系。例如,p1 > p2 表示指针 p1 的值大于指针 p2 的值,而 p1 < p2 则表示指针 p1 的值小于指针 p2 的值。

指针运算在许多编程语言中都是一种常见的操作,它可以用于实现数组、链表等数据结构,也可以用于动态内存分配和管理。但是需要注意的是,在进行指针运算时,要保证指针所指向的内存单元是有效的,否则可能会导致程序出现错误。

例1


5.指针和数组

指针与数组的关系

 1.当一个指针变量被初始化成数组名时,就说该指针变量指向了数组。如:

ptr被置为数组str的第一个元素的地址,因为数组名就是该数组的首地址,也是数组第一个元素的地址。此时可以认为指针ptr就是数组str(反之不成立),这样原来对数组的处理都可以用指针来实现。如对数组元素的访问,既可以用下标变量访问,也可以用指针访问。

2.指向数组元素的指针

  若有如下定义:

则pa=&a[0]是将数组第1个元素的地址赋给了指针变量pa。

实际上,C语言中数组名就是数组的首地址,所以第一个元素的地址可以用两种方法获得:pa=&a[0]或pa=a。

这两种方法在形式上相像,其区别在于:pa是指针变量,a是数组名。值得注意的是:pa是一个可以变化的指针变量,而a是一个常数。因为数组一经被说明,数组的地址也就是固定的,因此a是不能变化的,不允许使用a++、++a或语句a+=10,而pa++、++pa、pa+=10则是正确的。由此可见,此时指针与数组融为一体。

    例2

数组a中元素用下标表示为:
int *p = a;
*p,*(p+1),*(p+2),*(p+3),*(p+4)

①既然p是指向数组第一个元素起始地址的指针,可以用*(p+I)表示数组中第1+1个元索,a也是指向数组第一个元素的指针啊,那么能不能用*(a+1)表示第1+1个元素呢?
可以的,可以用printf 打印 *(a+i)的值验证
(②)反过来,a是指向数组第一个元素起始地址的指针,可以用a加数组下标引用数组元素,如a[3],p也是指向数组第一个元素起始地址的指
能不能用p加数组下标引用数组元素?计,也是可以的,可以用printf 打印 p[0],p[1]....的值验证PS: 由上得,数组名a和指针p是一样的。实际上编译时,数组元素a[i] 就是当作*(a+i)去处理的,先通过数组名a找到数组的首地址,然后首地址 a+i 得到元素a[i]的地址,
再然后通过*(a+i)得到第1个元素的内容。
所以:数组的第!个元索直接写成*(a+1)的形式直接取得值,效率不就提升了吗。省去编译器先通过数组名a找到数组的首地址,然后首地址 a+i 得到元素a[i]的地址,
再然后通过*(a+1)得到第1个元素的内容

6.二级指针

指针 可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针 ,或者 指向指针的指针 。


 

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

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

相关文章

冒泡排序法的名字由来,排序步骤是什么,最坏情况下的排序次数如何计算得来的呢?

问题描述&#xff1a;冒泡排序法的名字由来&#xff0c;排序步骤是什么&#xff0c;最坏情况下的排序次数如何计算得来的呢&#xff1f; 问题解答&#xff1a; 冒泡排序法的名字来源于排序过程中较大的元素会像气泡一样逐渐“冒”到序列的顶端&#xff0c;而较小的元素则会逐…

BI 数据分析,数据库,Office,可视化,数据仓库

AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 Mysql 8.0 54集 Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战&#xff0c; ETL Informatica 数据仓库案例实战 51集 Excel 2021实操 100集&#xff0c; Excel 2021函数大全 80集 Excel 2021…

谷歌掀桌子!开源Gemma:可商用,性能超过Llama 2!

2月22日&#xff0c;谷歌在官网宣布&#xff0c;开源大语言模型Gemma。 Gemma与谷歌最新发布的Gemini 使用了同一架构&#xff0c;有20亿、70亿两种参数&#xff0c;每种参数都有预训练和指令调优两个版本。 根据谷歌公布的测试显示&#xff0c;在MMLU、BBH、GSM8K等主流测试…

PostgreSQL与MySQL,谁更胜一筹

前言 PostgreSQL与MySQL都是优秀的开源数据库。在日常学习中&#xff0c;新手可能接触最多的是MySql,但是实际工作中&#xff0c;两者的应用场景其实都很广。我之前的做过上网流量销售业务&#xff0c;用的是MySQL,现在接触广告业务&#xff0c;用的是pg数据库&#xff0c;每天…

C# cass10 面积计算

运行环境Visual Studio 2022 c# cad2016 cass10 通过面积计算得到扩展数据&#xff0c;宗地面积 &#xff0c;房屋占地面积&#xff0c;房屋使用面积 一、主要步骤 获取当前AutoCAD应用中的活动文档、数据库和编辑器对象。创建一个选择过滤器&#xff0c;限制用户只能选择&q…

K8S—Pod详解

目录 一 Pod基础概念 1.1 Pod是什么 1.2 为什么要使用Pod&#xff1f;Pod在K8S集群中的使用方式&#xff1f; 1.3 基础容器pause 二 Pod的分类 2.1 自主式Pod和控制器管理的Pod 2.2 容器的分类 2.2.1 基础容器&#xff08;infrastructure container&#xff09; 2.2.2…

igolang学习3,golang 项目中配置gin的web框架

1.go 初始化 mod文件 go mod init gin-ranking 2.gin的crm框架 go get -u github.com/gin-gonic/gin 3.go.mod爆红解决

在word中将latex格式的公式转化为带有编号的mathtype公式

在word中将latex格式的公式转化为带有编号的mathtype公式 1.先在word里面配置好mathtype2.在word中设置mathtype的格式3.先将latex格式的公式转化为mathml格式4.读到这里&#xff0c;是不是觉得这个方法麻烦 1.先在word里面配置好mathtype 注意&#xff1a;1.word的版本应该是 …

【动态规划】【回文】【字符串】1147. 段式回文

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 本文涉及知识点 动态规划汇总 LeetCode1147段式回文 你会得到一个字符串 text 。你应该把它分成 k 个子字符串 (subtext1, subtext2&#xff0c;…&#xff0c; subtextk) &#xff0c;要求满足: subtext…

微服务-微服务Nacos配置中心

1.1 配置中心架构 1.2 Config Client源码分析 配置中心核心接口ConfigService public class ConfigServerDemo {public static void main(String[] args) throws NacosException, InterruptedException {String serverAddr "localhost";String dataId "naco…

汽车常识网:电脑主机如何算功率的计算方法?

今天汽车知识网就给大家讲解一下如何计算一台主机的功率。 它还会解释如何计算计算机主机所需的功率&#xff1f; &#xff1f; &#xff08;如何计算电脑主机所需的功率&#xff09;进行说明。 如果它恰好解决了您现在面临的问题&#xff0c;请不要忘记关注本站。 让我们现在就…

Elasticsearch:什么是 kNN?

kNN - K-nearest neighbor 定义 kNN&#xff08;即 k 最近邻算法&#xff09;是一种机器学习算法&#xff0c;它使用邻近度将一个数据点与其训练并记忆的一组数据进行比较以进行预测。 这种基于实例的学习为 kNN 提供了 “惰性学习&#xff08;lazy learning&#xff09;” 名…

2.5网安学习第二阶段第五周回顾(个人学习记录使用)

本周重点 ①多进程和多线程 1、进程和线程 2、多线程爆破 ②Redis数据库 1、Redis的使用 2、Redis持久化 3、Redis未授权免密登录 ③嗅探和Python攻击脚本 1、嗅探&#xff08;端口扫描和IP扫描&#xff09; 2、SCAPY的应用 3、Python攻击脚本&#xff08;SYN半连接…

前端数据可视化:ECharts使用

可视化介绍 ​  ​  应对现在数据可视化的趋势&#xff0c;越来越多企业需要在很多场景(营销数据&#xff0c;生产数据&#xff0c;用户数据)下使用&#xff0c;可视化图表来展示体现数据&#xff0c;让数据更加直观&#xff0c;数据特点更加突出。   ​  数据可视化主要目…

Qt_快速安装指南

下载Qt在线安装程序&#xff08;不仔细介绍&#xff09;注册Qt账号&#xff08;不仔细介绍&#xff09;使用快速运行的命令&#xff0c;按照指定的下载地址下载 在Qt指定目录打开cmd命令窗口.\eqt-unified-windows-x86-4.0.1-1-online. exe --mirror https://mirrors.ustc.edu.…

华清远见嵌入式学习——驱动开发——作业1

作业要求&#xff1a; 通过字符设备驱动分步注册过程实现LED驱动的编写&#xff0c;编写应用程序测试&#xff0c;发布到CSDN 作业答案&#xff1a; 运行效果&#xff1a; 驱动代码&#xff1a; #include <linux/init.h> #include <linux/module.h> #include &l…

代理模式笔记

代理模式 代理模式代理模式的应用场景先理解什么是代理&#xff0c;再理解动静态举例举例所用代码 动静态的区别静态代理动态代理 动态代理的优点代理模式与装饰者模式的区别 代理模式 代理模式在设计模式中是7种结构型模式中的一种&#xff0c;而代理模式有分动态代理&#x…

Nginx 配置前端工程项目二级目录

前提&#xff1a; 前端工程技术框架: vue 后端工程技术工程&#xff1a;spring boot 需求&#xff1a;需要通过二级目录访问前端工程&#xff1a; 如之前&#xff1a;http://127.0.0.1:80/ 改成 http://127.0.0.1/secondDirectory:80/ 一.前端工程支持二级目录 1.编译文…

(十八)devops持续集成开发——使用docker安装部署jenkins流水线服务

前言 本节内容介绍如何使用docker容器来部署安装jenkins流水线服务。关于docker容器的安装本节内容不做介绍。请读者提前安装。 正文 ①使用docker查找jenkins官方镜像 ② 拉取jenkins官方镜像jenkins/jenkins&#xff0c;选择一个最新稳定版本&#xff0c;避免一些插件不兼…

15.一种坍缩式的简单——组合模式详解

当曾经的孩子们慢慢步入社会才知道&#xff0c;那年味渐淡的春节就像是疾驰在人生路上的暂停键。 它允许你在隆隆的鞭炮声中静下心来&#xff0c;瞻前顾后&#xff0c;怅然若失。 也允许你在寂静的街道上屏气凝神&#xff0c;倾听自己胸腔里的那团人声鼎沸。 孩子们会明白的&am…