■指针的概念 ■指针的基本类型 ■野指针 ■指针和数组 ■二级指针 ■指针运算
**
一.指针的概念
**
指针也就是内存地址,指针变量是用来存放内存地址的变量,描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。
**
二.指针的基本类型
1.指针变量决定了:指针进行解引用操作时可以访问几个字节(权限)
char*: 解引用时访问一个字节
int : 解引用时访问四个字节
double:解引用时访问8个字节
int main() { int a = 0x11223344; int*pa = &a; *pa = 0; /*char* pc = &a; *pc = 0;*/ return 0; }
2.指针类型决定了指针的步长,及(向前,向后,走一步多大距离)
int* 指针加1,表示跳过一个整型,意思是向后走4个字节;
char指针加1,表示跳过一个字符,意思是向后走1个字节;
double指针加1,表示跳过一个double,意思是向后走8个字节;
short*指针加1,向后走2个字节;
int main() { int a = 0x11223344; int* pa = &a; char* pc = &a; printf("pa=%p\n", pa); printf("pc=%p\n", pc); printf("pa+1=%p\n", pa -1); printf("pc+1=%p\n", pc -1); return 0; }在这里插入代码片
**
三.野指针
**
野指针产生的原因(C语言中常见)
1.局部指针变量没有初始化
#include <stdio.h> int main() { int *p;//局部变量指针未初始化,默认为随机值 *p = 20; return 0; }
2.指针越界访问
#include <stdio.h> int main() { int arr[10] = {0}; int *p = arr; int i = 0; for(i=0; i<=11; i++) { //当指针指向的范围超出数组arr的范围时,p就是野指针 *(p++) = i; } return 0; }
3.就是指针指向的空间未释放
常见的还有以下:
/*int main() { int* p;//p就是野指针 *p = 20; return 0; }*/ int main() { int arr[10] = {0}; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); int* p = arr; for (i = 0; i <= sz; i++) { *p = i; p++; } return 0; }
如何规避野指针
1.定义创建一个指针变量时一定要记得初始化
2.动态开辟的内存空间,free()释放内存后,一定要马上将对应的指针置为NULL空指针
3.不用再函数中返回栈空间的指针(地址)或局部变量的地址
4.注意在动态开辟内存后,对其返回值做合理判断,判断其是否为空指针
#include <stdio.h> int main() { int *p = NULL; //.... int a = 10; p = &a; if(p != NULL) { *p = 20; } return 0; }
**
四.指针和数组
首先我们以如下例子来举例:
#include <stdio.h> int main() { int arr[5] = {1,2,3,4,5}; printf("%p\n", arr); printf("%p\n", &arr[0]); return 0; }
运行结果如下:
我们就可以得出结论:数组就是首元素地址,数组名是数组第一个元素的地址,也是数组的首地址。
*
而以下情况除外:
1.&数组名 ----->表示的是整个数组
2.sizeof数组名 ----->计算的是整个数组的大小
五.二级指针
把一个指向指针变量的指针变量称为多级指针变量,对于指向处理数据的指针变量称为一级指针变量,简称一级指针,而把指向一级指针变量的指针变量称为二级指针变量,简称二级指针
对于二级指针的运算有:
1.*ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 10; *ppa = &b;//等价于 pa = &b;
2.**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .
**ppa = 10; //等价于*pa = 10; //等价于a = 10;
六.指针运算
有下三种情况:
指针± 整数
指针-指针
指针的关系运算
6.1 指针±整数
#include <stdio.h> int main() { int arr[10] = {1,2,3,4}; int *p = arr; *p = 10; printf("%d\n",*p); p++; *p = 20; printf("%d\n",*p); return 0; }
结果为:
6.2指针-指针
int main() { //两个指针相减的前提是:指针指向的同一块连续的空间 int arr[10] = {0}; printf("%d\n", &arr[9] - &arr[0]); printf("%d\n", &arr[0] - &arr[9]); int a = 10; char c = 'w'; printf("%d\n", &a - &c);//err return 0; }
6.3指针的关系运算
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--) { *vp = 0; }
实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。
总结:指针可以相减,也可以和立即数加或者减,两个指针相减可以理解为两个指针的距离,但是两个指针相加后将会是一个毫无意义的地址。最后,希望对大家有所帮助!