恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

C语言基础核心:printf/scanf、类型转换与编译链接避坑

  • 首页
  • 资讯中心
  • /
  • C语言基础核心:printf/scanf、类型转换与编译链接避坑

相关资讯

Gromacs伞形采样实战:从牵引模拟到WHAM计算PMF的完整避坑指南 2026/9/18 14:06:50
商铺承包协议工程化拆解:从条款设计到数字化管理 2026/9/18 14:06:50
汽车理论习题解答MATLAB实现:动力性仿真与工程化建模 2026/9/18 14:06:50

最新资讯

权限模式非交互,TaoToken Key 分配
Prettier 构建脚本完全指南:从 yarn build 到 npm 发布的产物流水线
IT系统FMEA:严重度、发生度、探测度评价准则与RPN实践
模拟器架构三要素:时间驱动、状态注入与生态扰动
VB6+Access数据库编程:ADO对象详解与防坑指南
AIBrix 语义路由实战:基于 Envoy ext_proc 与 MoM 虚拟模型实现多模型智能分发

今日推荐

2026年AI设计工具在PPT制作中的核心应用与评测
Matlab手写逻辑回归:从数学原理到多变量概率预测模型实现
高值医用耗材研报PDF:用Python完成字段抽取、清洗与趋势预测

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

C语言基础核心:printf/scanf、类型转换与编译链接避坑

