C/C++ 中,unsigned char 是一种内置数据类型,它与普通的 char 类型类似,但其值总是非负(正数或 0)。它通常用于处理原始二进制数据,例如字节流、图像数据、文件缓冲区等。unsigned char 是用于表示原始字节数据的无符号类型,数值范围是 0~255,广泛应用于低层内存操作、文件 I/O 和通信协议中。

1、unsigned char 与 signed char

类型

字节数(通常)

数值范围

char(默认)

1 字节

-128127 0 255(取决于实现)

signed char

1 字节

-128127

unsigned char

1 字节

0255

char 的符号属性(signed/unsigned)取决于编译器,但 unsigned char 明确是无符号的。

#include <stdio.h>

int main() {
    unsigned char u = 255;
    signed char s = -1;

    printf("unsigned char: %u\n", u);  // 输出 255
    printf("signed char: %d\n", s);    // 输出 -1

    return 0;
}

2、unsigned char 作用

unsigned char 是一种 无符号字符类型,在处理二进制数据、需要精确控制内存、或者做底层嵌入式编程,unsigned char 是非常常用且重要的类型。

1)表示原始字节数据

用于图像、网络、音频等“二进制”处理场景,确保不会意外解释为负数。

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

int main() {
    FILE *file = fopen("example.bin", "rb"); // 以二进制只读模式打开文件
    if (file == NULL) {
        perror("无法打开文件");
        return 1;
    }

    unsigned char buffer[1024]; // 定义一个字节缓冲区

    size_t bytesRead = fread(buffer, 1, 1024, file); // 从文件中读取最多1024字节
    if (bytesRead == 0) {
        perror("读取文件失败或文件为空");
        fclose(file);
        return 1;
    }

    printf("成功读取了 %zu 字节的数据:\n", bytesRead);
    for (size_t i = 0; i < bytesRead; ++i) {
        printf("%02X ", buffer[i]); // 以十六进制打印每个字节
        if ((i + 1) % 16 == 0) printf("\n");
    }
    printf("\n");

    fclose(file); // 关闭文件
    return 0;
}

2)做位操作时更安全

使用 signed char 时,右移可能进行算术移位,结果可能不符合预期。unsigned 保证逻辑移位,结果更直观。

#include <stdio.h>

int main() {
    unsigned char val = 0b11110000; // 二进制:11110000,即十进制 240

    printf("原始值: 0x%02X (%u)\n", val, val);

    val = val >> 2; // 右移两位:00001111,即十进制 60

    printf("右移2位后的值: 0x%02X (%u)\n", val, val);

    return 0;
}

3)避免符号扩展

当把 char 转换为 int 或进行位操作时,signed char 会自动进行符号扩展。

#include <stdio.h>

int main() {
    // signed char 示例
    signed char s = 0xFF;   // 0xFF = -1(有符号的情况下)
    int i = s;              // 会进行符号扩展,i = -1(0xFFFFFFFF)

    // unsigned char 示例
    unsigned char u = 0xFF; // 0xFF = 255(无符号)
    int j = u;              // 直接转换为 int,j = 255(0x000000FF)

    printf("signed char s = 0xFF --> int i = %d (0x%X)\n", i, i);
    printf("unsigned char u = 0xFF --> int j = %d (0x%X)\n", j, j);

    return 0;
}