C 取消引用字符指针i';我得到了意想不到的结果

C 取消引用字符指针i';我得到了意想不到的结果,c,pointers,C,Pointers,我想使用char ptr从缓冲区发送16位数据中的8位数据(十六进制格式),因此为此,我采用了“Unsigned short int”数组,并使用char对其进行解引用。但在输出中,额外的“FFFFFF”会附加到我的数据中 代码段: unsigned short int buf[50]={0},j; char*ptr=buf; //手动输入一些16位数据 buf[0]=0xAAAA; buf[1]=0xCCBB; buf[2]=0x1234; buf[3]=0xABCD; 对于(j=0;j而言

我想使用char ptr从缓冲区发送16位数据中的8位数据(十六进制格式),因此为此,我采用了“Unsigned short int”数组,并使用char对其进行解引用。但在输出中,额外的“FFFFFF”会附加到我的数据中

代码段:


unsigned short int buf[50]={0},j;
char*ptr=buf;
//手动输入一些16位数据
buf[0]=0xAAAA;
buf[1]=0xCCBB;
buf[2]=0x1234;
buf[3]=0xABCD;

对于(j=0;j而言,
ptr
指针的类型需要在此处取消签名:

unsigned short int buf[50]={0},j;
unsigned char *ptr=buf;
//entering some 16bit data manually
buf[0]=0xAAAA;
buf[1]=0xCCBB;
buf[2]=0x1234;
buf[3]=0xABCD;

for(j=0;j<8;j++)
{
    printf("%X\t",*ptr);
    ptr++;
}

ptr
指针的类型需要在此处取消签名:

unsigned short int buf[50]={0},j;
unsigned char *ptr=buf;
//entering some 16bit data manually
buf[0]=0xAAAA;
buf[1]=0xCCBB;
buf[2]=0x1234;
buf[3]=0xABCD;

for(j=0;j<8;j++)
{
    printf("%X\t",*ptr);
    ptr++;
}

首先,你的代码应该如下所示

unsigned short int buf[50] = {0}, j;
char *ptr = (char *)buf;
//entering some 16bit data manually
buf[0] = 0xAAAA;
buf[1] = 0xCCBB;
buf[2] = 0x1234;
buf[3] = 0xABCD;

for (j = 0; j < 8; j++) {
    printf("%X ", *ptr); // "p" is not defined any where
    ptr++;               // i think, it's got to be "ptr"
}
unsigned short int buf[50]={0},j;
char*ptr=(char*)buf;
//手动输入一些16位数据
buf[0]=0xAAAA;
buf[1]=0xCCBB;
buf[2]=0x1234;
buf[3]=0xABCD;
对于(j=0;j<8;j++){
printf(“%X”,*ptr);//“p”在任何地方都没有定义
ptr++;//我想,应该是“ptr”
}
关于
FF…
前缀:

  • 在前两行之后

    a) 50*2(短
  • 的大小)=100字节被清零

    b) 然后,前8个字节被分配为
    aa aa bb cc 34 12 cd ab

  • 指针
    ptr
    是一个
    (char*)
    (指向一个单字节
    char
    ),但是
    printf
    尝试将它们打印为4字节整数

  • 由于
    *ptr
    取消对单个字节的引用,
    printf
    将其转换为4字节整数。你最好检查一下C语言书中关于
    char
    int
    &二进制数的转换的章节。基本上,那一章会告诉你;在从1字节到4字节的转换过程中,最左边的位向左复制。就是,

    • 1字节十六进制:aa
      1字节二进制代码:10101010
      转换为
      4字节二进制代码:11111111…10101010
      (最左边的位
      1
      在完成4字节时向左复制;这是
      FF
      前缀的来源)
    • 1字节十六进制:12
      1字节位:00010010
      转换为
      4字节位:00000000…00010010
      (当完成4字节时,最左边的位
      0
      向左边复制;全部为零,您看不到任何
      FF
      前缀)

    首先,您的代码应该如下所示

    unsigned short int buf[50] = {0}, j;
    char *ptr = (char *)buf;
    //entering some 16bit data manually
    buf[0] = 0xAAAA;
    buf[1] = 0xCCBB;
    buf[2] = 0x1234;
    buf[3] = 0xABCD;
    
    for (j = 0; j < 8; j++) {
        printf("%X ", *ptr); // "p" is not defined any where
        ptr++;               // i think, it's got to be "ptr"
    }
    
    unsigned short int buf[50]={0},j;
    char*ptr=(char*)buf;
    //手动输入一些16位数据
    buf[0]=0xAAAA;
    buf[1]=0xCCBB;
    buf[2]=0x1234;
    buf[3]=0xABCD;
    对于(j=0;j<8;j++){
    printf(“%X”,*ptr);//“p”在任何地方都没有定义
    ptr++;//我想,应该是“ptr”
    }
    
    关于
    FF…
    前缀:

  • 在前两行之后

    a) 50*2(短的大小)=100字节被清零

    b) 然后,前8个字节被分配为
    aa aa bb cc 34 12 cd ab

  • 指针
    ptr
    是一个
    (char*)
    (指向一个单字节
    char
    ),但是
    printf
    尝试将它们打印为4字节整数

  • 由于
    *ptr
    取消对单个字节的引用,
    printf
    将其转换为4字节整数。你最好检查一下C语言书中关于
    char
    int
    &二进制数的转换的章节。基本上,那一章会告诉你;在从1字节到4字节的转换过程中,最左边的位向左复制。就是,

    • 1字节十六进制:aa
      1字节二进制代码:10101010
      转换为
      4字节二进制代码:11111111…10101010
      (最左边的位
      1
      在完成4字节时向左复制;这是
      FF
      前缀的来源)
    • 1字节十六进制:12
      1字节位:00010010
      转换为
      4字节位:00000000…00010010
      (当完成4字节时,最左边的位
      0
      向左边复制;全部为零,您看不到任何
      FF
      前缀)
        • char*ptr=buf这是无效的C。由于指针类型不兼容,这违反了“简单赋值”的约束。编译器必须给你一个诊断信息,比如警告。您可以通过在赋值之前强制转换来修复此问题:
          char*ptr=(char*)buf

        • buf[1]=0xCCBB
          etc在内存中存储无符号short,与任何整数类型一样,它是根据endianess存储的。如果您使用的是一台x86 PC,它是小端,0xBB存储在最低的地址上。这就是为什么在以后逐字节打印它们时,它们会向后显示

        • printf(“%X\t”,*ptr)这条线上发生了很多奇怪的事情

          • 首先,我们必须了解
            char
            具有实现定义的签名性。因此,它是一种不应用于原始二进制操作或任何形式的算术的类型
          • 在您的特定编译器上,
            char
            碰巧被签名
          • printf
            是一个可变函数。这样的函数是外来的(也是不好的做法),并且有很多特殊的规则。其中一条特殊规则规定,传递给变量函数的每个参数都经过一种特殊的隐式提升,称为“默认参数提升”。此规则表示所有小整数类型(如
            char
            )都将升级为
            int
            类型
          • 每当有符号的char
          或任何其他小整数类型升级为较大的有符号类型时,都会对其进行符号扩展,这意味着如果它包含负的十进制值,则会保留该符号
        • 如果您的8位有符号字符指向数据,则它将被视为负数,因为<
          #include <stdio.h>
          #include <stdint.h>
          
          int main()
          {
            uint16_t buf[50];
            uint8_t* ptr = (uint8_t*)buf;
            
            buf[0]=0xAAAA;
            buf[1]=0xCCBB;
            buf[2]=0x1234;
            buf[3]=0xABCD;
          
            for(int i=0; i<8; i++)
            {
                printf("%X\t",*ptr);
                ptr++;
            }
          }