简单理解指针
1.内存和地址
首先我们可以理解指针就是电脑内存空间的地址,我们是通过指针来访问电脑中的数据,而这些数据是存储在电脑中的,举一个简单的例子,你想要找一个人,就必须知道他的地址,同样,我们用指针访问内存空间,可以直接简单理解为指针就是地址。
所以我们可以直接理解:内存单元的编号== 地址==指针
2.指针变量和地址
取地址操作符(&)
在C语言中创建变量其实就是向内存申请空间,比如:
#include<stdio.h>intmain(){inta=10;return0;}上述代码就是创建了整形变量a,内存中申请了4个字节,用于存放整数10,其中每个字节都有地址,如下图4个字节的地址分别是:
1:0x000000577EF6F914
2:0x000000577EF6F94c
3:0x000000577EF6F984
4:0x000000577EF6F9bc
而我们如果要得到a 的地址,就需要用到取地址符号&,
#include<stdio.h>intmain(){inta=10;&a;printf("%p",&a);return0;}
可以看到&a取出的是a所占4个字节中地址较小的字节的地址。
虽然整形变量占用4个字节,我们只要知道了第一个字节地址,就可以顺藤摸瓜访问4个字节的数据也是可行的。
3.指针变量和解引用操作符(*)
我们通过取地址操作符得到的地址是一个数值,而这个数据有时候也要存起来,方便以后再使用,那我们把这样的地址值存放在指针变量中。
指针变量也是一种变量,这种变量就是用来存放地址的,存放在指针变量中的值都会理解成指针
而我们首先要做的就是理解解引用操作符:
int a=10;
int *pa =&a;
pa左边写的是int *, *是在说明pa是指针变量,而前面的int 是在说明pa 指向的是整形(int)类型的对象。
除此之外,我们还可以通过解引用操作符来修改变量中的值。
#include<stdio.h>intmain(){inta=100;int*pa=&a;*pa=0;printf("%d",a);return0;}
通过上述代码以及打印结果可以看出,a 的值被修改为了0
3.指针变量类型的意义
先看一段代码:
#include<stdio.h>intmain(){intn=10;char*pc=(char*)&n;int*pi=&n;printf("%p\n",&n);printf("%p\n",pc);printf("%p\n",pc+1);printf("%p\n",pi);printf("%p\n",pi+1);return0;}上述代码中,我们定义了一个整形变量n, 然后分别用(char*)类型的指针变量和(int*)类型的指针变量来存储n的地址,我们分别打印出pc、n、pc+1、pi+1的地址发现pc 与 n 的地址是一样的,但是pc+1,和pi+1的地址有所不用,原因是在于指针的类型不一样,我们先将pc 强制转化位char* 类型的指针再+1,只移动一个字节,而int* 类型的指针+1,移动的是4个字节。
结论:指针的类型决定了指针向前或者向后走一步的距离。
void * 指针:
再指针类型中有一种指针是void* 类型的,可以理解为无具体类型的指针(泛型指针)
这种指针可以用来接受任意类型的地址。但是也有局限性,void类型的指针不能直接进行指针的±整数和解引用的运算。
而void类型的指针是使用在函数参数的部分,用来接收不同类型的数据的地址,这样的设计可以使得一个函数用来处理多种类型的数据。
4.指针的运算
指针的基本运算有三种:分别是:
- 指针±整数
- 指针-指针
- 指针的关系运算
指针±指针
#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};int*p=arr;inti=0;intsz=sizeof(arr)/sizeof(arr[0]);for(i=0;i<sz;i++){printf("%d ",*(p+i));}return0;}
数组在内存中的地址是连续存放的,所以知道第一个元素地址,就可以依次找到所有元素。
指针-指针
#include<stdio.h>intmain(){charp[5]="abc";char*s=p;while(*s!='\0'){s++;}printf("%d",s-p);return0;}
大指针-小指针得到的是两个指针之间的元素个数,反之则是个数的相反数。
指针的关系运算
#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};int*p=arr;intsz=sizeof(arr)/sizeof(&arr[0]);while(p<arr+sz){printf("%d ",*p);p++;}return0;}
大家在这里可能会很疑惑,打印出来的为什么不是1-10,而是1-5,原因在于本人所用的编译器是64位的,在64位下的编译器中指针变量占8字节,在32位的编译器中指针变量才为4字节,而arr这个数组占40字节,所以得到的sz位5
结语:
以上是本人对于指针的一些理解和心得,后续还会有更详细的指针讲解,比如const修饰指针,二级指针等。