发布时间:2026/9/18 14:11:50
C语言基础核心:printf/scanf、类型转换与编译链接避坑 简介围绕C语言入门学习整理的《C语言基础知识.pdf》面向零基础或需要夯实底子的编程初学者、计算机专业学生与备考复习的自学者重点解决C语言基本概念零散、输入输出函数与程序运行流程理解不清的问题。压缩包内共1个PDF文档约437KB属于第一讲「C语言概述」的讲义式内容以文字、示例代码与表格形式组织篇幅精炼便于打印或移动端阅读。文档系统梳理了C语言的特点与程序基本结构详解库函数printf与scanf的功能及使用格式并附常用转义字符、格式符对照表同时区分主函数、用户自定义函数与库函数三类函数说明从编辑、编译、连接到执行的完整开发过程配有Hello输出、两数求和、求最大值等例题与运行结果。该资源已有894人学习下载适合作为C语言入门自学材料或课堂复习提纲帮助读者快速建立知识框架并动手验证示例代码。1. 从一份五讲讲稿说起它到底覆盖了什么、漏了什么很多人把《C语言基础知识.pdf》当成扫一遍语法的读物翻完第一讲就合上然后在真正写代码时卡在scanf(%d,%d, a, b)为什么输入3 5就是不对。这份五讲的讲稿把 C 的语法骨架、输入输出格式控制、数据类型与转换、选择与循环结构、运算符优先级以及编辑—编译—连接—运行的完整流程都压进去了密度不低但例子带着明显的 Turbo C 时代印记main()不带返回类型、#include stdio.h被说成可以缺省、目标文件和可执行文件默认是.obj和.exe。它适合三类人零基础想系统过一遍语法的新手、要照方抓药出上机题的老师、准备计算机二级或嵌入式笔试的考生——scanf 的地址表列、printf 的宽度说明、unsigned 的取值范围这些细节恰好是考题反复出现的地方。后面几章按它的五讲顺序拆开重点补两件事在现代编译器上怎么把老例子跑通以及每一处语法背后最容易踩的坑在哪。2. printf 与 scanf 的格式控制从转义字符到地址表列输入输出是这份讲稿里例子最密集的部分也是初学者第一个真正的坎。printf和scanf共用一套格式控制串的写法但语义完全相反一个是从内存往外送一个是把键盘输入往里塞所以格式符能对上号只是及格线宽度、对齐、分隔符、缓冲区残留才是失分点。2.1 格式控制串的三层结构普通字符、转义字符、格式说明printf(...)里的双引号内容由三部分混排而成照原样输出的普通字符、以反斜杠开头的转义字符、以及以%开头的数据格式说明。转义字符这一块讲稿列了完整表格先把常用的几个记住转义字符作用\n回车换行光标移到下一行行首\r回车不换行光标回到本行行首\t横向跳格跳到下一个 8 的倍数位置\b退一格光标左移一位\\输出一个反斜杠\\输出单引号、双引号\ddd三位八进制数对应的 ASCII 字符\xhh两位十六进制数对应的 ASCII 字符光看表没用得打出来看到光标怎么动#include stdio.h int main(void) { /* 标尺行数 \t 跳了几格、\b 退了几位都靠它 */ printf(123456789012345678901234567890\n); printf(123\t456\n); /* 走到第 4 位遇到 \t跳到第 9 位再写 456 */ printf(12345\b123\r9\n); /* 退一格覆盖 5再回行首用 9 覆盖 1 */ return 0; }第二行输出的是123加 5 个空格再加456第三行先得到1234123\r把光标拉回行首再写一个9覆盖掉最前面的1最终是9234123。理解\r只动光标不换行是做终端进度条和覆盖式刷新的基础。2.2 宽度说明%和格式符中间那两个位置数据格式说明的完整形式是%宽度说明格式符。宽度为正数时右对齐、左边补空格为负数时左对齐、右边补空格实际位数超过宽度则按实际位数输出宽度说明被忽略。格式符本身决定了数据的解释方式格式符输出形式d带符号十进制整数正数不输出正号oxu无符号八进制、十六进制、十进制cs单个字符、字符串f小数形式默认 6 位小数e标准指数形式小数部分默认 6 位#include stdio.h int main(void) { int a 12; double b 3.456; /* %4d总宽 4 右对齐%-6.2f总宽 6、左对齐、保留 2 位小数 */ printf(a%4d,b%-6.2f,c%c,d%s\n, a, b, A, hello); /* %2d 的宽度 2 小于 300 的实际位数 3按实际输出 */ printf(x%d,y%-6.2f,z%2d\n, 2, 8.999, 300); return 0; }第一行里3.456按%-6.2f先四舍五入成3.46占 4 位右侧补两个空格第二行的z%2d输出300而不是截断。宽度说明只影响排版的观感不改变数值。2.3 scanf 的地址表列与输入分隔符的匹配规则scanf(格式控制, 地址表列)里地址表列由若干个地址组成取值范围是变量本身用取地址数组名本身就是地址所以不加。格式控制里除了格式符之外的字符必须由用户在键盘上原样敲出来这是最容易被忽略的一条规则#include stdio.h int main(void) { int a, b; /* 格式串里有一个逗号输入时也必须敲这个逗号 */ if (scanf(%d,%d, a, b) ! 2) { printf(input error\n); return 1; } printf(%d %d %d\n, a, b, a b); return 0; }格式串中是%d,%d就只能输入3,5如果敲成3 5第一个%d读到 3 后期待一个逗号却遇到空格匹配失败直接返回b保持未定义值。反过来格式串写成%d%d时没有其它字符间隔输入3 5、3回车5、3Tab5都能正确匹配。scanf的返回值是成功匹配并赋值的项数拿它做输入校验比事后检查变量值可靠得多。字符型还有一层缓冲区问题前一句scanf留下的回车符会停在下一次%c前面。#include stdio.h int main(void) { int n; char ch; scanf(%d, n); scanf( %c, ch); /* 格式串开头的空格会跳过所有空白字符 */ printf(n%d ch%c\n, n, ch); return 0; }提示scanf的格式串里永远不要在%c前省略那个空格除非你确实想读到回车符本身。把这三节的内容拼起来其实是一份很实用的自查清单输出对不上就先数宽度说明的位置输入卡住就先看格式串里有没有额外字符字符读错就先看缓冲区里是不是躺着一个回车。3. 基本数据类型、修饰符与隐式类型转换第二讲把数据类型、存储空间、修饰符、类型转换串在一起讲逻辑是通的先知道每种类型占几个字节、能装多大的数才能判断一次赋值会不会溢出、一次除法会不会丢小数。问题在于讲稿给的是 16 位平台下的字节数直接套到现在的机器上会算错。3.1 用 sizeof 把字节账实测一遍讲稿的表里写int占 2 字节、范围 -32768 到 32767那是 Turbo C 的 16 位模型。现在 64 位 Linux 和 Windows 上int普遍是 4 字节long在 64 位 Linux 上是 8 字节、在 Windows 上仍是 4 字节。别背表跑一遍#include stdio.h int main(void) { /* %zu 是 size_t 的正确格式符用 %d 打 sizeof 在 64 位下会出问题 */ printf(char%zu short%zu int%zu long%zu\n, sizeof(char), sizeof(short), sizeof(int), sizeof(long)); printf(float%zu double%zu long double%zu\n, sizeof(float), sizeof(double), sizeof(long double)); return 0; }用gcc -m64和gcc -m32各编一次对比就能看到 32 位和 64 位下long的差别。实践中真正要记住的是三条char恒为 1 字节short至少 2 字节long至少 4 字节跨平台传二进制数据时不要用long要用int32_t、int64_t这类固定宽度类型。3.2 long 与 unsigned 修饰符改变了什么类型修饰符的作用是扩大基本类型的使用范围。long把存储长度加长unsigned则改变最高位的解释方式——不再当符号位而是并入数值部分类型典型存储典型取值范围char1 字节-128 到 127unsigned char1 字节0 到 255int2 字节16 位平台-32768 到 32767unsigned int2 字节16 位平台0 到 65535long4 字节讲稿环境-2147483648 到 2147483647float4 字节有效位 6 到 7 位double8 字节有效位 15 到 16 位无符号数超出上限会回绕有符号数超出上限按标准属于未定义行为#include stdio.h int main(void) { unsigned char u 255; signed char s 127; u u 1; /* 无符号回绕2551 变成 0这是标准定义好的行为 */ s s 1; /* 有符号溢出实际机器上按补码变成 -128但不能依赖 */ printf(u%u, s%d\n, u, s); return 0; }无符号回绕在做位运算、校验和、哈希时是常用特性写循环边界时却是灾难for (unsigned i n; i 0; i--)永远不会结束因为无符号数不可能小于 0。3.3 自动转换与强制转换整数除法丢小数的修法讲稿给的自动转换规则是参与运算的数据中有float或double就统一转成double否则有long就转long其余按int处理。实际标准里还多一步整型提升但按这个顺序判断绝大多数情况够用了。真正要动手改的是整数除法#include stdio.h int main(void) { int a 3, b 2; float c 2.5f; double r1 a / b; /* 先做整数除法得 1再赋给 double结果是 1.0 */ double r2 (float)a / b; /* 先把 a 提升为 float 再除结果是 1.5 */ printf(r1%.1f r2%.1f\n, r1, r2); printf((int)c%d\n, (int)c); /* 截断取整2.5 得到 2不是四舍五入 */ printf((int)2.5%%3%d\n, (int)2.5 % 3); /* %% 输出一个百分号2%3 得 2 */ return 0; }强制类型转换的形式是(类型)表达式讲稿点名了两个主要用途一是满足运算符对类型的硬性要求%两侧必须是整型所以要先(int)再取余二是防止整数除法丢小数把被除数或除数任意一个转成浮点即可。反过来把浮点赋给整型变量时是直接砍掉小数部分不是四舍五入这点在做金额计算时尤其要注意。4. 控制结构与运算符优先级把易错写法逐个过一遍第三、四、五讲分别讲选择结构、循环结构、运算符与表达式三条线在真实代码里是缠在一起的。else和最近的if配对、switch漏break会穿透、循环里break只跳一层、自增运算符前后置在表达式里的差异这几处是新手代码出错频率最高的地方。4.1 if 的三种形态与 else 配对规则if提供两个分支的选择基本形态有三种单分支、if-else双分支、if-else if-else多分支。嵌套时 C 编译系统处理配对的原则是else总是与同一语法层次中离它最近的、尚未配对的if结合。这条规则光看文字容易误判跑一段就知道#include stdio.h int main(void) { int a 1, b 2, c 3; if (a b) if (b c) printf(abc\n); else printf(bc\n); /* 这个 else 属于内层 if不是外层的 */ if (a b) { if (b c) printf(abc\n); } else { printf(ab\n); /* 加大括号后else 才属于外层 if */ } return 0; }第一段里a b不成立整块被跳过什么也不输出第二段因为显式加了花括号输出了ab。结论很简单只要嵌套超过一层就一律补花括号别靠缩进表达意图。4.2 switch 的穿透与 break 的作用switch解决多分支选择表达式必须是整型或字符型case后面必须跟着常量。执行过程是先算出表达式的值逐个和case后面的常量比较相等就从那里开始往下执行遇到break跳出。省略break会继续执行后面的语句这叫穿透#include stdio.h int main(void) { int choice; if (scanf(%d, choice) ! 1) return 1; switch (choice) { case 1: printf(请输入\n); break; case 2: printf(请输入查找学生学号\n); break; case 3: printf(正在输出\n); break; case 0: printf(谢谢使用\n); break; default: printf(输入错误\n); break; } return 0; }穿透并不总是 bug多个取值共用同一段处理逻辑时反而更清爽switch (grade) { case A: case B: printf(良好以上\n); break; /* A 和 B 共用同一分支 */ case C: printf(及格\n); break; default: printf(不及格\n); break; }注意case后面只能是常量表达式不能写变量default可以放在任意位置但习惯上放最后。4.3 三种循环的选型与 break、continue 的边界三种循环的执行顺序不同导致一次都不执行和至少执行一次的区别语句判断时机最少执行次数while先判断条件成立才执行循环体0 次do-while先执行循环体再判断条件1 次for先执行表达式 1再判断条件0 次do-while后面那个分号不能省这是编译报错里很常见的一处。break和continue的区别也必须分清continue只结束本次循环跳过循环体中它后面的语句直接进入下一次条件判定break直接终止整个循环。#include stdio.h int main(void) { int i, sum 0; for (i 1; i 10; i) { if (i 3) continue; /* 跳过 i3 这一轮sum 不加 3 */ if (i 8) break; /* i 到 8 时整个循环结束 */ sum i; } printf(sum%d\n, sum); /* 124567 25 */ return 0; }嵌套循环里break只能跳出一层想跳出多层要么用标志变量加条件判断要么把逻辑抽成函数用returngoto虽然能直接跳到外层标号但会破坏结构讲稿里也明确建议避免。4.4 优先级、结合性与几个反直觉表达式优先级决定谁先算结合性决定同级运算从左还是从右走两者合起来才能确定一个表达式的求值顺序。常用层级从高到低是括号、单目!~--和强制类型转换、算术、关系、相等、逻辑与、逻辑或、条件、赋值、逗号。其中两个容易记错的点关系运算符里优先级高于和!赋值运算符的结合性是从右往左。看几个例子#include stdio.h int main(void) { int a 3, b 2, c 1; int r, s, t, i 5, j; r a b c; /* (ab) 得 1再算 1c 得 0 */ s a b c; /* 从右往左c 赋给 b结果再赋给 a三者都是 1 */ t (a 10, b 20, a b); /* 逗号表达式取最后一个表达式的值t30 */ j i; /* j 拿到 5i 变成 6 */ j i; /* i 先变成 7j 拿到 7 */ printf(r%d s%d t%d j%d\n, r, s, t, j); return 0; }a b c这种连写几乎永远是笔误正确写法是a b b c。自增运算符的前置和后置只有在参与其它运算时才有区别单独成句i;和i;效果完全一样。注意同一个表达式里对同一个变量多次自增比如i i属于未定义行为不同编译器给出的结果可以不一样这种代码不要写。5. 从 .c 到可执行文件编译链接四阶段与报错定位讲稿把开发过程拆成编辑、编译、连接、运行四步对应的文件扩展名是.c源程序、.obj目标文件、.exe可执行文件。换成 gcc 之后概念没变只是文件名和命令不同而且能拆开看每一步的中间产物gcc -E hello.c -o hello.i # 预处理展开 #include 和宏得到预处理后的源文件 gcc -S hello.c -o hello.s # 编译把 C 翻译成汇编 gcc -c hello.c -o hello.o # 汇编把汇编翻译成目标文件Linux 下是 .o 不是 .obj gcc hello.o -o hello # 连接和 C 库函数一起打包成可执行文件 ./hello日常一行就够gcc -Wall -Wextra -g -stdc11 -o hello hello.c。-Wall打开常用警告-Wextra再补一批-g生成调试信息供 gdb 用-stdc11锁定语言标准避免不同编译器行为漂移。5.1 老教材写法在新编译器上的三处必然报错一是main()不写返回类型。C99 起不再允许隐式int必须写成int main(void)并在末尾return 0;。二是省掉#include stdio.hTurbo C 2.0 允许现在会得到implicit declaration of function printf。三是用了getch()、clrscr()这类conio.h里的函数Linux 和 macOS 上没有这个头文件换成getchar()。#include stdio.h int main(void) { int a, b, sum; a 123; b 456; sum a b; printf(sum is %d\n, sum); return 0; /* main 声明为 int就必须给一个返回值 */ }5.2 三类报错怎么读语法和类型问题在编译期就会被拦住gcc 的警告信息里已经给出了位置和期望类型照着改就行$ gcc -Wall wrong.c -o wrong wrong.c:5:12: warning: format %d expects argument of type int, but argument 2 has type double [-Wformat]undefined reference to sqrt出现在连接期说明函数声明在了头文件里但实现没链进来加-lm即可gcc -Wall -o calc calc.c -lm运行期崩溃最常见的是段错误来源集中在三处scanf漏写、数组下标越界、指针未初始化就解引用。定位手段是把-g加上用 gdb 单步gcc -g -o calc calc.c gdb ./calc (gdb) break main (gdb) run (gdb) next (gdb) print anext逐行执行print 变量名随时看值崩在哪一行一目了然。这套加-g、下断点、逐行走、看变量的动作比在代码里到处插printf效率高得多也是读这份讲稿里运行结果有误就重新编辑那句话时最该补上的具体做法。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号