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

深入理解指针---1

(一)什么是指针

指针就是存放变量内存地址的变量 怎么理解呢

我们电脑的内存分为8GB,16GB,32GB等等,而内存也被划分成一个个的内存单元,每个内存单元的大小取一个字节,每个内存单元就相当于一个学生宿舍,一个字节空间里又能放8个比特位,就像我们宿舍是8人间,每个人是一个比特位,每个内存单元都有一个编号,就相当于宿舍的门牌号,而这个编号就等于地址等于指针

(二)取地址操作符&

在c语言中创建变量本质上就是向内存申请空间,比如创建一个整型变量如下

int a=10;

一个整型变量占4个字节,就是向内存申请了4个字节,每个字节都有自己的地址,如下所示

那么如何取到a的地址呢,这里我们就在需要用到取地址操作符&,&在之前使用scanf函数也是经常用到,表示取这个数据的地址 ,怎么将地址打印出来呢,这里需要用到之前学到的占位符%p,比如将上述整形a的地址打印出来,如下所示

#include <stdio.h> int main() { int a=10; &a;//取出a的地址 printf("%p",&a); return 0; }

这里整型a明明占了4个字节,为什么只打印出来一个地址,因为&a取出的是4个字节中地址较小的字节的地址

(三)指针变量的创建和类型

在上述过程中我们得到了a的地址,那么为了后续使用,怎么样将它存储起来,这时候我们就可以将它存储在指针变量中 如下所示

int a = 10; int* pa = &a;//取出a的地址,将其放入指针变量pa中

那么上述代码中的指针变量类型是什么,首先pa左边的int*,它在常规的整型变量中加了一个*,而*就表示pa是指针变量,而前面的int指pa指向的a是一个整型类型 那如果有一个char类型的b,那么该如何创建指针变量呢?如下所示

char b='a'; char*pc=&b;//取出字符b的地址,将其放入指针变量pc中

(四)指针变量的使用

我们通过指针变量将地址给存储起来,那么又该如何使用呢? 这时候我们就需要用到解引用操作符*,具体操作如下所示

int a = 10; int* pa = &a; *pa;//解引用,通过pa中存放的地址,找到指向的空间,所以这里的*pa就相当于a printf("%d", *pa);

打印出来的*pa就是a的值

也可以通过修改*pa的值来修改a的值,如下所示

可以看出,不仅*pa的值变成199,a的值也同样修改为199

(五)指针变量类型的意义

1.指针的解引用

下面我们通过两段代码来理解指针变量的意义

int a = 0x11223344;//整型a存放的是16进制的数字 int* pa = &a; * pa = 0;将整型a的4个字节改成0

原来a在内存中存放的值如下

修改完之后如下

可以看出将4个字节全部修改成0

然而当我们创建char类型的变量时

int a = 0x11223344; char* pa = (char*) & a; * pa = 0;

可以看出只能将a的第一个字节改成0

所以指针的类型决定了指针解引用时的权限,char*类型就只能访问一个字节,而int*类型的指针就可以访问4个字节

2.指针+-整数

通过上述的例子我们可以得知指针类型的不同,访问的字节也不同,我们可以再举一例,如下方代码

int a = 10; int* pa = &a; char* pc = (char*)&a; printf("&a=%p\n", &a); printf("pa=%p\n", pa); printf("pa+1=%p\n", pa+1); printf("pc=%p\n", pc); printf("pc+1=%p\n", pc+1);

我们可以看出,char类型的指针+1之后在原来的基础上地址只变化了一位,而int类型的指针+1之后则在原来的基础上变化了4位,所以可以得知,指针的类型决定了指针变化了多少位。

那么我们可以再做个练习,用指针将数组中的元素依次打印出来,如下代码所示

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); int i = 0; int* pa = &arr[0]; for (i = 0; i < sz; i++) { printf("%d ", *(pa + i)); }

pa表示的是取的是arr数组中第一个元素的地址,那我们只需要依次求出arr数组中元素的地址,再使用解引用符号*,我们就可以依次得出arr数组中的元素

3.指针+-指针

用以下代码举例

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* pa = &arr[0]; int* pc = &arr[9]; printf("%d", pc-pa);

指针-指针最终得到的结果就是两个指针(地址)之间的元素个数

⚠️:指针+-指针必须指向的是同一内存空间,像上方的代码中,指向的都是arr数组,下方代码为错误示范

int arr[4] = { 1,2,3,4 }; char b = 'e'; int* pa = &arr[2]; char* pc = &b; printf("%d", pc - pa);

我们可以用指针-指针来求字符串长度,在之前,不用指针如何求字符串长度的呢,我们需要用到strlen函数,并且strlen函数的返回值是size_t,且需要头文件<string.h>,如下所示

