飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 编程基础概念

    • 冯·诺依曼体系结构
    • 数据在计算机中的表示
    • 编程语言的层次
    • C语言的起源与发展
    • C99标准的主要改进
    • 开发环境搭建
    • 第一个C程序
    • 编译与运行流程
    • 可移植性风险的三级体系
  • 第2章 数据类型与运算

    • 字符集与标识符
    • 关键字
    • 注释
    • char 类型
    • short 与 int
    • long 与 long long
    • 有符号与无符号
    • 取值范围与 limits.h
    • float 与 double
    • long double
    • _Bool 类型
    • 变量声明与定义
    • 常量
    • 转义序列
    • 算术运算符
    • 赋值运算符
    • 自增自减运算符
    • 关系与判等运算符
    • 逻辑运算符
    • 位运算符
    • 条件运算符
    • 逗号运算符
    • 运算符优先级
    • 隐式类型转换
    • 显式类型转换
  • 第3章 控制流

    • 表达式语句与空语句
    • 复合语句
    • if 语句
    • switch 语句
    • while 循环
    • do-while 循环
    • for 循环
    • break 与 continue
    • goto 语句
    • return 语句
  • 第4章 函数与模块化编程

    • 函数定义
    • 函数声明与原型
    • main 函数
    • 函数调用机制
    • 传值调用
    • 数组参数
    • 作用域
    • 存储期
    • 链接属性
    • static 与 extern
    • 递归
    • 头文件与源文件
    • 头文件保护
    • include 规则
  • 第5章 数组与字符串

    • 一维数组声明与初始化
    • 数组的存储模型
    • 数组访问与越界
    • 数组操作
    • 二维数组
    • 变长数组 VLA
    • 字符串基础
    • 字符串输入输出
    • 字符串处理函数
    • 字符串与数字转换
  • 第6章 指针

    • 指针的概念
    • 指针的声明与使用
    • 指针运算
    • const 与指针
    • 数组名与指针
    • 指针遍历数组
    • 指针与多维数组
    • 指针作为函数参数
    • 函数返回指针
    • 函数指针
    • 二级指针
    • 复杂声明解析
  • 第7章 结构体、联合体与枚举

    • 结构体定义与声明
    • 结构体初始化
    • 结构体成员访问
    • 结构体嵌套
    • 结构体指针
    • 结构体与函数
    • 联合体
    • 联合体与类型双关
    • 枚举类型
    • 位域
    • 内存对齐与填充
  • 第8章 动态内存管理

    • malloc 与 free
    • calloc 与 realloc
    • 内存泄漏
    • 悬垂指针
    • 内存分配策略
    • 自定义内存池
    • Valgrind 与内存检测
    • 内存碎片
    • 内存对齐分配
    • 常见内存错误
  • 第9章 文件输入输出

    • 文件打开与关闭
    • 文本读写
    • 格式化输入输出
    • 二进制读写
    • 文件定位
    • 错误处理
    • 标准流
    • 临时文件
    • 文件操作示例
  • 第10章 预处理器

    • 预处理器基础
    • 宏定义
    • 带参数的宏
    • 条件编译
    • 头文件包含
    • 预定义宏
    • 宏的高级技巧
    • 预处理器陷阱
    • 编译器特定扩展
  • 第11章 标准库概览

    • 标准库概述
    • assert.h
    • ctype.h
    • errno.h
    • float.h
    • limits.h
    • locale.h
    • math.h
    • setjmp.h
    • signal.h
    • stdarg.h
    • stddef.h
    • stdlib.h
  • 第12章 进阶主题

    • 内联函数
    • 变长数组 VLA
    • 复数类型
    • 布尔类型
    • stdint 与 inttypes
    • 灵活数组成员
    • 匿名结构体与联合体
    • 静态断言
    • 线程支持
    • 原子操作

编程语言的层次

