C语言中的不同数据类型所占用的内存大小是不同的。比如char类型占用1个字节,int类型占用4字节。那么指针的偏移步长是不是与指针的类型有关呢?
我们先来看几个简单例子
例子1:
#include <stdio.h>
int main()
{
char str[] = "abcdefgh";
char* p = str;
printf("str[0]的地址:%p, a[0]的值:%c\n", &str[0], str[0]);
printf(" p+0的地址:%p, p+0的值:%c\n", (p + 0), *(p + 0));
printf("str[1]的地址:%p, a[1]的值:%c\n", &str[1], str[1]);
printf(" p+1的地址:%p, p+1的值:%c\n", (p + 1), *(p + 1));
printf("str[2]的地址:%p, a[2]的值:%c\n", &str[2], str[2]);
printf(" p+2的地址:%p, p+2的值:%c\n", (p + 2), *(p + 2));
return 0;
}
通过指针偏移后的地址值可以看出,char类型的指针偏移一个单位时指针就指向了下一个字符,也就是地址偏移了1个字节。
例子2:
#include <stdio.h>
int main()
{
int arr[5] = {1, 2, 3, 4, 5};
int* p = arr;
printf("arr[0]的地址:%p, a[0]的值:%d\n", &arr[0], arr[0]);
printf(" p+0的地址:%p, p+0的值:%d\n", (p + 0), *(p + 0));
printf("arr[1]的地址:%p, a[1]的值:%d\n", &arr[1], arr[1]);
printf(" p+1的地址:%p, p+1的值:%d\n", (p + 1), *(p + 1));
printf("arr[2]的地址:%p, a[2]的值:%d\n", &arr[2], arr[2]);
printf(" p+2的地址:%p, p+2的值:%d\n", (p + 2), *(p + 2));
return 0;
}
通过指针偏移后的地址值可以看出,int类型的指针偏移一个单位时指针就指向数组的下一个元素,也就是地址偏移了4个字节。
例子3:
#include <stdio.h>
int main()
{
int a = 1;
char* p = (char*)&a;
*(p + 1) = 2;
printf("a = %d\n", a);
*(p + 2) = 3;
printf("a = %d\n", a);
printf(" p的地址:%p\n", p);
printf("p+1的地址:%p\n", p+1);
printf("p+2的地址:%p\n", p+2);
return 0;
}
1.在vs的调试模式下可以查看到整型变量a的地址及地址所存放的类容。在指针p偏移前,a的地址存放的内容(4个字节)为 01 00 00 00
2.程序执行*(p+1)=2之后,a的地址的存放内容为 01 02 00 00,也就是第2字节的数据被修改为 2。
3.程序执行*(p+2)=3之后,a的地址的存放内容为 01 02 03 00,也就是变量a的第3个字节的数据被修改为3。
4.通过程序运行结果可以看出,char类型指针指向了int类型变量,指针的偏移步长并不是4个字节,而是1个字节。
结论:
指针的偏移步长与指向的变量的类型无关,与指针本身的类型有关。比如char类型指针+1时,内存地址就偏移1个字节;int类型指针+1时,内存地址就偏移4个字节。