#include <stdio.h> #include <string.h> int main() { char ch[] = "abcde"; size_t len = strlen(ch); printf("%d", len); return 0; }

那么我们现在知道指针-指针就是两个指针之间的元素个数,那么我们可以分别求出字符串长度中第一个元素的地址,和’/0’的地址,将两个指针(地址)相减,就能得到字符串长度了,如下代码所示

size_t my_strlen(char* p)//指针接受参数 { char* start = &p[0];//start取ch数组第一个元素的地址 while (*p != '\0') { p++; } //p最终变成\0的地址 return p - start; } int main() { char ch[] = "abcde"; size_t len = my_strlen(ch);//函数传递的是ch数组,其实ch又代表ch数组中第一个元素的地址 printf("%d", len); //所以传递的是地址,需要用指针来接受参数 return 0; }
4.指针的关系运算

两个指针比较大小,我们依旧拿我们最熟悉的题目举例,打印出数组中的每个元素,如下代码所示

int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); int* pa = arr; int* pc = &arr[sz]; while (pa < pc) { printf("%d ", *pa); pa++; } return 0; }

上述代码中,pa表示第一个元素的地址,而pc表示数组中的第十个元素的后一位的地址,不是数组内的,所以当pa<pc时,解引用打印出元素,再通过pa++,依次打印后面的元素

http://www.jsqmd.com/news/1016740/

相关文章:

  • 晋中市黄金回收门店推荐 五家靠谱店铺TOP排行榜及联系方式地址电话+白银回收+铂金回收+彩金回收当场结算 - 大熊猫898989
  • 数据科学落地七宗罪:从模型到业务价值的实战避坑指南
  • 直播预告!从 MLA 到 GQLA:无需从头训练,硬件自适应高效注意力机制
  • 宁波市五家靠谱店铺TOP排行榜及联系方式地址+黄金回收门店推荐 电话+白银回收+铂金回收+彩金回收当场结算 - 盛世金银回收
  • 2026 居家轻健身|每周 3 小时,无痛坚持,练出紧致好状态✨
  • 2026年浙江定制集装箱处置方案深度测评:技术路径、成本控制与落地案例全解析 - 优质品牌商家
  • 告别混乱配置:在Flask/Django项目中优雅管理config.py(附解决导入错误的实战技巧)
  • 多维聚合操纵:从OLAP立方体到动态分析引擎
  • React状态管理深度辨析:Context、Redux、Zustand核心区别与实战选型
  • 解决CH32V307以太网项目痛点:DHCP网线热插拔与IP耗尽问题的LwIP底层修改详解
  • 宁德市五家靠谱店铺TOP排行榜及联系方式地址+黄金回收门店推荐 电话+白银回收+铂金回收+彩金回收当场结算 - 盛世金银回收
  • 手把手调试USB PD:用逻辑分析仪抓包分析Reset全过程(附Wireshark配置)
  • 靠谱的超市收银系统公司 - myqiye
  • Mythos架构解析:模块化推理与门控式能力释放
  • Aspose.Words for Python避坑指南:提取Word文本时,书签、注释和字段怎么处理?
  • 多维聚合数据操纵:分层聚合、条件聚合与窗口重标定实战
  • 避开这些坑!Arduino驱动42步进电机时,TB6600接线与代码的5个常见误区
  • AWS数据湖实战:从S3分层设计到可信数据交付
  • HT1632C驱动IC的“暗黑”操作:避开C51/Arduino时序编程的5个常见坑
  • 荆门市黄金回收门店推荐 五家靠谱店铺TOP排行榜及联系方式地址电话+白银回收+铂金回收+彩金回收当场结算 - 大熊猫898989
  • WordPress网站突然报403?可能是.htaccess在捣鬼,试试这个一键生成方法
  • 2026年西北风管加工市场观察:哪家工厂更懂你的通风工程需求? - 优质品牌商家
  • 2026年分析本地哪个位置能成批采购酒店窗帘 - myqiye
  • P1342 请柬【洛谷算法习题】
  • 避坑指南:Android自定义悬浮窗/系统弹窗开发,那些WMS权限校验与WindowToken的坑
  • 荆州市黄金回收门店推荐 五家靠谱店铺TOP排行榜及联系方式地址电话+白银回收+铂金回收+彩金回收当场结算 - 大熊猫898989
  • Gmail-邮件自动处理系统
  • Python代码考古学:逆向工程工作流实战指南
  • 攀枝花市五家靠谱店铺TOP排行榜及联系方式地址+黄金回收门店推荐 电话+白银回收+铂金回收+彩金回收当场结算 - 盛世金银回收
  • 生产环境避坑实录:银河麒麟服务器bond双网卡绑定后,网络延迟飙升怎么办?