当前位置: 首页 > news >正文

C语言—再学习(指针)

一、指针是什么?                                                                               

指针是一种在计算机编程中用于存储和操作内存地址的变量。

指针变量中存储的是内存地址,而不是数据本身。通过指针,程序可以直接访问和操作内存中的特定位置,这使得程序员能够更灵活地管理内存,实现对数据的高效访问和修改。

它可以用于在函数之间传递数据、动态分配内存、实现数据结构(如链表、树等)以及优化程序的性能。

注:整型变量分配4个字节、单精度浮点型变量分配4个字节字符型变量分配1个字节

注:数据的分配是分类型的,对不同类型的数据,在内存中分配的存储单元大小,和存储方式是不同的。为了有效存取数据需要位置信息之外,还需要有改数据的类型信息。

例:若有int类型的变量a,和float类型变量b。若先后把它们分配在2000开始的存储单元中,&a和&b的信息完全相同吗?  答案是不相同的,虽然编号相同,但是数据类型不同

二、指针的存取                                                                                   

printf ("%d", &i) ;

在此之前系统已经为 i 分配了按整型存储方式的4个字节。并建立了对应的变量名和地址的对应表。在执行上面语句时——首先通过变量名找到对应的地址,从该4个字节中按照整型数据的存储方式读出整型变量 i 的值,然后按十进制整数格式输出。

scanf("%d",&i);

执行时,把键盘输入的值送到地址为2000开始的整型存储单元中。

这种直接按变量名进行的访问,称为:直接访问

当然也可以:间接访问

i_pointer = &i;  //将 i 的地址存放在i_pointer中,i_pointer的值就是2000 

在此处i_pointer就是    指针变量     ,指针变量的值是地址

三、定义指针变量

一般形式:类型名  * 指针变量名

例如:int *pointer_1, *pointer_2;

int是定义指针变量必须指定“基类型”

注意⚠️:指针变量中只能存放地址,不能存放整数

*pointer_1=100;   //不合法!

四、引用指针变量

(1)给指针变量赋值

p=&a;    //把a的地址赋值给指针变量p

(2)引用指针变量指向的变量

在(1)的基础上:

printf("%d", *p);  //其作用是以整数形式输出指针变量p所指向的变量的值,即a的值

这里*p代表的是一个整数值

*p = 1; //表示将整数1赋给p当前所指的变量,也就是a=1

 (3)引用指针变量的值

printf("%o",p);    //表示输出指针变量p的值,如果p指向a,那就是输出a的地址值,即&a。

1⚠️:     &  取地址运算符,&a是变量a的地址。

2⚠️:     *   指针运算符。*p代表指针变量p指向的对象。

例题:输入两个整数a、b。按大小输出a、b

五、指针变量作为函数参数

还是做两个数交换,例题:

 swap函数表示,传入两个指针变量,进行交换,其中中间值是一个整形变量!所以说交换的是两个地址里面的值

在main函数里定义两个int型指针变量,并且分别指向a、b。如果符合条件就交换两个地址里面的值。此时a、b里面的值已经被换了。

⚠️:swap函数里面的中间变量是指针可以吗?

⚠️:swap函数如果不是用指针来传参,用形参x、y可以吗?

六、通过指针引用数组

所谓数组元素的指针就是数组元素的地址

int a[10] = {1,3,5,7,9,11,13,15,17,19};//定义a为包含10个整型数据的数组
int *p;                                //定义p为指向整型变量的指针变量
p = &a[0];                             //把a[0]元素的地址赋给指针变量p

第三行的p代表是一个地址值!  

  • 数组名代表数组中首元素的地址,因此下面两个语句等价
p = &a[0];  //p的值是a[0]的地址
p = a;      //p的值是数组a首元素(即a[0])的地址
  • 引用一个数组元素,可以使用下面两种方法:

               <下标法,如a[i]  形式。

               <指针法,如 * (a+i)或 *(p+i)

  • 在使用数组元素时指针的运算:

   <指针可以进行加减运算,其结果会根据指针类型自动调整。

int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr;  // 指向数组首元素ptr + 2;  // 指向arr[2](偏移2*sizeof(int)字节)
ptr - 1;  // 指向arr[-1](需确保地址有效)

<通过修改指针值可以遍历数组:

for (int i = 0; i < 5; i++) {printf("%d ", *ptr);  // 输出当前元素ptr++;  // 指向下一个元素
}

<两个同类型指针相减得到元素个数的差值:

int *p1 = &arr[0];
int *p2 = &arr[3];
printf("%d", p2 - p1);  // 输出:3

分析:*(p++)与*(++p)的作用

*(p++):先取*p的值,然后使p加1。 相当于a[i++]

*(++p) :先使p加1 ,再取*p    ,相当于a[++i]                 

相关文章:

  • AI 产业化浪潮:从生成智能到星载计算,中国如何重塑全球竞争格局
  • 力扣算法ing(70 / 100 )
  • Python爬虫实战:研究进制流数据,实现逆向解密
  • Protocol Buffers 全流程通俗讲解
  • DHCP协议
  • 基于 NanoDet 的工厂巡检机器人目标识别系统研究与实现​
  • 基于RFSOC ZU28DR+DSP 6U VPX处理板
  • CPS联盟+小程序聚合平台分销返利系统开发|小红书番茄网盘CPA拉新推广全解析
  • 使用matlab进行数据拟合
  • 【操作系统期末速成】①操作系统概述
  • 紫光同创FPGA实现AD9280数据采集转UDP网络传输,分享PDS工程源码和技术支持和QT上位机
  • 基于IMX429-IMX430-IMX432-IMX437等sensor的SLVS桥MIPI透传模组方案
  • DA14531如何在固件中生成与时间相关的mac和版本号
  • 半成品的开源双系统VLA模型,OpenHelix-发表于2025.5.6
  • 【Vue.js 的核心魅力:深入理解声明式渲染】
  • AG-UI:AI 用户交互协议,解决了Agent与前端应用连接和通信的问题
  • 数学复习笔记 8
  • LeRobot 框架的核心架构概念和组件(上)
  • 【Java基础】HashTable 和 ConcurrentHashMap 的区别与使用
  • 【测试】BUG
  • 秦洪看盘|指标股发力,A股渐有突破态势
  • 上海北外滩开发建设五周年交出亮眼答卷,未来五年有何新目标?
  • 事关心脏健康安全,经导管植入式人工心脏瓣膜国家标准发布
  • 王毅会见巴西外长维埃拉、总统首席特别顾问阿莫林
  • 海北州委常委、常务副州长桑本履新青海省供销社理事会主任
  • 4月国产新能源,降价潮迈入拐点