指针的步长及意义
文章目录
- 指针的步长及意义
- 指针变量+1后偏移的字节数不同
- 指针[解引用](https://so.csdn.net/so/search?q=解引用&spm=1001.2101.3001.7020)时取出的字节数不同
- 其他例子
不同类型的指针有何不同的意义
- 指针变量+1后跳跃字节数量不同
- 解引用的时候,取出字节数量不同
指针变量+1后偏移的字节数不同
代码演示:(不同编译器下偏移值可能不同)
void test01()
{
char * p1 = NULL;
printf("%d\n", p1);
printf("%d\n", p1 + 1);//+1偏移1个字节
int * p2 = NULL;
printf("%d\n", p2);
printf("%d\n", p2 + 1);//+1偏移4个字节
double * p3 = NULL;
printf("%d\n", p3);
printf("%d\n", p3 + 1);//+1偏移8个字节
}
运行结果:
总结:vs下常见指针的偏移值分别为:
char *:1个字节
int *:4个字节
double *:8个字节
数组指针:偏移整个数组大小
结构体指针:偏移整个结构体大小
指针解引用时取出的字节数不同
代码演示:
void test02()
{
char buf[1024] = { 0 }; //1024字节
int a = 1000; //4字节
memcpy(buf, &a, sizeof(int));//内存拷贝函数
char * p = buf;
printf("%d\n", *(int*)p );//指针类型强制转换在对其解引用
}
运行结果:
总结:不同类型指针解引用时取出数据的字节数不同
VS下常见指针类型解引用时取出的字节数分别为:
char *:1个字节(通常需要强转)
指针解引用时取出数据的字节数不同
VS下常见指针类型解引用时取出的字节数分别为:
char *:1个字节(通常需要强转)
int * :4个字节
其他例子
// todo 字节序转换
#include <stdio.h>
#include <arpa/inet.h>
void printf_bin(int num) // 这个函数将整形变量以二进制的形式打印出来
{
int i, j, k;
unsigned char *p = (unsigned char *)&num + 3; // p先指向num后面第3个字节的地址,即num的最高位字节地址
for (i = 0; i < 4; i++) // 依次处理4个字节(32位)
{
j = *(p - i); // 取每个字节的首地址,从高位字节到低位字节,即p p-1 p-2 p-3地址处
for (int k = 7; k >= 0; k--) // 处理每个字节的8个位,注意字节内部的二进制数是按照人的习惯存储!
{
if (j & (1 << k)) // 1左移k位,与单前的字节内容j进行或运算,如k=7时,00000000&10000000=0 ->该字节的最高位为0
printf("1");
else
printf("0");
}
printf(" "); // 每8位加个空格,方便查看
}
printf("\r\n");
}
int main()
{
char buf[4] = {192, 168, 1, 2}; // 32位
// todo1 将 4字节(32位)的数据存放在 num容器(int 类型, 32位)中
unsigned int num = *(unsigned int *)buf; // int*把buf(char类型的数组首地址强转为int*类型的地址),
// 再*(解引用)取出四个字节的数据,而int 类型刚好是4字节,就能存放这四字节数据
// 你可以把 int num 当成是定义了一个能存放32位数据的容器,只是这32位存放的是
// 192.168.1.2 的用二进制(01)表示的情况
printf_bin(num);
printf("%u\n", num); //%u用于打印 unsigned int .
// 打印结果 33663168 . 这么大是因为 他不会每八位隔断,每八位分别做二进制转换
//(像把 00000010 00000001 10101000 11000000)隔断为 192.168.1.2 而是
// 直接将这个32位的数作为整体进行二进制转换
printf("================");
int n1 = 33663168; // 实际上这个十进制数用二进制的表示就是 00000010 00000001 10101000 11000000
printf_bin(n1);
// htol() 函数的作用是将一个32位数从主机字节顺序转换成网络字节顺序。
unsigned int sum = htonl(num);
printf_bin(sum); // 11000000 10101000 00000001 00000010 和 num中的二进制位是相反的
}