资讯动态

C语言课程.8.1指针详解

发布时间:2026/10/26 18:15:07 来源:尧图企业网站定制
文章目录1. 内存和地址2. 指针变量和地址2.1 取地址操作符2.2 解引用操作符2.3 指针变量的大小3.指针变量类型的意义4.指针运算5. const 修饰指针6. 野指针的成因6.1 指针未初始化6.2 指针越界访问6.3 指针指向的空间释放7. assert 断言1. 内存和地址内存就是我们在运行时将数据存储的地方。一个比特位可以存储一个 2 进制的位 1 或者 0。计算机常见单位1Byte 8bit1KB 1024Byte1MB 1024KB1GB 1024MB1TB 1024GB1PB 1024TB而每一个内存都有其独一无二的地址。地址指针2. 指针变量和地址2.1 取地址操作符取地址操作符用于获取变量在内存中的实际地址。intmain(){inta10;printf(变量 a 的值是%d\n,a);printf(变量 a 的地址是%p\n,a);// %p 用于打印指针/地址格式化输出十六进制return0;}2.2 解引用操作符解引用操作符*用于访问指针所指向的内存地址中的内容。#includestdio.hintmain(){inta10;// 定义一个整型变量 a初始值为 10int*paa;// 定义一个指针变量 pa存储 a 的地址printf(a 的值%d\n,a);// 输出10printf(pa 存储的地址%p\n,pa);// 输出0x7fffffffe45c假设 a 的地址printf(pa 指向的内容%d\n,*pa);// 输出10读取地址处的值*pa20;// 修改 pa 所指向的内存中的值为 20printf(修改后 a 的值%d\n,a);// 输出20因为 a 被改变了printf(pa 存储的地址%p\n,pa);// 输出0x7fffffffe45c地址未发生改变return0;}int* pa a是将a的地址放在pa中。printf(%d , *pa);*pa的作用是读取pa存储的地址得到地址内存放的内容。*pa 20*pa的作用是读取pa存储的地址将地址中存放的内容改为 20。2.3 指针变量的大小指针变量的大小与类型无关只与平台有关。64 位机器 8 个字节32 位机器 4 个字节。#includestdio.h//指针变量的⼤⼩取决于地址的⼤⼩//32位平台下地址是32个bit位即4个字节/64位平台下地址是64个bit位即8个字节intmain(){printf(%zd\n,sizeof(char*));printf(%zd\n,sizeof(short*));printf(%zd\n,sizeof(int*));printf(%zd\n,sizeof(double*));return0;}3.指针变量类型的意义#includestdio.hintmain(){intn10;char*pc(char*)n;int*pin;printf(%p\n,n);printf(%p\n,pc);printf(%p\n,pc1);printf(%p\n,pi);printf(%p\n,pi1);return0;}我们可以看出char* 类型的指针变量 1 跳过 1 个字节int* 类型的指针变量 1 跳过了 4 个字节。结论指针的类型决定了指针向前或者向后走一步有多大距离。4.指针运算因为数组在内存中是连续存放的只要知道第一个元素的地址顺藤摸瓜就能找到后面的所有元素。intarr[10]{1,2,3,4,5,6,7,8,9,10};指针 ± 整数 指针#includestdio.h//指针- 整数intmain(){intarr[10]{1,2,3,4,5,6,7,8,9,10};int*xparr[0];inti0;intszsizeof(arr)/sizeof(arr[0]);for(i0;isz;i){printf(%d ,*(pi));//pi 这里就是指针整数}return0;}指针 - 指针 整数//指针-指针#includestdio.hintmy_strlen(char*s){char*xps;while(*p!\0)p;returnp-s;}intmain(){printf(%d\n,my_strlen(abc));return0;}5. const 修饰指针修饰指针一共有两种情况就接下来我们来讲解一下。#includestdio.h//代码1 - 测试无const修饰的情况voidtest1(){intn10;intm20;int*pn;*p20;//ok?pm;//ok?}//代码2 - 测试const放在*的左边情况voidtest2(){intn10;intm20;constint*pn;*p20;//ok?pm;//ok?}//代码3 - 测试const放在*的右边情况voidtest3(){intn10;intm20;int*constpn;*p20;//ok?pm;//ok?}//代码4 - 测试*的左右两边都有constvoidtest4(){intn10;intm20;intconst*constpn;*p20;//ok?pm;//ok?}intmain(){//测试无const修饰的情况test1();//测试const放在*的左边情况test2();//测试const放在*的右边情况test3();//测试*的左右两边都有consttest4();return0;}代码 1 没有影响代码 2 无法改变指针指向的值代码 3 无法改变指针的地址代码 4 均无法改变。声明名称指针本身指向的内容int *p普通指针可改可改const int *pint const *p指向常量的指针可改不可通过 p 改int * const p常量指针不可改可改6. 野指针的成因野指针就是指针指向的位置是不可知的随机的、不正确的、没有明确限制的。6.1 指针未初始化#includestdio.hintmain(){int*p;// 局部变量指针未初始化默认为随机值*p20;return0;}6.2 指针越界访问#includestdio.hintmain(){intarr[10]{0};int*parr[0];inti0;for(i0;i11;i){//当指针指向的范围超出数组arr的范围时p就是野指针*(p)i;}return0;}6.3 指针指向的空间释放#includestdio.hint*test(){intn100;returnn;}intmain(){int*ptest();printf(%d\n,*p);return0;}7. assert 断言需要assert.h用来调试当条件为假时会终止执行并报错。常用来判断是否为空指针。assert(ps!NULL);//assert(ps也对如果程序已经确认没有 BUG那么可以在 #include assert.h 之前加上 #define NDEBUG。#defineNDEBUG#includeassert.h这样就会将程序中的所有 assert 全部注释掉。缺点因为引入了额外的检查增加了程序的运行时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