指针的步长及意义(C语言基础)

指针的步长及意义


不同类型的指针有何不同的意义

  • 指针变量+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中的二进制位是相反的
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁金金

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值