1.4 进制、编码与内存基础

本篇建立二进制、进制表示、字符编码和内存字节组织的基础认知,为后续类型和指针学习打底。

进制、编码与内存基础

概念说明

计算机底层并不直接认识“数字 12”“字母 A”或“字符串 hello”。 对它来说,数据最终都是一串二进制位,也就是由 01 组成的比特序列。

为了方便阅读,程序员经常用不同进制去表示同一份数据:

  • 二进制适合直接观察位模式。
  • 八进制和十六进制适合压缩表示长二进制串。
  • 十进制更适合人类日常理解数量大小。

文字要进入计算机,还需要一套“字符和编号如何对应”的规则,这就是字符编码。 学 C 语言时最常遇到的不是“C 只支持 ASCII”,而是:字符如何存到内存里一个字符到底占几个字节字符串为什么要以 '\0' 结尾

同时还要建立一个基本概念:内存是按字节编址的。 一个字节通常等于 8 位,而变量、数组和结构体最终都要落到一段连续或不连续的内存区域里。后面学 sizeof、数组、指针和文件读写时,这个基础会不断用到。

语法/规则

  1. 1 Byte = 8 Bit,位是最小的二进制单位,字节是更常见的存储单位。
  2. 十进制字面量直接写,例如 26;八进制常以前导 0 开头,例如 032;十六进制以 0x0X 开头,例如 0x1A
  3. 标准 C 的整数写法里,0 开头不表示“普通十进制”,而通常表示八进制,这一点非常容易写错。
  4. 字符编码描述的是“字符与编号的关系”,常见有 ASCII、GBK、Unicode、UTF-8 等。
  5. 字符串在 C 里本质上是以 \0 结尾的字符序列,因此字符串长度和实际占用的数组空间不完全是一回事。
  6. 内存里的同一串比特,按不同类型解释时可能得到完全不同的含义,这也是类型系统和强制类型转换重要的原因。
  7. 十六进制在调试中非常常见,因为它和二进制之间转换方便,也很适合观察地址、掩码和字节内容。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>

int main(void) {
    int value = 26;
    char letter = 'A';

    printf("decimal = %d\n", value);
    printf("octal = %o\n", value);
    printf("hex = %X\n", value);
    printf("letter = %c\n", letter);
    printf("code = %d\n", letter);
    return 0;
}

输出结果:

1
2
3
4
5
decimal = 26
octal = 32
hex = 1A
letter = A
code = 65

这个例子说明了两件事: 同一个整数可以用不同进制显示;字符 'A' 在底层也可以按它的编码值 65 来观察。

常见错误

  1. 012 当成十进制 12,实际上它通常会被解释为八进制字面量。
  2. 以为 C 语言“固定只用 ASCII”,忽略了源文件编码、终端编码和运行环境编码都会影响字符显示。
  3. 把字符常量 'A' 和字符串字面量 "A" 当成同一种东西来用。
  4. 忘记字符串末尾还需要一个 \0,导致数组空间预留不够。
  5. 只会背 KBMB 这些单位,却不知道数组长度、sizeof 和文件大小最终都要落回字节这个尺度上理解。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字