eee一.
1指针是什么
指针即是地址,地址又是什么呢?内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节
而这个一个字节所在的位置名字即是地址。举个例子
int main()
{
int a=10;
{
0x0012ff40就是a的地址如果我们想把地址取出,可以使用&取地址符号即&a,而地址指向的就是a的值即10。
2.指针的大小
32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后 是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4 个字节才能存储。 如果指针变量是⽤来存放地址的,那么指针变的⼤⼩就得是4个字节的空间才可以。 同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节的空间,指针变量的大小就是8个字节。
二.指针类型
就像整型变量,浮点变量,指针也有变量即指针变量
int *p=&a//int * 就如 int 一样来创造一个变量,而int * 创造的就是指针变量
而指针变量p的值是a的地址
如果我们想取a的值可以使用*p等价于a。
指针自己的类型即指向内容的类型就像我们一开始学的int,float,double等等
指针的基本类型有 int* , float*等等
指针的进阶类型有
(1)
(*p)[]数组指针类型即使(*)[]指向的是整个数组的地址
如
int arr[5]={1,2,3,4,5};
int (*p)[5]=&arr;
这里我们需要辨别一下关于数组的地址需要注意的几个事项
1 int *p=arr 这里的arr代表是a[0]的地址
2 而arr[0]就可以等价 *(arr+0)取出的是数字首元素的地址
3而&arr的地址虽然和首元素地址相同,但是却是(*)[]
(2)
这里我们先介绍一下关于指针的运算
1指针可以减指针(不可以加)
例如
int arr[5]={1,2,3,4,5};
int (*p)[5]=&arr;
int *p1=&arr[1];
int *p2=&arr[4];
这里的p2-p1的值即两个地址间元素的个数即3个元素两个位置可以相反如果是printf函数以%d输出那么就是-3.
2指针可以+-整数
(p1+1)就等价于(&arr[1]+1)==&arr[2]而这个地址指向的就是arr[2]的值
现在我们回到数组指针
int arr[5]={1,2,3,4,5};
int (*p)[5]=&arr;
而这里&arr如果加1那么跳过的是整个数组即使arr[4]元素后一个地址每加减一个1就跳过于所设置类型数组的元素个数*元素类型的字节大小
int型所占4个字节
那么每次+-1就跳过4个字节乘以5个元素的大小
指针的进阶还有
(2)
函数指针
假如有个自定义函数
int test(int x,int y);
int (*p)(int x, int y)=test;或者int (*p)(int , int )=&test;
第一个int代表函数返回类型
后面()中的两个int指的是参数类型
函数指针的使用与函数相似
p(3,4)或者*p(3,4)效果相同
(3)
二级指针(可以继续加三级,四级等等,本质差不多)
int a=10;
int *p1=&a;
int* *p2=&p;
p1的值是a的地址
p2的值是p1的地址
如果我们想取出a的值
可以 *(*p2)------(*p2)取出的是p1的值即a的地址
*(*p2)取出的a的值
(4)
指针数组
这个很好理解就是数组里放的是指针变量
int a=10,b=3,c=4;
int *p1=&a,*p2=&b,*p3=&c
int *arr[3]={p1,p2,p3};
利用这个我们可以模拟二维数组即数组里放数组的地址.
以上就是指针的一些基本介绍.