第01章 初识C语言

发布时间:2026/7/22 13:44:02
第01章 初识C语言 第1章 初识C语言章节摘要本章将带你走进C语言的世界了解C语言的历史、特点和应用领域搭建开发环境编写第一个C程序理解编译过程为后续深入学习打下坚实基础。1.1 C语言的诞生与发展历史C语言的诞生C语言由**丹尼斯·里奇Dennis Ritchie**于1972年在贝尔实验室开发最初是为了开发UNIX操作系统而设计的。C语言的前身是B语言而B语言又源自BCPL语言。重要时间节点1972年C语言诞生1978年Brian Kernighan和Dennis Ritchie出版《The C Programming Language》KR C1989年ANSI发布C语言标准ANSI C / C891990年ISO采纳ANSI C标准C901999年发布C99标准增加了许多新特性2011年发布C11标准增加了多线程支持等特性2018年发布C17标准C18主要是bug修复C语言的影响C语言对计算机科学产生了深远影响UNIX操作系统用C语言重写使其具有良好的可移植性Linux内核完全用C语言编写许多编程语言受C语言影响C、Java、C#、JavaScript、Go等大量系统软件使用C语言开发数据库、编译器、网络协议栈等1.2 C语言的特点高效、灵活、接近底层核心特点1. 高效性接近硬件C语言提供了对内存的直接访问能力执行速度快编译后的代码效率接近汇编语言资源占用少适合资源受限的嵌入式系统2. 灵活性指针操作可以直接操作内存地址位操作支持位级别的数据处理类型转换提供灵活的类型转换机制3. 可移植性标准化有明确的语言标准ANSI C、ISO C跨平台同一份代码可以在不同平台上编译运行广泛支持几乎所有平台都有C编译器4. 简洁性关键字少C89只有32个关键字C99增加到37个语法简单核心语法规则清晰明了易于学习适合作为第一门编程语言5. 强大的标准库丰富的函数提供输入输出、字符串处理、数学运算等功能可扩展性可以创建自己的库C语言的局限性需要注意的问题内存管理需要手动管理内存容易出现内存泄漏类型安全类型检查相对宽松容易出错缓冲区溢出需要程序员自己保证数组访问安全没有面向对象不支持类、继承等面向对象特性1.3 C语言能做什么系统编程、嵌入式、操作系统、编译器应用领域1. 操作系统开发Linux内核完全用C语言编写Windows内核大部分用C语言编写macOS/iOS内核基于Darwin用C语言编写2. 嵌入式系统单片机编程Arduino、STM32等物联网设备智能家居、可穿戴设备汽车电子发动机控制、车载系统3. 系统软件数据库MySQL、PostgreSQL、SQLiteWeb服务器Nginx、Apache编译器GCC、Clang4. 网络编程网络协议栈TCP/IP实现网络工具ping、traceroute、netcat防火墙iptables5. 游戏开发游戏引擎Unreal EngineC但核心是C图形库OpenGL、DirectX的底层实现6. 科学计算数值计算库BLAS、LAPACK科学软件MATLAB的底层实现1.4 C语言与其他语言的对比C vs C特性C语言C编程范式面向过程面向对象 面向过程类和对象不支持支持函数重载不支持支持模板不支持支持异常处理不支持支持标准库较小非常丰富STL学习曲线较平缓较陡峭编译速度快较慢选择建议学习底层原理、系统编程 → 选C大型软件开发、需要面向对象 → 选CC vs Java特性C语言Java内存管理手动管理自动垃圾回收指针支持不支持有引用平台依赖需要重新编译一次编译到处运行执行方式编译为机器码编译为字节码JVM执行性能非常高较高但低于C安全性较低较高应用场景系统编程、嵌入式企业应用、Android开发C vs Python特性C语言Python类型系统静态类型动态类型执行速度非常快较慢开发速度较慢非常快内存管理手动自动语法复杂度中等简单适用场景性能关键型应用快速开发、数据分析1.5 开发环境搭建Windows环境搭建方案一MinGW-w64推荐步骤下载MinGW-w64访问https://www.mingw-w64.org/或使用MSYS2https://www.msys2.org/安装MSYS2推荐方式# 下载msys2-x86_64-latest.exe并安装# 安装后打开MSYS2终端执行pacman-Syupacman-Smingw-w64-x86_64-gcc配置环境变量将C:\msys64\mingw64\bin添加到系统PATH重启命令行窗口验证安装gcc--version方案二Visual Studio下载Visual Studio Community免费安装时选择使用C的桌面开发包含MSVC编译器和调试工具Linux环境搭建Ubuntu/Debian系统# 更新软件包列表sudoaptupdate# 安装build-essential包含gcc、g、make等sudoaptinstallbuild-essential# 验证安装gcc--versionmake--versionCentOS/RHEL系统# 安装开发工具组sudoyum groupinstallDevelopment Tools# 验证安装gcc--versionmacOS环境搭建# 安装Xcode Command Line Toolsxcode-select--install# 验证安装gcc--version# 注意macOS的gcc实际上是clang的别名clang--version1.6 编译器选择GCCGNU Compiler Collection特点开源免费跨平台Linux、Windows、macOS支持多种语言C、C、Fortran等优化能力强使用场景Linux开发跨平台项目开源项目Clang特点基于LLVM编译速度快错误信息友好模块化设计使用场景macOS/iOS开发需要友好错误提示的项目现代化的C/C项目MSVCMicrosoft Visual C特点Windows平台原生支持与Visual Studio深度集成调试工具强大使用场景Windows专属开发需要使用Windows API企业级Windows应用编译器对比编译器平台开源优化错误提示GCC全平台✓优秀良好Clang全平台✓优秀非常好MSVCWindows✗良好良好1.7 IDE与编辑器Visual Studio Code推荐优点轻量级启动快插件丰富跨平台免费开源配置步骤安装VS Code安装C/C扩展Microsoft官方安装Code Runner扩展可选配置编译器路径推荐插件C/C (Microsoft)C/C Compile RunBetter C SyntaxCode RunnerCLion专业IDE优点智能代码补全强大的重构功能内置调试器CMake支持缺点收费学生免费占用资源较多Dev-C初学者友好优点简单易用一键编译运行适合初学者缺点功能相对简单更新较慢Vim/Emacs高级用户优点效率极高高度可定制轻量级缺点学习曲线陡峭需要配置1.8 第一个程序Hello, World!现在让我们一步步创建并运行你的第一个C程序。我们会详细讲解每一个操作步骤。1.8.1 创建项目目录首先我们需要创建一个文件夹来存放我们的代码。Windows系统打开文件资源管理器导航到你想要存放代码的位置比如D:\code右键点击空白处 → 新建 → 文件夹命名为hello或者使用命令行# 打开命令提示符WinR输入cmdmkdirD:\code\hellocdD:\code\helloLinux/macOS系统# 打开终端mkdir~/code/hellocd~/code/hello1.8.2 创建源代码文件现在我们需要创建一个.c文件来编写代码。方法一使用文本编辑器在hello文件夹中右键 → 新建 → 文本文档将文件名改为hello.c注意要显示文件扩展名用记事本或VS Code打开这个文件方法二使用VS Code打开VS Code文件 → 打开文件夹 → 选择hello文件夹点击新建文件图标命名为hello.c方法三使用命令行# Windowstypenulhello.c# Linux/macOStouchhello.c1.8.3 编写代码在hello.c文件中逐行输入以下代码建议手动输入而不是复制粘贴这样能加深记忆#includestdio.hintmain(){printf(Hello, World!\n);return0;}输入提示第1行输入#include stdio.h注意和是英文符号第2行空行按回车键第3行输入int main() {注意有一个空格在main()和{之间第4行按Tab键缩进然后输入printf(Hello, World!\n);第5行按Tab键缩进然后输入return 0;第6行输入}保存文件按CtrlSWindows/Linux或CmdSmacOS或者文件 → 保存1.8.4 代码详解让我们逐行理解这段代码的含义第1行#include stdio.h#include这是一个预处理指令告诉编译器包含一个文件stdio.h标准输入输出头文件StandardInputOutput作用这个头文件包含了printf函数的声明没有它就无法使用printf第3行int main() {int表示这个函数会返回一个整数main主函数的名字每个C程序必须有且只有一个main函数()参数列表这里是空的表示不接收参数{函数体的开始第4行printf(Hello, World!\n);printf打印函数用于在屏幕上显示文本Hello, World!\n要显示的内容双引号表示这是一个字符串\n换行符让光标移到下一行;语句结束符每条语句后面都要加分号第5行return 0;return返回语句0返回值表示程序正常结束约定返回0表示成功返回非0值表示出错第6行}函数体的结束1.8.5 编译程序编写完代码后我们需要将它编译成可执行文件。使用GCC编译推荐打开命令行/终端进入hello文件夹cdD:\code\hello# Windowscd~/code/hello# Linux/macOS执行编译命令gcc hello.c-ohello命令解释gcc调用GCC编译器hello.c源代码文件名-o hello指定输出文件名为helloWindows会自动加.exe后缀如果编译成功不会有任何输出信息会生成一个可执行文件Windowshello.exeLinux/macOShello如果编译失败会显示错误信息比如hello.c:4:5: error: expected ; before return仔细检查代码看是否有拼写错误或缺少分号修改后重新保存再次编译1.8.6 运行程序编译成功后我们可以运行程序了。Windows系统hello.exe# 或者直接输入helloLinux/macOS系统./hello输出结果Hello, World!恭喜你已经成功运行了第一个C程序1.8.7 理解整个过程让我们回顾一下刚才做了什么源代码(hello.c) → 编译器(gcc) → 可执行文件(hello.exe) → 运行 → 输出结果编写源代码用文本编辑器写.c文件编译用gcc将源代码翻译成机器能理解的二进制代码运行执行生成的可执行文件查看结果在屏幕上看到输出1.8.8 修改代码现在让我们修改程序让它更有趣。修改hello.c#includestdio.hintmain(){printf(你好世界\n);printf(这是我的第一个C程序\n);printf(我正在学习C语言\n);return0;}保存并重新编译gcc hello.c-ohello运行./hello# Linux/macOShello.exe# Windows输出你好世界 这是我的第一个C程序 我正在学习C语言1.8.9 使用变量让我们进一步改进程序使用变量来存储信息。修改hello.c#includestdio.hintmain(){intage20;printf(你好世界\n);printf(我今年 %d 岁\n,age);printf(我正在学习C语言\n);return0;}新知识点//单行注释编译器会忽略这一行int age 20;声明一个整数变量age并赋值为20%d占位符表示这里要插入一个整数age要插入的变量编译并运行gcc hello.c-ohello ./hello# Linux/macOShello.exe# Windows输出你好世界 我今年 20 岁 我正在学习C语言1.8.10 常见问题问题1找不到gcc命令gcc 不是内部或外部命令解决方案检查是否已安装GCC参考1.5节检查环境变量PATH是否配置正确问题2找不到hello.c文件gcc: error: hello.c: No such file or directory解决方案确认当前目录是否正确pwdLinux/macOS或cdWindows确认文件名是否正确注意大小写问题3中文乱码解决方案使用英文字符串输出推荐初学者使用Windows系统确保源文件保存为UTF-8编码并在终端中设置正确的代码页# 在命令行中运行此命令后再编译运行chcp65001问题4双击.exe文件窗口闪退原因程序执行完毕后立即关闭解决方案推荐方式在命令行/终端中运行程序而不是双击.exe文件1.9 编译过程详解编译的四个阶段源代码(.c) → 预处理 → 编译 → 汇编 → 链接 → 可执行文件1. 预处理Preprocessing作用处理以#开头的预处理指令展开宏定义处理#include指令删除注释命令gcc-Ehello.c-ohello.i示例原始代码#includestdio.h#definePI3.14159intmain(){printf(PI %f\n,PI);return0;}预处理后hello.i简化版// stdio.h的内容被展开数千行// ...intmain(){printf(PI %f\n,3.14159);// PI被替换return0;}2. 编译Compilation作用将预处理后的代码翻译成汇编代码进行语法检查进行优化命令gcc-Shello.i-ohello.s汇编代码示例hello.s简化版.section .rodata .LC0: .string Hello, World! .text .globl main main: pushq %rbp movq %rsp, %rbp leaq .LC0(%rip), %rdi call puts movl $0, %eax popq %rbp ret3. 汇编Assembly作用将汇编代码翻译成机器码生成目标文件.o或.obj命令gcc-chello.s-ohello.o目标文件二进制文件包含机器指令还不能直接执行需要链接才能生成可执行文件4. 链接Linking作用将目标文件与库文件链接解析符号引用生成可执行文件命令gcc hello.o-ohello链接过程链接C标准库libc链接启动代码crt0.o等解析printf等函数的地址一步编译# 直接从源代码生成可执行文件gcc hello.c-ohello这个命令实际上执行了上述四个步骤。1.10 如何阅读编译器错误信息常见错误类型1. 语法错误Syntax Error示例代码#includestdio.hintmain(){printf(Hello, World!\n)// 缺少分号return0;}错误信息hello.c:4:31: error: expected ; before return printf(Hello, World!\n) ^ ; return 0; ~~~~~~解读hello.c:4:31错误位置文件名:行号:列号error错误类型expected ; before return期望在return前有分号^指向错误位置2. 未声明的标识符示例代码#includestdio.hintmain(){printf(%d\n,x);// x未声明return0;}错误信息hello.c:4:20: error: x undeclared (first use in this function) printf(%d\n, x); ^3. 类型不匹配示例代码#includestdio.hintmain(){intxhello;// 类型不匹配return0;}错误信息hello.c:4:13: warning: initialization of int from char * makes integer from pointer without a cast int x hello; ^~~~~~~4. 缺少头文件示例代码// 没有包含stdio.hintmain(){printf(Hello\n);return0;}错误信息hello.c:3:5: warning: implicit declaration of function printf printf(Hello\n); ^~~~~~阅读错误信息的技巧从第一个错误开始修复后续错误可能是连锁反应注意行号和列号精确定位错误位置理解错误类型error必须修复vs warning建议修复查看上下文有时错误位置不是真正的错误原因使用搜索引擎搜索错误信息可以找到解决方案实战练习练习1输出个人信息题目编写一个程序输出你的姓名、年龄、学校/公司信息。要求使用多个printf语句输出格式美观使用转义字符完整解决方案#includestdio.hintmain(){printf(\n);printf( 个人信息卡片\n);printf(\n);printf(姓名张三\n);printf(年龄20岁\n);printf(学校某某大学\n);printf(专业计算机科学与技术\n);printf(\n);printf(学习目标\n);printf(\t1. 掌握C语言基础语法\n);printf(\t2. 理解计算机底层原理\n);printf(\t3. 能够开发大型项目\n);printf(\n);return0;}知识点\n换行符\t制表符Tab多个printf语句的使用练习2ASCII艺术字题目使用字符绘制ASCII艺术字输出HELLO。完整解决方案#includestdio.hintmain(){printf( H H EEEEE L L OOO \n);printf( H H E L L O O \n);printf( HHHHH EEEE L L O O \n);printf( H H E L L O O \n);printf( H H EEEEE LLLLL LLLLL OOO \n);return0;}输出效果H H EEEEE L L OOO H H E L L O O HHHHH EEEE L L O O H H E L L O O H H EEEEE LLLLL LLLLL OOO练习3查看编译过程题目编写一个简单程序查看编译的四个阶段的输出。源代码test.c#includestdio.h#defineMAX100intmain(){intxMAX;printf(x %d\n,x);return0;}操作步骤# 1. 预处理gcc-Etest.c-otest.i# 查看test.i文件可以看到stdio.h被展开MAX被替换为100# 2. 编译gcc-Stest.i-otest.s# 查看test.s文件可以看到汇编代码# 3. 汇编gcc-ctest.s-otest.o# test.o是二进制文件无法直接查看# 4. 链接gcc test.o-otest# 生成可执行文件# 5. 运行./test查看预处理结果# 只查看预处理后的main函数部分gcc-Etest.c|grep-A10int main练习4修复编译错误题目以下代码有多个错误请找出并修复。错误代码#includestdio.hintmain(){printf(Hello, World!\n)intx10printf(x %d\nx);return0}错误分析第5行printf语句末尾缺少分号第6行变量声明语句末尾缺少分号第7行printf的两个参数之间缺少逗号分隔符第8行return语句末尾缺少分号正确代码#includestdio.hintmain(){printf(Hello, World!\n);intx10;printf(x %d\n,x);return0;}