关于二级指针作参数

本文介绍了在C++中进行大小端转换时遇到的二级指针问题及其解决方法。代码示例中,由于优先级问题导致了段错误,通过调整指针操作解决了该问题。同时,指针赋值错误也得到了修正,明确了二级指针与一级指针的区别。修复后的代码能够正确实现数组前两个字节的大小端转换并移动指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近日在进行大小端转换时碰到一个关于二级指针的问题,为避免遗忘,在此整理。

原代码如下

#include <stdio.h>

#define Little ('l')
#define Big ('b')

#define uint8_t char
#define uint16_t short
union order_help
{
    uint8_t c[4];
    unsigned long l;
};


typedef union order_help order_help_t;

const order_help_t _order;

uint8_t order() { return (uint8_t)(_order.l); }

uint16_t ByteOrderSwitch16(uint16_t value)
{
    return (((value & 0x00ff) << 8) | ((value & 0xff00) >> 8));
}

int switchU16(int _order, uint8_t **_buf, uint16_t _size, uint16_t *_v)
{
   if (_size < 2)
    {
        return 0;
    }

    uint8_t *tmp = (uint8_t *)_v;
    //memcpy(tmp, (UInt8 *)(*_buf), 2);

    printf("buf0:%#x\n", **_buf);
    tmp[0] = *_buf;
    *_buf++;

    printf("buf1:%#x\n", **_buf);
    tmp[1] = *_buf;
    *_buf++;
    printf("tmp0:%#x tmp1:%#x _v:%p %x\n", tmp[0], tmp[1], _v, *_v);
    if (_order != order())
    {
        *_v = ByteOrderSwitch16(*_v);
    }
    //*((UInt8*)_buf) += 2;
    return 1;
}

int main ()
{
        uint8_t buf[5] = {0x01, 0x02, 0x03, 0x04, 0x05};
        uint16_t ret = 0;
        char *p_buf = buf;
        switchU16(Big, &p_buf, 2, &ret);
        printf("ret = %#x\n", ret);

        uint8_t *temp = (uint8_t *)&ret;
        temp[0] = 0x07;
        temp[1] = 0x08;
        printf("temp:%p temp[0]:%p %d temp[1]:%p %d ret:%p %#x\n",
                temp, &temp[0], temp[0], &temp[1], temp[1], &ret, ret);

        return 0;
}

         以上代码实现两个功能:

                1:将数组前两个字节进行大小端转换

                2:指针后移两个字节

                注:由于memcy有时会出现问题所以改用直接赋值的方法。

        但是运行后出现问题两个问题:

                1:段错误

                2:输出的值错误

        经排查发现问题所在:

                问题1:段错误是因为

*_buf++;

                所以上段代码旨在将传入的指针向后移,但是因为“右++”优先级>“*”优先级,所以造成段错误,应改为

(*_buf)++;

                问题2:赋值错误问题是因为

uint8_t *tmp = (uint8_t *)_v;

printf("buf0:%#x\n", **_buf);
tmp[0] = *_buf;

        由于传入的是二级指针“**_buf”,申请了一级指针“*tmp”,而"tmp[0]"表示该指针下的值,所以上述代码实际上是把二级指针下的一级指针地址赋给了“tmp[0]”,导致赋值错误。

        经验证:上述推论正确:

buf0:0x1
buf1:0x2
tmp0:0xffffffd0 tmp1:0xffffffd1 _v:0x7fffccd8b6be ffffd1d0
ret = 0xffffd0d1

正确输出结果应为:

buf0:0x1
buf1:0x2
tmp0:0x1 tmp1:0x2 _v:0x7fffc0831dde 201
ret = 0x102
temp:0x7fffc0831dde temp[0]:0x7fffc0831dde 7 temp[1]:0x7fffc0831ddf 8 ret:0x7fffc0831dde 0x807

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值