指针的运算
1.指针+1或者指针-1是什么意思?
把指针中记录的内存地址,往后或者往前移动一个步长
2.什么是步长?跟什么有关?
跟数据类型有关
Windows64位操作系统:
char:移动一个字节
short:移动两个字节
int:移动四个字节
long:移动四个字节
long long:移动八个字节
有意义的操作 :
指针跟整数进行加、减操作(每次移动N个步长)
指针跟指针进行减操作(间隔步长)
无意义的操作:
指针跟整数进行乘除操作
指针和指针进行加、乘、除操作
原因:此时指针指向不明
指针运算案例
前提:保证内存空间是连续的
#include<stdio.h> main() { int arr[] = {1,2,3,4,5,6,7,8,9}; int* p1 = &arr[0]; int* p2 = &arr[5]; printf("数组的0索引对应的元素是:%d\n",*p1); printf("数组的1索引对应的元素是:%d\n",*(p1+1)); printf("arr[5]和arr[0]之间的间隔步长为:%d\n",p2-p1); printf("%p\n",p1); printf("%p\n",p2); return 0; }
指向不明的指针
1.野指针
(指针指向的空间未被分配): 获取到的数据是其他程序的数据 (外挂的基本原理)
#include<stdio.h> main() { int a = 10; int* p1 = &a; int* p2 = p1+10; //将p1的内存地址加10个步长后的地址赋给p2 但p2是一个未被分配的内存地址 printf("%p\n",p1); printf("%d\n",*p1); printf("%p\n",p2); printf("%d\n",*p2); return 0; }
2.悬空指针
(指针指向的空间已分配,但被释放了)
#include<stdio.h> int* test(); main() { int* p3 = test(); //函数结束后内存空间被释放,里面的变量也被释放 printf("%p\n",p3); printf("%d\n",*p3); return 0; } int* test() { int a = 10; int* p = &a; return p; }
void类型的指针
优点:
可以接收任何类型指针记录的内存地址
缺点:
无法获取其中的数据,也无法对其进行加、减计算
代码案例
#include<stdio.h> void swap(void* p1,void* p2,int len); int main() { int a = 10; int b = 13; swap(&a,&b,sizeof(int)); printf("a:%d b:%d",a,b); return 0; } //函数:用于交换两个变量记录的数据 //使用viod型指针,提高函数通用性,任何数据类型的数据都可以进行交换 void swap(void* p1,void* p2,int len) //定义两个viod指针来接受传递的内存地址,定义len接收外部数据的占用字节长度 { int i; int temp = 0; //把void类型指针转成占用字节长度为一的char型,用于后面的字节级转换 char* pc1 = (char*)p1; char* pc2 = (char*)p2; //循环每一个字节进行交换 for(i = 0;i < len;i++) { temp = *pc1; *pc1 = *pc2; *pc2 = temp; pc1++,pc2++; //交换完后,进行下一个字节的交换 } }
多级指针
含义:
指向指针的指针
作用:
多重指针可以操作它指向的指针中的内存地址
代码案例
逻辑如下
int ** pp = p
其中的int*是p的变量类型; *是标记这是个指针变量
当使用多重指针时
*pp = &b
*是解引用运算符,代表解一次,所以此时就是p,而p保存的是内存地址,所以就代表把p的内存地址改为p的内存地址
**pp
解两次,解1次是p,p保存的是内存地址,再解一次就解成了b,b保存的是具体的值,所以此时就是输出b的值
#include<stdio.h> int main() { int a =10; int b =20; //定义指针保存变量a的内存地址 int* p = &a; //定义指针保存指针变量p的内存地址 int** pp = &p; //把p中的内存地址修改为为b的内存地址 *pp = &b; printf("a的内存地址为:%p\n",&a); printf("b的内存地址为:%p\n",&b); printf("指针p的内存地址为:%p\n",p); printf("指针pp的值为:%d\n",**pp); return 0; }
数组指针
获取数组的指针,实际上是获取数组的首地址
代码案例
#include<stdio.h> int main() { int arr[] = {1,2,3,4,5,6,7,8,9}; int length = sizeof(arr) / sizeof(arr[0]); int* p = arr; //获取数组首地址 //int* p = arr[0]; 这行代码和上面效果一样 int i; for(i = 0;i < length;i++) { printf("%d ",*(p+i));//*(p+i):首地址也就是0索引的元素,获取完0索引元素后,地址往后移一位就是1索引,以此类推 } printf("\n"); return 0; }
数组指针的细节
arr参与计算的时候,会退化为第一个元素的指针
特殊情况:
sizeof 运算的时候,不会退化,arr还是整体
&arr获取地址的时候,不会退化,步长:数据类型*数组长度
标签:arr,p1,int,C语言,---,printf,内存地址,指针 From: https://blog.csdn.net/2301_80464770/article/details/140995650