编程语言是人与计算机沟通的桥梁。从底层的机器语言到高层的高级语言,每一层都在抽象和易用性之间做权衡。C 语言处于这个谱系的中间位置,因此被称为"中级语言"——它既保留了直接操作硬件的能力,又提供了足够的抽象让程序员高效表达逻辑。

机器语言

机器语言是计算机唯一能直接执行的语言,由 0 和 1 组成的二进制指令构成。每条指令对应 CPU 的一个基本操作,如数据移动、加法、跳转等。

/* 机器语言示例(x86-64):将 42 放入寄存器 eax */
10111000 00101010 00000000 00000000 00000000
/* 对应的十六进制:B8 2A 00 00 00 */

机器语言的优点是指令直接对应硬件操作,执行效率最高。缺点是几乎无法由人类直接编写和阅读——一串二进制数字没有任何语义提示,写错一位就可能导致完全不同的行为。

汇编语言

汇编语言用人类可读的助记符代替二进制指令,是机器语言的一层薄包装:

; 汇编语言示例(x86-64 AT&T 语法)
movl    $42, %eax       ; 将 42 放入 eax 寄存器
addl    $8, %eax        ; eax = eax + 8

汇编指令与机器指令基本一一对应,汇编器(Assembler)负责将助记符翻译为二进制。汇编语言仍然直接操作寄存器和内存地址,程序员需要了解 CPU 架构细节。

C 语言可以直接嵌入汇编代码(内联汇编),在需要极致性能或操作特定硬件时使用:

/* GCC 内联汇编示例 */
int result;
__asm__ volatile (
    "movl $42, %0"
    : "=r" (result)     /* 输出 */
);

高级语言

高级语言用更接近人类思维的语法描述算法,屏蔽了硬件细节。一行高级语言代码通常对应多条机器指令。

/* C 语言:简洁、可读 */
int sum = 0;
for (int i = 1; i <= 100; i++)
    sum += i;

/* 等效的汇编代码(概念示意,约 10+ 条指令) */
/* 初始化计数器、比较、跳转、加法、递增、循环... */

高级语言的优势在于:

  • 可读性:代码意图清晰,便于维护
  • 可移植性:同一份代码可在不同硬件上编译运行
  • 抽象能力:函数、结构体、类型系统帮助管理复杂度

编译型 vs 解释型

编译型语言(如 C、C++、Rust)在程序运行前通过编译器将整个源代码翻译为机器码,生成可执行文件。运行时直接执行机器码,效率高。

# C 编译流程
gcc source.c -o program    # 编译
./program                  # 运行

解释型语言(如 Python、JavaScript)由解释器逐行读取源代码并即时执行,没有独立的编译步骤。开发迭代快,但运行效率通常低于编译型语言。

# Python 解释执行
python script.py           # 直接运行源代码

C 语言是典型的编译型语言。编译过程分为四个阶段:预处理、编译、汇编、链接。这种"先翻译后执行"的模式让 C 程序能达到接近汇编的性能,同时保持高级语言的可维护性。

C 语言的定位

C 语言诞生于 1972 年,设计目标是编写操作系统(Unix)。它的设计哲学可以概括为:

  • 信任程序员:提供直接操作内存的指针,不做过多安全检查
  • 保持简洁:语言特性精炼,核心概念少而精
  • 接近硬件:可以精确控制内存布局、数据表示、调用约定
  • 可移植:同一份代码通过重新编译可在不同平台运行

这些特性使 C 语言成为系统编程的首选:操作系统内核、嵌入式固件、数据库引擎、编译器本身,大多用 C 或 C++ 编写。当你需要精确控制性能、内存或硬件时,C 语言是理想选择;当你需要快速开发、快速迭代时,更高层的语言可能更合适。

/* C 语言直接操作内存的示例 */
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;
printf("%d\n", *p);        /* 10 */
printf("%d\n", *(p + 2));   /* 30:直接通过地址偏移访问 */
上一页
数据在计算机中的表示
下一页
C语言的起源与发展