网站专题页面设计欣赏,用软件做seo网站关键词推广,大一python基础编程题,凡科模板建站目录
1.初始C指针
几个重要的概念#xff1a;
指针的加减
与*
二级指针
2.指针与数组
指针数组
数组指针变量
一维数组与二维数组传参的本质
编辑编辑 编辑
3.指针与函数
函数指针数组
4.指针与结构体
5.野指针以及常见的内存管理错误
常见的内存错…目录
1.初始C指针
几个重要的概念
指针的加减
与*
二级指针
2.指针与数组
指针数组
数组指针变量
一维数组与二维数组传参的本质
编辑编辑 编辑
3.指针与函数
函数指针数组
4.指针与结构体
5.野指针以及常见的内存管理错误
常见的内存错误
6.结语 今天咱们讲C语言的指针都说指针难确实这部分对新手来说确实不好理解那么下面跟着博主一起来学习学习吧。
1.初始C指针 先来看一个代码图片
怎么样这六个能否彻底搞清楚呢如何可以的话那么说明你的指针学的还是可以的如果搞不清楚咱们就一起来探讨一下。先抛出几个问题什么是指针指针与数组的关系是什么指针与函数的关系是什么指针与函数数组之间的关系又是什么
几个重要的概念
博主在观看c语言指针相关的书籍的时候发现有的书籍并没有把这几个概念描述的很清楚但这几个概念要是不清楚很影响学指针的。
1.指针的类型指针变量的声明类型例如 int*、char*、void* 等。
一般来说去掉*剩下的就是指针类型。 int **p;//指针类型为int** int(*p)[3];//指针类型为int(*)[3] int*(*p)[3];//指针类型为int*(*)[3] 由于指针可对指针指向的内存区里的数据进行修改所以说二级指针可以修改一级指针
2.指针所指向的类型指针指向的内存区域中存储的数据类型。
一般只需要将指针名称以及指针左边的*去掉即可。 int **p;//指针所指向的类型为int* int(*p)[3];//指针所指向的类型int()[3] int*(*p)[3];/指针所指向的类型int*()[3] 3.指针的值就是指针所指向的那块内存的起始地址 是一个地址 要注意的是一般为指针指向的内存块就是从内存的首地址开始往后sizeof指针所指向的类型个字节的内存区域以后我们说一个指针的值是hh就相当于说该指针指向了以hh 为首地址的一片内存区域我们说一个指针指向了某块内存区域就相当于说该指针的值是这块内存区域的首地址。
4.指针的大小这个大小取决于编译器x86环境下是4字节x64环境下是8字节。
指针的加减 1.指针加减整数 由此可见指针的1这个1的大小为sizeof指针所指向的类型个字节的大小例如上面第一个图片由于ptr这个指针所指向的类型是int所以说ptr1就是相当于在原来的基础上加了4个字节。所以说相当于一开始的ptr指向的是内存空间0地址的位置后面指向了内存空间第4个字节的位置。
2.指针减指针 指针也是可以减指针的当然这里需要注意的是如果是高地址减低地址为正。反之为负。
3.指针的比较指针也是可以比较大小的 int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p arr[0]; int sz sizeof(arr)/sizeof(arr[0]); while(p arr sz) // 指针的大小比较 { printf(%d , *p); p; } 与*
是“取地址”的意思而*是解引用操作符相当于的逆运用 int a10; int *pa; printf(%d,*p); 这里就是把a的地址拿出来锁到p这个指针变量中且p指向的是int类型的a而*相当于钥匙打开房门拿出a的地址的钥匙所以*p就是拿出了a的地址相当于*p就是a了。
二级指针
把变量的地址拿出来放到一个指针中这个指针叫做一级指针a存放的是变量的地址但是一级指针a也有地址的把一级指针a的地址拿出来再放到一个指针b 中这个指针b就是二级指针。同理也有三级指针四级指针·不过这些都用的少了。 int a 10; int *pa;//一级指针 int **ppp;//二级指针 2.指针与数组 下面开始咱们的正题咱们知道对于一个数组数组名是数组首元素的地址 实际上sizeof(对象)测出的都是对象自身的类型的大小而不是别的什么类型的大小。sizeofa就是整个数组的大小就是12字节sizeofaa是整个数组的地址而地址的大小取决于编译器的编译环境上面有讲解。
指针数组
什么叫做数组指针呢就是存储指针的数组它是一个数组这个数组里面存储了指针
例如int *p[3];就是p是数组名p这个数组中存了三个int类型的指针。看这类可以通过符号的优先级来看首先从指针名字开始指针名字先与[]结合就是数组后再与*结合为数组中存储的是指针最后再是int说明数组中的指针为int类型的。
数组指针变量 这是一个指针变量例如int(*p)[3]就是p先与*结合所以这是一个指针后再与[]结合这是一个数组是指针指向的数组且指针存储的数组是3个int类型元素的数组指针指向的是整个数组的地址。 那么数组指针变量如何初始化呢 int arr[10]{1,2,3,4}; int (*p)[10]arr;//数组指针即可这样初始化这样p这个指针指向的是arr这个数组的地址。 一维数组与二维数组传参的本质 图一是一维数组传参数组传参的本质就是一维数组的参数可以写成arr[]arr[3],但是编译器在识别的时候会自动把他们退化为指针即int*arr。
图二是二维数组传参的本质你看着像不像数组指针没错就是它没想到吧数组指针变量还可以用做二维数组的形参。如何理解呢实参是arr二维数组的数组名咱们知道数组名是数组首元素的地址。那么二维数组的首元素的地址就是整个第一行的地址而整个第一行有5个元素所以说像不像一个指向数组的指针变量这个数组中存储的是元素。这个就是数组指针。
123452345634567
但在内存中二维数组是连续存放的并不是这样的表格形状。
再来看一个知识点*(*(pi)j)
剖析来看pip指的是整一行的地址所以说pi是横着移动i行移动完之后再解引用得到的是第i行第一个元素的地址那么之后再加j指的是该行第j个元素的地址再解引用就可以得出二维数组第i行j列的元素与p[i][j]一样的。同理一维数组也是这样的p[i]*(pi).\
3.指针与函数
看完了指针与数组再来看指针与函数先来介绍一个函数指针 上图中p为函数指针变量因为前面有*代表p是一个指针变量。int xint y代表的是函数指针指向的函数的参数而int是函数指针指向的函数的返回值。经过这样一剖析是不是就清楚多了。而函数指针的初始化与数组指针的初始化差不多这里需要注意的是函数名与函数名均可以作为函数的地址。所以可见上面的代码示例。
函数指针数组
那么有没有一个数组里面存储的是函数指针呢有的兄弟有的下面请看 int(*p[3])(int x,int y); parr1 先和 [] 结合说明parr1是数组数组的内容是什么呢 是 i nt (*)()类型的函数指针。
4.指针与结构体 观看上面两个代码图片可知第一张图片是结构体定义了一个变量ss咱们可以通过ss.访问成员变量。也可以通过结构体定义的指针变量去访问结构体成员变量。如图二。
5.野指针以及常见的内存管理错误
什么叫做野孩子就是不受管教的孩子那么我们需要制定出一套规则去约束野孩子这样他就不会乱闯祸了。野狗也是一样找一条链子把它拴起来这样它就不会乱咬人了。那么野指针就需要使用NULL来约束它为了避免野指针建议每次定义指针之后将指针置为空。
对于mallocrealloccalloc等动态开辟出的空间就需要手动置为空即free。
常见的内存错误
1.指针没有指向一块合法的内存。
2.为指针分配的内存太小。
3.内存分配成功了但是没有初始化。
4.内存越界。
5.内存泄露。
6.内存已经被释放了但仍通过指针来访问内存
[1].freep后继续通过p来访问指针这时候p是野指针。
[2].在函数内部定义了一个数组却用return语句返回指向该数组的指针。这个地方函数栈帧已经回收了指针指向的那块内存空间没有了你还怎么访问解决办法就是弄明白栈上的变量的生命周期。
6.结语
世上无完人也无完事。所以说C语言成也指针败也指针。这个野指针一定一定要注意还有内存问题否则以后会吃大亏。
以上内容仅我个人理解如果不对请指出谢谢
本篇完..................