c语言指针 1、指针定义 指针是一个变量, 它保存的是另一个变量的地址, 即内存位置的直接地址。
int ptr; //整型变量,ptr+1 表示变量值+1;const int ptr;//只读变量,和int const ptr效果一致;int *ptr1; //定义一个整型指针, ptr+1 表示地址偏移 int 类型字节;int ptr[3];//3 个成员的整型数组, ptr+1 表示指向 ptr[1]的地址;int *ptr[3];//指针数组,ptr[3]是数组,int*再与 ptr[3]结合成指针数组, 表明数组中保存着 int 类型的指针, ptr+1 表示指向 ptr[1][]的地址, 即二维数组 ptr[1][0]的地址;int (*ptr)[3];//数组指针,()优先级高,(*ptr)是指针, 再与[3]结合, 说明指针所指向的内容是数组, 最后和 int 结合, 表示数组元素类型是 int 类型。ptr+1 表示指向 ptr[1][]的地址, 即 ptr[1][]的地址;int **ptr;//二维指针变量, 保存一维指针变量的地址;int const *ptr;//常量指针,ptr指向的内容不可以修改,但可以改变指向;int *const ptr;//指针常量,ptr的指向不可以修改,但可以修改指向的内容; 2、*p++、 *(p++)、 *++p、 ++*p、 *p+1、 *(p+1)#include int main(){ int buff[]={10,20,30}; int *p=buff; /*1 buff[0]的地址:&buff[0]*/ printf(print1 buff addr:%#x\n,buff); /*2 buff[0]的地址:&buff[0]*/ printf(print2 p addr:%#x\n,p); /*3 偏移 sizeof(int)字节*/ printf(print3 p+1 addr:%#x\n,p+1); /*4 取 buff[0]的值*/ printf(print4 *p=%d\n,*p); /*5 取 buff[0]的值+1*/ printf(print5 *p+1=%d\n,*p+1); /*6 地址偏移 sizeof(int)再取值, 即 buff[1]*/ printf(print6 *(p+1)=%d\n,*(p+1)); /*7 先取*p 的值,再 p+1*/ printf(print7 *p++=%d\n,*p++); /*8 先取*p 的值, 再(*p)+1*/ printf(print8 ++*p=%d\n,++*p); /*9 先 p+1,再取*(p+1)*/ printf(print9 *++p=%d\n,*++p);} 运行结果:[xsw@xsw cc]$ ./a.outprint1 buff addr:0xbf98f2a0print2 p addr:0xbf98f2a0print3 p+1 addr:0xbf98f2a4print4 *p=10print5 *p+1=11print6 *(p+1)=20print7 *p++=10print8 ++*p=21print9 *++p=30 3.null指针和void*指针 null 是标准宏定义, 用来表示空指针常量, 在声明指针变量时若没有确切地址赋值, 可以给指针变量赋null。
#include int main(){ char *ptr=null; printf(ptr addr:%d\n,ptr); return 0;} 执行结果[xsw@xsw cc]$ ./a.outptr addr:0 在大多数操作系统中程序不允许访问地址为 0 的内存, 因为该内存是操作系统保留的。 指针指向地址为 0 的内存表示该指针指向的地址不可访问。 按照惯例 null 指针假定为不指向任何东西。
void 表示”无类型”, void*指针表示”无类型指针”, 即可指向任何数据类型。
#include int main(){ void *p; int a=100; char buff[]={0,10,20,30}; p=&a;//保存 int 型变量地址 //void*指针访取值时要保证和所指向的变量类型一致 printf(*p=%d\n,*((int *)p));//强制转换成 int* p=buff;//指向字符数组首地址 //强制转换成 char* printf(*p=%d\n,*(char *)p);//buff[0] printf(*(p+1)=%d\n,*(char *)(p+1));//地址往后偏移 char 字节: buff[1] printf(*p+1=%d\n,*(char *)p+1);//取出的值+1: buff[0]+1 return 0;} 执行结果*p=100*p=0*(p+1)=10*p+1=1 注:void 几乎只能用于指针的声明和函数返回值以及函数形参, 不能用于变量的定义。
4、二维指针 二维指针:指向指针的指针。 保存一维指针的地址。
指针声明:int **ptr;
#include int main(){ int a=0x12; int *ptr=&a;//一维指针保存变量地址 int **pptr=&ptr;//二维指针保存一维指针本身地址 //1 ptr==&a printf(line1:a addr:%#x\n,ptr); //2 *(&ptr)==&a printf(line2:*(&ptr)=%#x\n,*(&ptr)); //3 pptr==&ptr printf(line3:pptr :%#x\n,pptr); //4 *ptr==*(&a)==a printf(line4:*ptr=%#x\n,*ptr); //5 *(&ptr)==ptr==&a printf(line5:*pptr=%#x\n,*pptr); //6 **pptr==**(&ptr)==*ptr=*(&a) printf(line6:**pptr=%#x\n,**pptr); //7 ***(&pptr)==**(&ptr)==*ptr==*(&num)=0x12 printf(line7:**pptr=%#x\n,***(&pptr));} 执行结果:[xsw@xsw cc]$ ./a.outline1:a addr:0xbf90384cline2:*(&ptr)=0xbf90384cline3:pptr :0xbf903848line4:*ptr=0x12line5:*pptr=0xbf90384cline6:**pptr=0x12line7:**pptr=0x12 5、数组指针 指针定义:int (p)[n];指向数组整体的指针。 数组指针类型:int ()[n];
()优先级高, 所以 p 是一个指针, 指向一个整型的一维数组, 一维数组的成员个数位 n, 也就是说 p 的步长为 n。 即 p+1 偏移的地址为 n 个 int 型长度。 因此数组指针也称为行指针。
优先级: () > [] > *
示例一:数组指针指向一维数组示例
#include int main(){ int buff[]={11,22,33,44,55,66}; int (*ptr)[6];//数组指针,指向数组整体 ptr=&buff; int i; //数组指针 ptr+1 偏移指向的数组整体大小,即偏移 6*sizeof(int)=24 字节 printf(ptr addr:%#x\n,ptr); printf((ptr+1) addr:%#x\n,ptr+1); /*数组指针遍历 buff*/ for(i=0;i<6;i++) { printf(%d ,*(*ptr+i));//或*(ptr[0]+i)或 ptr[0][i] } printf(\n); return 0;} 执行结果:[root@xsw cc]# ./a.outptr addr:0xbfbc8ce0(ptr+1) addr:0xbfbc8cf811 22 33 44 55 66 示例二:数组指针指向二维数组示例:
#include int main(){ int buff[][3]={1,10,3,4,5,6};//每行有 3 个元素 int (*p)[3]=buff; printf(*p[0]=%d\n,*p[0]);//等价于 buff[0][0] printf(*(p[0]+1)=%d\n,*(p[0]+1));//等价于 buff[0][1] printf(*p[1]=%d\n,*p[1]);//等价于 buff[1][0]} 6、指针数组 定义:int p[n];数组中保存 int指针。指针数组类型:int *[n], p的类型是 int **,p+1 偏移的地址为:sizeof(int *)。
示例一:将一维数组赋值给指针数组:
#include int main(){ int buff[]={11,22,33,44,55,66}; /* //初始化直接赋值 int *ptr[10]={&buff[0],&buff[1],&buff[2],&buff[3],&buff[4],&buff[4]} */ int *ptr[10];//指针数组,数组中保存 int 型指针 /*数组指针赋值*/ int i; for(i=0;i<6;i++) { *(ptr+i)=&buff[i];//或:buff+i } for(i=0;i<6;i++) { printf(%d ,*(*ptr+i)); } printf(\n); return 0;} 运行结果:[root@xsw cc]# ./a.out11 22 33 44 55 66 示例二:将二维数组赋值给指针数组示例
#include void tow_array(int (*buff)[3],int line);int main(){ int buff[][3]={1,10,3,4,5,6};//每行有 3 个元素 int *p[3]; *p=buff[0]; p[0]=buff[0]; *(p+1)=buff[1]; printf(%d\n,(*p)[0]);//等价于:p[0][0] printf(%d\n,(*p)[1]);//等价于 p[0][1] printf(%d\n,*(p[0]+1));//等价于 p[0][1]printf(%d\n,*(p+1)[0]);//等价于 p[1][0], *(p+1)指向 buff[1][0]地址 printf(%d\n,*(*(p+1)+1));//等价于 p[1][1]}printf(%d\n,*(p+1)[0]);//等价于 p[1][0], *(p+1)指向 buff[1][0]地址printf(%d\n,*(*(p+1)+1));//等价于 p[1][1] 注:二维数组赋值给指针数组时 p=buff 是错误的。
7、函数指针 函数指针:指向函数的指针变量。 本质是指针变量。
QUIC如何解决TCP性能瓶颈
发光二极管谁发明的_最早出现在哪个国家
英特尔医疗影像领域已取得诸多突破 大幅提升了筛查的检测精度和效率
支持包裹看护 萤石极光人脸视频锁Y3000FVX 双摄版热售中
顺丰供应链携手亚马逊云科技,推动供应链智慧转型和升级
C语言指针
大米粮食重金属检测仪的功能特点
寒武纪发布首款云端AI芯片MLU100_创始人兼CEO陈天石公开信内容预览
Linux rename命令重命名多个文件与目录
ADI发布最新任意波形发生器解决方案
台积电宣布今年大规模资本支出计划后,将面临巨大的盈利压力
接触器继电器的几个细节
做一个激光雷达,需要哪些基本部件?
程序员怎样在工作中提升自我
USB标准适用于哪些应用
适合移动应用开发的编程语言有哪些
手机锂电池充电误区及正确充电方法一览
新唐科技NUC240SE3AE控制器简介
百能云芯与Sourcengine正式达成战略合作!为客户提供更高效的服务
太赫兹辐射是否能够通过能量波传播进入生物组织?