指针是什么
指针相对于一个内存单元来说,指的是单元的地址,该单元的内容里面存放的是数据。在C语言中,允许用指针变量来存放指针,因此,一个指针变量的值就是某个内存单元的地址。
指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。
指针类型
指针类型的意义:
1.指针类型决定了指针解引用的权限有多大;
2.指针类型决定了,指针走一步,能走多远(步长)
int main() { int a = 0x11223344; int* pa = &a; char* pc = &a; printf("%p\n", pa); printf("%p\n\n", pa + 1); printf("%p\n", pc); printf("%p\n\n", pc + 1); printf("%0x\n", a); *pc = 0; printf("%0x\n", a); *pa = 0; printf("%0x\n", a); return 0; }
野指针
野指针是指指针指向的位置是不可知(随机的、不正确的、没有明确限制的)。
1.指针未初始化
int main() { //指针未初始化 int* p;//p是一个局部指针变量,局部变量不初始化,默认是随机值 *p = 10; return 0; }
2.指针访问越界
int main() { //指针访问越界 int arr[10] = { 0 }; int* pa = arr; int i = 0; for (i = 0; i <= 10; i++) { *pa = i; pa++; } return 0; }
3.指针指向空间释放
int* test() { int a = 10; return &a; } int main() { //指针指向空间释放 int* p = test(); *p = 20; return 0; }
规避野指针:
1.指针初始化 - 明确知道初始化的值
2.小心指针越界
3.指针指向空间释放及时置成NULL
4.指针使用之前检查有效性
指针运算
指针+-整数;
指针-指针,得到两个指针之间的元素个数;指针和指针相减的前提是两个指针指向同一块空间;
指针关系运算
标准规定指向数组元素的指针可以与指向数组最后一个元素之后的内存位置的指针/地址进行比较,但是不允许与指向第一个元素之前的内存位置的指针/地址进行比较。
int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = arr; int* pend = arr + 9; while (p <= pend) { printf("%d\n", *p); p++; } printf("%d\n", &arr[9] - &arr[0]); return 0; }
int my_strlen(char* str) { char* start = str; while (*str != '\0') { str++; } return str - start; } int main() { int len = my_strlen("abc"); printf("%d\n", len); return 0; }
数组与指针
int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //[]是一个操作符,2和arr是两个操作数,两个操作数的顺序可以交换 //arr[2]在编译时会转换成*(arr+2),arr[2] <==> *(arr+2) //arr等价p,*(arr+2) <==> *(p+2) <==> *(2+p) <==> *(2+arr) //arr[2] <==> *(arr+2) <==> *(p+2) <==> *(2+p) <==> *(2+arr) <==> 2[arr] //arr[2] --> *(arr+2) -->*(2+arr) --> 2[arr] int* p = arr; printf("%d\n", arr[2]); printf("%d\n\n", p[2]); printf("%d\n", 2[arr]); printf("%d\n", arr[2]); return 0; }
指针数组
指针数组本质是一个数组,是专门用来存放指针的数组。
二级指针
指针的本质也是一个变量,既然是变量,那它也会存放在内存中,就也会有存放地址,而用来存放一个一级指针地址的变量就被称为二级指针。同理用来存放二级指针地址的变量就是三级指针(禁止套娃,doge)。
int main() { int a = 10; int* pa = &a; //ppa就是一个二级指针变量 int** ppa = &pa;//pa也是个变量,&pa取出pa在内存中起始地址 return 0; }