(C语言)指针详解与应用
指针是C语言的灵魂指针与底层硬件联系紧密使用指针可操作数据的地址实现数据的间接访问。指针即指针变量用于存放其他数据单元如变量、数组、结构体和函数的首地址。若指针存放了某个数据单元的首地址则这个指针指向了这个数据单元若指针存放的值为0则这个指针为空指针。指针原理指针占用的内存空间在32位操作系统下占用4个字节空间 在64位操作系统下占用8个字节int main(){cout sizeof(int *) sizeof(int*) endl;cout sizeof(char *) sizeof(char*) endl;cout sizeof(double *) sizeof(double*) endl;cout sizeof(float *) sizeof(float*) endl;return 0;}结果我是64位操作系统所以4个输出都为8如何定义指针char* p、short* p、int* p等其中*号只是一个标识就是告诉计算机我要定义一个指针了它与数据类型是一个整体其中p为指针变量存放的是数据单元的首地址。指针的操作int *p;//定义一个指针内存分配int *arr (int*)malloc(10 * sizeof(int)); // 分配10个int空间free(arr);//释放内存与malloc是一对arr NULL;//防止指针悬空则对指针p有如下的操作方式p a;//取地址将数据a的首地址赋值给pint b *p;//取内容即将p指向的地址里的数据给b就是将a的值赋给b数据类型要一致char *p a;//意思就是我定义一个指针p并存放a的首地址p;//使指针向下移动一个数据宽度p同理p--;//使指针向上移动一个数据宽度--p同理p和--p错用可能导致越界一般用于数组关于*号的区分若是在数据类型的后面如int *p*号就是一个标识符告诉计算机我要定义指针无运算若是a *p,那么这里的*号就是取内容若是a*b,那么这里的*就是乘号空指针和野指针空指针1、指针变量指向内存中编号为0的空间2、用途初始化指针变量注空指针指向的内存不可以直接访问3、得到空指针的方式int *ptr nullptr;//最直接最简单int *ptr 0;int *ptr NULL;//#include cstdlib注意一定要初始化所有的指针。未初始化的指针是造成运行错误的一大原因访问未被初始化的指针相当于去访问一个本不存在的位置上的本不存在的对象。如果指针所指向的空间恰好有内容我们就很难分清它到底是合法的还是非法的了。所以建议初始化所有的指针尽量定义好对象之后在定义指向它的指针。实在不清楚的情况下就把指针初始化为nullptr。野指针指针变量指向非法的内存空间出现的原因1、指针变量未初始化2、指针释放后之后未置空3、指针操作超越变量作用域int main(){int *p (int*)0x1100;//0x1100是随便指向的编号而编号里的数无权操作因为未申请空间cout *p endl;return 0;}在程序中要避免出现野指针十分危险。总结空指针和野指针都不是我们申请的空间所以不要访问。const修饰指针const修饰指针有三种情况1、const修饰指针常量指针特点指针的指向可以修改但是指针指向的值不可以修改const int *p a*p 20;//错误指针指向的值不可以修改p b; //正确指针的指向可以修改2、const修饰常量指针常量特点指针的指向不可以改但是指针指向的值可以改int * const p a;*p 20;//正确指针指向的值可以修改p b;//错误指针的指向不可以修改3、const既修饰指针也修饰常量特点指针的指向和指针指向的值都不可以改const int * const p a;*p 20;//错误p b;//错误记忆技巧1、名称记忆将const翻译为中文”常量“” * “就叫指针const在前*在后就叫常量指针 const在后*在前就叫指针常量。2、可否修改记忆要明白const是起限定的作用int *const p中的const限定的是指针p而指针的是起到指向的作用所以p就不能指向了也就不能修改指向了const int *p中的const限定的是*而*的作用是取值所以*就不能取值了也就不能修改值了。数组与指针数组是一些相同数据类型的变量组成的集合其数组名即为指向该数组类型的指针简单理解就是数组名相当于指针变量里面存放的都是首地址。c[0] 等于 *c;c[1] 等于 *(c1)c[2] 等于 *(c2)遍历的方法1、用for循环遍历int *p arr; //arr是一个数组名for(int i 0;i 10;i ){cout p[i] endl;}2、用指针遍历for(int i 0;i 10;i ){cout *arr endl;arr ;}指针与函数本节主要讨论的是函数的参数采用指针的形式又叫地址传递。void swap(int *a,int *b) //地址传递{int temp *a;*a *b;*b temp;}int main(){int a 10;int b 20;swap(a,b);cout a a b b endl;return 0;}这是一个简单的交换值的程序这段代码改变了实参a和b的值总结如果不想修改实参就用值传递想修改实参就用地址传递。函数指针与指针函数主体是指针还是函数需求指针函数函数返回类型为指针函数指针指针指向一个函数首先要明白的优先级大于 *主要看fint* f(int x,int y): 因为的优先级大于 *所以首先主体是一个函数返回指针int (*f)(int x,int y): 首先f是一个指针指向一个函数格式为int (int x,int y)函数指针指向普通函数#include iostreamusing namespace std;int add(int a,int b){return ab;}int Minus(int a,int b){return a-b;}int main(){//定义一个函数指针int (*f)(int a,int b);f add;//将函数add的地址给函数指针cout a b (*f )(1,3) endl;f Minus;//将函数minus的地址给函数指针cout a - b (*f)(5,6) endl;return 0;}函数指针指向指针函数#include iostreamusing namespace std;int* add(int a,int b) //指针函数{int c ab;return c;}int* Minus(int a,int b) //指针函数{int c a-b;return c;}int main(){//定义一个函数指针int* (*f)(int a,int b);f add;//将函数add的地址给函数指针cout a b *(*f )(1,3) endl;f Minus;//将函数minus的地址给函数指针cout a - b *(*f)(5,6) endl;return 0;}总结1、指针函数依然是一个函数返回类型为指针比如int*、char*等2、而函数指针是一个指针它指向函数存放函数的地址函数地址与返回值地址一致3、函数指针的格式与要调用的函数格式保持一致注意事项在对指针取内容之前一定要确保指针指在了合法的位置否则将会导致程序出现不可预知的错误同级指针之间才能相互赋值跨级赋值会导致报错或警告指针的应用传递参数又叫地址传递1、使用指针传递大容量的参数主函数和子函数使用的是同一套数据避免了参数传递过程中的数据复制提高了运行效率减少了内存使用。#include stdio.hint FindMax(int *array,int count)//子函数找最大值的简单算法{int i;int max array[0];for(i 1;i count;i){if(array[i] max){max array[i];}}return max;}int main(){int a[] {1,5,7,2,3,4,15};int Max;Max FindMax(a,7);printf(Max %d,Max);}以上是一个找最大值的简单算法其中数组a的容量比较大可以通过指针传地址的方式减小空间的使用。若采用传地址的方式那么数据就可以在子函数里被改变而不是简单的复制。所以为了不让子函数随意的更改主函数的数据我们可以用const关键字。int FindMax(constint *array,int count) //const的运用{array[2] 66;//若这样写就会报警告或是报错不可以更改数组a里的数据只可以读}2、使用指针传递输出参数利用主函数和子函数使用同一套数据的特性实现数据等返回可实现多返回值函数的设计运用了地址传递。一般情况下C语言只能返回一个参数那如果我们想要返回多个参数怎么办呢#include stdio.h//子函数可以返回次数count与最大值max的值可以不需要returnint FindMax(int *max, int *count, const int *array, int length){*max array[0];for(int i 1;i length;i ){if(*max array[i]){*max array[i];(*count);}}}int main(){int a[] {1,5,7,2,3,4,15};int Max;int Count 0;FindMax(Max,Count,a,7);//将Max地址与Count的地址都传递给子函数printf(Max %d,Count %d,Max,Count);}这样我们就可以返回多个参数了。传递返回值将模块内的共有部分返回让主函数持有模块的“句柄”便于程序对指定对象的操作。#include stdio.h/*******************************************///假设这是一个模块里面的Time数据我们不能直接访问所以通过指针来进行间接访问int Time[] {23,50,55};//注意若是局部变量则出错int *GetTime(void){return Time;}/*******************************************///以上为一个模块int main(){int *pt;pt GetTime();printf(pt[0] %d\n,pt[0]);//pt[0] 23}直接访问物理地址下的数据访问硬件指定内存下的数据如设备ID号等。将复杂格式的数据转换为字节方便通信与存储。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2633016.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!