Printf()打印字符为32位

时间:2018-03-16 18:13:54

标签: c printf

我正在进行快速测试,以确保我的指针算法失效​​:

的main.c

#include <stdio.h>
#include <stdlib.h>

#define ADDRESS    0xC0DCA11501LL
#define LENGTH     5


void print_address( char *, char );

/* Main program */
int main( int argc, char *argv[] )
{
    char nums[ LENGTH ];

    /* LSB first */
    for( int i = 0; i < LENGTH; i++ )
    {
        nums[ i ] = ( ADDRESS >> ( 8 * i ) ) & 0xFF;
    }

    print_address( nums, LENGTH );

    system("PAUSE");

    return 0;
}

void print_address( char *data, char len )
{
     char *data_ptr = data;

     while( len-- )
     {
            printf( "%X\n", *data_ptr++ );
     }
}

我期望以{十六进制格式首先打印出LSB的ADDRESS字节。但最后3个字节似乎是用32位长度打印的:

1
15
FFFFFFA1
FFFFFFDC
FFFFFFC0
Press any key to continue . . .

这是由于我的位移算术,特定于编译器,某些printf()行为吗?

(我在Windows 10上使用MinGW GCC v6.3.0进行编译。)

3 个答案:

答案 0 :(得分:5)

我认为您的char被用作签名值并且您看到了FFFF,因为0xA1大于0x80因此显示签了。尝试使用unsigned char指针(以及函数原型中的nums数组和data),问题应该消失。

答案 1 :(得分:2)

类型char似乎已在您的环境中签名,因此A1作为8位值实际上代表负数。请注意,varargs printf被提升为int类型,负数用前导1 - 位填充。换句话说,当提升为32位整数时,签名A1将给出FFFFFFA1。这就是原因。

改为使用unsigned char

void print_address( unsigned char *, char );

/* Main program */
int main( int argc, char *argv[] )
{
    unsigned char nums[ LENGTH ];

    /* LSB first */
    for( int i = 0; i < LENGTH; i++ )
    {
        nums[ i ] = ( ADDRESS >> ( 8 * i ) ) & 0xFF;
    }

    print_address( nums, LENGTH );

    system("PAUSE");

    return 0;
}

void print_address( unsigned char *data, char len )
{
    unsigned char *data_ptr = data;

    while( len-- )
    {
        printf( "%X\n", *data_ptr++ );
    }
}

答案 2 :(得分:0)

问题是printf不知道您的数据类型是char。

试试这个

void print_address( char *data, char len )
{
     char *data_ptr = data;

     while( len-- )
     {
            printf( "%02X\n", *data_ptr++ &0xFF);
     }
}

结果:

[jmgomez@d1 tmp]$ a.o
01
15
A1
DC
C0
sh: PAUSE: command not found
[jmgomez@d1 tmp]$