制作网站服务器,h5手机端页面开发,网站建站模版,宁波本地抖音seo推广你是真的“C”——详解指针知识#x1f60e;前言#x1f64c;1、 指针是什么#xff1f;#x1f64c;2、指针和指针类型#x1f64c;2 、1指针-整数2 、 2指针的解引用3、 野指针#x1f64c;3、 1野指针成因3、 2如何规避野指针4、指针运算#x1f64c;4、1 指针-整数4…
你是真的“C”——详解指针知识前言1、 指针是什么2、指针和指针类型2 、1指针-整数2 、 2指针的解引用3、 野指针3、 1野指针成因3、 2如何规避野指针4、指针运算4、1 指针-整数4、2 指针-指针4、3 指针的关系运算5、指针和数组6 、 二级指针7、指针数组总结撒花博客昵称博客小梦 最喜欢的座右铭全神贯注的上吧 作者简介一名热爱C/C算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主 博主小留言哈喽各位CSDN的uu们我是你的博客好友小梦希望我的文章可以给您带来一定的帮助话不多说文章推上欢迎大家在评论区唠嗑指正觉得好的话别忘了一键三连哦 前言 哈喽各位友友们我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下我仅已此文和大家分享C语言中指针相关的知识点~ 都是精华内容可不要错过哟 1、 指针是什么
在学习指针之前首先要知道指针是什么其实指针理解起来可以概括为一下两个要点
指针是内存中一个最小单元的编号也就是地址平时口语中说的指针通常指的是指针变量是用来存放内存地址的变量 总结指针就是地址口语中说的指针通常指的是指针变量。指针变量我们可以通过取地址操作符取出变量的内存起始地址把地址可以存放到一个变量中这个变量就是指针变量 。
举个栗子辅助理解
#include stdio.h
int main()
{int a 10;//在内存中开辟一块空间int* p a;return 0;}知识点分析
这里我们对变量a取出它的地址可以使用操作符。a变量占用4个字节的空间这里是将a的4个字节的第一个字节的地址存放在p变量中p就是一个之指针变量。
小结一下 指针变量用来存放地址的变量。存放在指针中的值都被当成地址处理。 那么一个内存单元要分配多大的空间呢又是怎么对这些内存进行编地址的呢无数的先辈对此进行探讨分析最终认为一个内存单位分配一个字节并分配一个地址是比较合适的。对于32位的机器假设有32根地址线那么假设每根地址线在寻址的时候产生高电平高电压和低电平低电压就是1或者0。那么这里就有2的32次方个地址。同样的方法那64位机器如果给64根地址线那能编址就有2的64次方的地址。 简单的概括来说 在32位的机器上地址是32个0或者1组成二进制序列那地址就得用4个字节的空间来存储所以 一个指针变量的大小就应该是4个字节。 那如果在64位机器上如果有64个地址线那一个指针变量的大小是8个字节才能存放一个地 址。 总结 指针变量是用来存放地址的地址是唯一标示一个内存单元的。指针的大小在32位平台是4个字节在64位平台是8个字节 2、指针和指针类型
我们都知道变量有不同的类型整形浮点型等。那指针有没有类型呢准确的说是有的。指针的定义方式是 type * 。 举些栗子大家就知道啦 char* 类型的指针是为了存放 char 类型变量的地址。 short* 类型的指针是为了存放 short 类型变量的地址。 int* 类型的指针是为了存放 int 类型变量的地址。 那指针类型的意义是什么
2 、1指针±整数
这里通过画图的方式帮助大家辅助理解正指针加减运算的规律 总结指针的类型决定了指针向前或者向后走一步有多大距离
2 、 2指针的解引用
那么指针的解引用和指针的类型有没有什么关联呢这里还是通过画图的方法帮助大家理解 总结 指针的类型决定了对指针解引用的时候有多大的权限能操作几个字节。 比如 char* 的指针解引用就只能访问一个字节而 int* 的指针的解引用就能访问四个字节。
3、 野指针
按照教科书上的解释概念 野指针就是指针指向的位置是不可知的随机的、不正确的、没有明确限制的。按照我的理解野指针其实就像是一条没有被绳子拴住的野狗到处乱串当使用它时解引用就会有危险。
3、 1野指针成因
对于野指针存在的原因分析比较常见的可以归纳为以下几个
指针未初始化指针越界访问指针指向的空间释放
指针未初始化导致野指针这里举个栗子分析以下
#include stdio.h
int main()
{ int *p;*p 20;return 0;
} 小结局部变量指针未初始化默认为随机值
指针越界访问造成野指针这里举一个简单的栗子 #include stdio.h
int main()
{int arr[10] {0};int *p arr;int i 0;for(i0; i11; i){*(p) i;}return 0;
}
小结一下 这个数组一共只有10个元素循环却访问到了第11个元素的位置。 当指针指向的范围超出数组arr的范围时p就是野指针。 指针指向的空间释放当再次访问原空间时造成野指针。
int * test()
{int a 10;return a;
}int main()
{int* p test();printf(%d, *p);return 0;
}小结一下 变量a是test内的局部变量当运行的时候出了这个函数时就会被销毁掉这里却返回a变量的地址赋值给指针pp去解引用操作不属于程序的空间则造成了野指针的问题。
3、 2如何规避野指针
指针初始化小心指针越界指针指向空间释放及时置NULL避免返回局部变量的地址指针使用之前检查有效性
4、指针运算
4、1 指针±整数
上面已经探讨了这个知识点这里就不做讲解了。
4、2 指针-指针
这里举一个模拟实现strlen函数的代码
#includestdio.h
#includeassert.h
int my_strlen(const char* p)
{assert(p);char* str p;while (*p ! \0){p;}return p - str;
}int main()
{char arr[] Hello bit!;printf(%d, my_strlen(arr));return 0;
}这里的返回值就是指针 - 指针的典型体现啦。指针减去指针得到的是两个指针之间元素的个数。
4、3 指针的关系运算
C语言的语法标准规定 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
5、指针和数组
指针和数组是不是同一个东西其实不是的。虽然我们常说数组名是首元素的地址好像和指针有紧密的关系但指针和数组是完全不一样的两个东西。 可见数组名和数组首元素的地址是一样的。 结论数组名表示的是数组首元素的地址
既然可以把数组名当成地址存放到一个指针中我们使用指针来访问一个数组中的元素就成为可能。所以 pi 其实计算的是数组 arr 下标为i的地址。 那我们就可以直接通过指针来访问数组举个栗子
#include stdio.h
int main()
{int arr[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int* p arr; int sz sizeof(arr) / sizeof(arr[0]);int i 0;for (i 0; i sz; i){printf(%d , *(p i));}return 0;
} 6 、 二级指针
指针变量也是变量是变量就有地址那指针变量的地址存放在哪里其实还是存放到指针变量中。
这里举个栗子辅助大家理解一下
#include stdio.h
int main()
{int a 10;//a是要在内存中申请4个字节的空间的//一级指针int* pa a;// pa是指针变量用来存放地址也得向内存申请申请4/8存放变量a的地址//二级指针int** ppa pa;//ppa是指针变量用来存放地址也得向内存申请申请4/8存放一级指针地址int** * pppa ppa;//pppa是指针变量用来存放地址也得向内存申请申请4/8存放二级指针地址printf(%d\n, **ppa);return 0;
}如图所示 对于二级指针的运算有
*ppa 通过对ppa中的地址进行解引用这样找到的是 pa *ppa 其实访问的就是 pa .**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作 *pa 那找到的是 a .
7、指针数组
指针数组顾名思义就是数组。指针数组是用来存放指针的数组。数组我们已经知道整形数组字符数组。那指针数组又是长什么样的呢
int* arr3[5];上述就是一个指针数组arr3是数组名一共有5个元素每个元素的类型时int*。
接下来举几个栗子辅助大家理解 可以利用指针数组来模拟二维数组的打印但是这里有个区别是二维数组的每一行元素在内存中是连续存放的这里就不一定。
#include stdio.h
int main()
{int arr1[] { 1,2,3,4,5 };int arr2[] { 2,3,4,5,6 };int arr3[] { 3,4,5,6,7 };int* ptr[] {arr1, arr2, arr3};int i 0;for (i 0; i 3; i){int j 0;for (j 0; j 5; j){printf(%d , ptr[i][j]);}printf(\n);}return 0;
}程序运行结果图 上述知识的一个综合运用栗子
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int i 0;for (i 0; i 10; i){printf(%d , i[arr]);//i[arr] -- *(iarr)//arr[i] -- *(arri)}//int* p arr;//test(arr, 10);*(arri) -- *(pi) -- arr[i]arr[i] -- *(arri) -- *(iarr) -- i[arr]//for (i 0; i 10; i)//{// printf(%p %p\n, arr[i], pi);//}return 0;
}int main()
{int arr[3][5];//arr[i][j]//(*(arri))[j]//*(*(arri)j)return 0;
}
总结撒花 本篇文章旨在分享C语言详解指针的相关知识点。希望大家通过阅读此文有所收获如果我写的有什么不好之处请在文章下方给出你宝贵的意见。如果觉得我写的好的话请点个赞赞和关注哦~