1:指针是什么
指针是内存中的一个编号,也就是地址。
理解成一个个房间,房间上有号码,房间是内存空间,号码就是地址,可以通过地址找到这块空间,而指针就是地址。
一般口语中提到的指针我们认为他是指针变量,存地址的变量。
这里有个点是内存单元的大小,一个内存单元大小为一个字节。
另一个点是指针变量的大小,在32位平台下为四个字节,注意,是所有类型的指针变量, int* p与char* p,p都占4个字节,在64位平台下为8个字节。
2:指针类型
char *p
short *p
int *p
long *p
float *p
double *p
那么既然所有指针类型都占相同的内存大小,为什么要区分类型呢?
看代码
#include <stdio.h> int main() { int a = 128;//129 ->129 -127 int *pint = &a; char *pchar =(char*)&a; printf("%d\n",*pint);//128 printf("%d\n",*pchar);//-128 return 0; }
也就是说,指针类型决定了解引用时能够操作的内存大小,
int *可以操控四个字节,
char* 一个
double* 八个
3:指针+-整数
指针+整数:看代码
#include <stdio.h> int main() { int arr[10] = {0}; int *p = arr; for(int i=0; i<10; i++) { *(p++) = i; //p = p+1;然后解引用,p+1就是p向后走一个int大小 //也可以是*(arr++),因为arr是数组首地址,地址就是指针 } return 0; }
指针-整数同理
但是要注意越界问题,p不要越界,不然就成为了野指针。
4:野指针
一:野指针成因
1:指针未初始化
#include <stdio.h> int main() { //p为野指针 int *p; return 0; }
2:数组越界:
在第三模块有讲。
3:指针所指空间被释放后未置空
#include <stdio.h> #include <stdlib.h> int main() { int *p = (int*)malloc(sizeof(int)); *p = 6; free(p); //野指针 //应该这样:p = NULL; printf("%d",*p); return 0; }
二:如何规避野指针
1:指针创建时初始化,若暂时不初始化,置空,NULL。
2:在数组中注意越界问题
3:free后,及时给指针置空
4:避免返回局部变量的地址
5:使用前检查指针是否有效
#include <stdio.h> int main() { int *p = NULL; //检查有效性 if(p == NULL) { printf("NULL"); } else { printf("!NULL"); } return 0; }
5:指针的运算
一:指针与指针间的运算
两个指针相减的值的绝对值就是两个指针中间的元素个数
两个指针相加没有任何意义
指针相减需要两个指针都指向一块相同的连续空间
#include <stdio.h> int my_len(char s[]); int main() { char s[] = "abcdefg"; int len = my_len(s); printf("len = %d\n", len); return 0; } int my_len(char s[]) { char* p = s; if (s[0] == '\0') { return 0; } else { while (*s != '\0')//(*s) { s++; } //return s - &s[0]; return s - p; } //while(*s++) //return s - p - 1; }
二:指针的关系运算
#include <stdio.h> int main() { int arr3[10]; for (int* vp = &arr3[10];vp>arr3;) { *--vp = 0; } //该处编译器允许与数组首地址与其前一个地址比较,但C标准是不允许的, //C标准允许数组最后一个元素与其后一个地址进行比较 int arr4[10]; for (int* rp = &arr4[9]; rp >= arr4;) { *rp-- = 0; } return 0; }