在学习指针时,说指针也是一种变量,所以指针变量就和普通变量一样:需要占用内存,需要初始化等等。但在使用和普通变量一样的用法时,指针变量的运算就和普通变量的运算不太一样了。
一:
先给出一个例子吧。
#include <stdio.h>
int main()
{
int arr[10]={1,2,3,4};
int *p=arr;
printf("%d\n",*p);//这时*p是arr[0]的值
*p=10;//这时*p将arr[0]的值从1改为10
printf("%d\n",*p);
p++;//在这就会有人问p++是指什么?
*p=20;
printf("%d\n",*p);
printf("%d\n",arr[0]);
printf("%d\n",arr[1]);
return 0;
}
我们可以想一下加法都有哪几种可能情况?
1.加一个字节
2.加一个数组
3.加一个单元格
在上面的程序中有定义一个数组arr,假设数组的起始地址是1000,因为定义的是一个整型数组,所以每一个单元格是4个字节,那么arr[1]的地址是1004。所以就会有下图:
*p=10;这句是将arr[0]的值变为10
1.当假设p++是指加一个字节:
因为数组中每一个单元格是4个字节,所以可以把前两个单元格放大,整型数字在计算机中是以“0”,“1”代码的形式存在的,但是过长的数字代码对人的阅读造成了较大的障碍,为了解决这一问题,才使用十六进制来表示二进制,4位二进制数用1位十六进制数就可以表示,十进制数10用十六进制表示为0xa,但是要用a占4个字节,也就是8位,所以是0x0000000a,那么十进制数2用十六进制表示为0x00000002。因为在计算机内有大端模式和小端模式保存字节。大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在高地址中。小段模式,是指数据的高字节保存在高地址中,而数据的低字节保存在内存的低地址中。在英特尔处理器,Windows操作系统上,控制台显示的结果是99 FB E4 15,与直接求出来的十六进制值15 E4 FB 99 正好相反,所以证明是小段的。所以就有如下图:
所以在当p++表示为加一个字节时,然后把*p赋值为20,则会有:
此时arr[0]表示的十六进制数是0x140a,转换为十进制是5130,arr[1]为0。很显然不符合实际。
2.当假设p++表示加一个数组:
刚开始指针p指向的是arr[0],然后p++就直接由一个数组头跳到数组尾,此时指针p对于数组来说没有用。
3.当p++表示加一个单元格:
这时当p++之后指针p指向的是arr[1],就会有如下图:
此时得到的arr[0]的数用十进制表示是10,arr[1]的数用十进制表示为20,是符合我们的认知。
所以上面程序的运行结果是:
所以对于整型指针变量加1,是指加一个单元格的长度,也就是4个字节。这个同样也用于其他类型的指针变量。当是字符指针变量p,p++是指加一个单元格的长度,也就是1个字节.因此,指针加整型数字时是需要调整,调整的权重是sizeof(指针去掉一个*)。
例如:
int main()
{
int *p = (int *)1000;
printf("%d\n",p+5);//1020
printf("%d\n",(short *) p+5);//1010
printf("%d\n",(unsigned long *)p+5);//1020
printf("%d\n",(double *)p+5);//1040
printf("%d\n",(char ***)p+5);//1020
printf("%d\n",(char *)p+5);//1005
printf("%d\n",(long long)p+5);//1005
return 0;
}
运行结果是:
二:指针减整型数字和加整型数字类似
int main()
{
int arr[10] = {0};//x
int *p = &arr[9];//x+36
int *q = &arr[1];//x+4
printf("%d\n",p-q);//8
printf("%d\n",q-p);//-8
printf("%d\n",(short *)p-(short *)q);//16
printf("%d\n",(long *)p-(long *)q);//8
printf("%d\n",(char **)p-(char **)q);//8
printf("%d\n",(double *)p-(double *)q);//4
printf("%d\n",(long long)p-(long long)q);//32
printf("%d\n",(char *)p-(char *)q); //32
return 0;
}
执行结果如下:
三:指针加指针:是非法的
四:指针减指针:是求两个指针间隔的单元数
1.算出字节数;2.再除以调整的权重