基本使用
#include <stdio.h> main() { int a[] = {5, 15, 34, 54, 14, 2, 52, 72}; int *p = &a[5]; //将a[5]的地址赋给指针p printf("p = %d\n",p); //p存储的是地址 printf("*p = %d\n",*p); //*p存储的是地址对应的值 printf("p[-2]=%d\n",p[-2]); // p[-2]是a[3]元素 printf("p+1=%d\n",p+1); //地址加1,对应的移动到下一元素的地址,移动的长度是一个变量的大小 printf("*p+1=%d\n",*p+1); //p==2.*p+1==3 p=p+1; printf("*(p+1)=%d\n",*(p+1)); //*p存储的是p+1地址对应的值 printf("p+1=%d\n",p+1); //p+1对应的地址 }
#include <stdio.h> #include <stdlib.h> int main() { int i; scanf("%d",&i); char *a[]={"january","february","march","april","may","june","july","august","september","october","november","december"}; printf("%s\n",a[i-1]); }
指针运算
*p++的作用:
1、取出p所指的那个数据来,完事之后顺便把p移到下一个位置去;
2、*的优先级虽然高,但是没有++高;
3、常用于数组类的连续空间操作;
4、在某些CPU上,这个语句可以直接被翻译成一条汇编指令,因此可以加快运算速度。
0地址
1、当然你的内存中有0地址,但是0地址通常是不能随便碰的地址;
2、所以你的指针不应该具有0值;
3、因此可以用0指针来表示特殊的事情:
1.返回的指针是无效的;
2.指针没有被初始化(一般指针都要先初始化为0);
4、NULL是一个预定定义的符号,表示0地址,建议使用0地址时,使用NULL,因为有的编译器不愿意你用0来表示0地址。
指针的类型转换
1、void*表示不知道指向什么东西的指针,计算时与char*相同,但不相通;
2、指针也可以转换类型,如int *p=&i; void*p=(void*)p;
3、这并没有改变p所指的变量的类型,而是让后人用不同的眼光通过p看它所指的变量:我不在当p是int啦,我认为你就是个void。
指针能做的事情
1、需要传入较大的数据时用作参数;
2、传入数组后对数组做操作;
3、函数返回不止一个结果时,需要用函数来修改不止一个变量;
4、动态申请的内存。
动态内存分配
1、C99允许用变量来做数组定义的大小,但是ANSI不允许,就必须使用malloc动态分配内存;
2、malloc函数包含在stdlib.h头文件中,因此使用malloc必须包含该头文件;
3、malloc的调用形式为void*malloc(n*sizeof(变量类型)),申请的内存以字节为单位,返回的结果时void*,需要将申请的内存转换为自己需要的类型。可以理解为你申请了一块内存,但是内存是以int类型存储,还是char类型存储由你决定;
4、如果内存申请失败则返回0,或者叫做NULL;
5、与malloc申请内存对应的是free释放内存,这个必须要有,需要注意的是释放的时候,只能释放申请来的空间的首地址;
函数间传递指针需要注意的
如果在程序中要用到动态内存分配的内存,并且会在函数之间传递,不要让函数申请内存后返回给调用者,因为十有八九调用者会忘了free,或找不到合适的时机free。好的模式是让调用者自己申请,传地址进函数,函数再返回这个地址出来。也就是说除非函数的作用就是分配内存,否则不要在函数中molloc然后传出去用。
2018.05.18