ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

2026九月重新学习C语言记录

2026九月重新学习C语言记录 2026年9月29日前的c语言学习笔记翁恺版5.3.3前的内容第一章计算机与编程语言基础1.1.1 计算机与编程语言计算机怎么做事情计算机本身只会做极其简单的机械动作加法、存取数据、跳转它无法理解人类的意图。它按照人类预先写好的**指令序列程序**一步步执行。编程语言是什么人和计算机沟通的桥梁。人类用接近自然语言的“高级语言”如C语言写代码再通过编译器翻译成计算机能直接听懂的“机器语言”0和1。1.1.2 计算机的思维方式核心思维重复与枚举。人类觉得重复枯燥但计算机最擅长的就是极其精准、不知疲倦地重复。所以编程时只要发现规律就要用循环去解决而不是手写几十遍。1.2.1 为什么是C在工业界和嵌入式领域如STM32、Linux内核C语言几乎是唯一选择。因为它高效、贴近底层硬件能直接操作内存和寄存器且代码体积小。1.2.2 简单历史C语言诞生于1972年贝尔实验室由Dennis Ritchie设计。主要版本有C89/C90、C99你现在学的大多是C99标准。它的设计哲学是“信任程序员”所以赋予了很多底层的控制权但也容易出错。1.2.3 编程软件推荐的DevC是一个轻量级IDE集成开发环境它包含了编辑器写代码、编译器转成机器码和调试器。对于初学者不需要复杂的配置直接新建“源代码”即可。1.3.1 1.3.2 第一个C程序程序框架#includestdio.h// 预处理指令引入标准输入输出库intmain(){// 主函数程序的唯一入口printf(Hello World!\n);// 输出函数\n是换行符return0;// 返回0表示程序正常结束}易错点所有标点必须是英文半角。漏掉分号;是最常见的报错。如果报错看编译器提示的行号通常错误就在那附近。1.3.3 做点计算可以直接在printf里写表达式如printf(%d, 1 2);。%d是占位符告诉程序这里要输出一个整数。1.3.4 MacOSX命令行略在Mac上可以用gcc或clang命令编译本总结以DevC为主。—第二章变量与运算2.1.2 变量定义变量是内存中的一块空间用于存数据。定义格式类型 变量名;如int price;。变量名规则只能由字母、数字、下划线组成不能以数字开头不能是C语言关键字如int,if。建议见名知义。2.1.3 2.1.4 变量赋值、初始化与输入赋值a 10;是把10放进a的空间。初始化int a 10;在定义的同时给初值。输入scanfscanf(%d, a);必须加取地址符否则程序会崩溃内存错误。这是初学者第一大坑易错点scanf中不要加\n如scanf(%d\n, a);会导致卡住不返回。如果输入多个变量可以用空格隔开。2.1.5 常量vs变量常量不变的量。使用const int AMOUNT 100;定义后续试图修改AMOUNT会报错。这是良好的编程习惯防止意外修改。2.1.6 浮点数核心区别整数运算的结果只有整数部分如10/3 3。如果要有小数必须用浮点数10.0/3 3.333...。类型有float单精度4字节和double双精度8字节。在C语言中写小数默认是double如果要用float建议写成10.0f。2.2.1 表达式表达式 数据 运算符。运算符包括 - * / %。% 取余10 % 3 1。%两边的操作数必须是整数不能是浮点数。2.2.2 运算符优先级单目运算符如-、 算术运算符* / %高于 - 关系运算符 逻辑运算符 赋值运算符。赋值运算符的结合性是从右向左a b 10;先执行b 10再执行a b。2.2.3 交换变量经典“三杯水”交换法inttempa;ab;btemp;不用临时变量的异或法面试题aa^b;ba^b;aa^b;注意这种方法仅适用于整数且可读性差实际开发不用。2.2.4 复合赋值和递增递减a 5;等价于a a 5;i和i的区别i是后置加先使用i的值再加1。i是前置加先加1再使用i的值。如果单独占一行两者没有区别。但如果用在表达式里如int b a;b得到的是a自增前的值。2.2.5 PAT系统在线编程练习平台。注意PAT系统的代码要有严格的输入输出格式不要打印“请输入”这样的提示语会判错。—第三章判断3.1.3 0的故事在C语言中0表示假False非0表示真True。if (0)永远不执行if (1)或if (-1)永远执行。3.2.1 3.2.2 做判断与关系运算if (条件) { 语句 }关系运算符判断相等、!不等于、、、、。致命错误把误写成。if (a 1)是赋值不是比较且结果永远为真非0编译器可能只给警告不报错极难查Bug。3.2.3 找零计算器引入了注释//单行注释/* ... */多行注释。注释是写给人看的编译器会忽略。流程图椭圆形表示开始/结束平行四边形表示输入/输出矩形表示处理菱形表示判断。3.2.4 3.2.5 否则的话elseif (条件) { ... } else { ... }if和else后面如果只有一条语句可以省略{}但强烈建议永远加上{}防止产生歧义悬空else问题。3.3.1 3.3.2 嵌套与级联 if-else嵌套在if或else里又写了一个if。注意else总是与最近的、未匹配的if配对这就是为什么建议加{}。级联if ... else if ... else if ... else适合多条件分支。3.3.4 多路分支 switch-caseswitch(表达式){// 表达式必须是整型int, char, enumcase常量1:语句;break;// 必须加否则会“穿透”到下一个case继续执行case常量2:语句;break;default:// 可选处理所有不匹配的情况语句;}注意switch只能判断等于不能判断范围如a 10不行。第四章循环基础4.1.1 4.1.2 while循环格式while (条件) { 循环体 }执行逻辑先判断条件条件为真才执行循环体。条件一旦为假立刻跳出循环。死循环如果条件永远为真循环永不停止如while(1)需要配合break使用。4.1.3 do-while循环格式do{循环体;}while(条件);执行逻辑先执行一次循环体再判断条件。无论条件是否成立循环体至少执行一次。4.2.2 猜数使用rand()函数生成随机数用srand(time(0))设置随机种子。循环结构while (input ! target)如果猜大了提示“大了”猜小了提示“小了”。4.2.3 算平均数输入一串数字直到输入-1结束-1称为哨兵值。需要记录两个变量sum总和和count个数。易错点最后计算平均数时防止count为 0导致除以 0 的错误。4.2.4 整数求逆如输入123输出321。算法intret0;while(x0){intdigitx%10;// 取出个位retret*10digit;// 拼接到结果末尾x/10;// 去掉个位}第五章循环进阶与控制5.1.1 5.1.2 for循环格式for (初始化; 条件; 步进) { 循环体 }执行顺序初始化(仅执行1次) - 判断条件 - 循环体 - 步进 - 判断条件…直到条件为假。选择如果知道循环次数比如从1加到100首选for。如果不知道循环次数比如猜数游戏、算平均数直到输入-1首选while。5.2.1 循环控制 break 和 continuebreak跳出整个循环不再进行后续的循环。continue跳过本次循环剩余的语句直接进入下一次循环的条件判断。STM32关联在while(1)主循环中break常用于退出主循环如看门狗复位前continue常用于跳过某些不符合条件的传感器数据。5.2.2 5.2.3 嵌套的循环与跳出嵌套循环外层循环跑一次内层循环跑完整的一轮。从嵌套循环中跳出break只能跳出它所在的那一层内层循环。如果要从最内层跳出最外层常用的方法是在外层循环加一个标志位flagintflag1;for(inti0;i10flag;i){for(intj0;j10;j){if(条件){flag0;// 设置标志位break;// 跳出内层循环}}}注更极端的做法是用goto语句直接跳到最外层但翁恺老师一般不推荐实际开发中也尽量少用。5.3.1 前n项求和例如求1 1/2 1/3 ... 1/n。易错点1/2在C语言中是整数除法结果是0必须写成1.0/2或者把变量定义为double。5.3.2 整数分解把一个整数如3456按位拆开可以用% 10取个位再/ 10去掉个位配合循环完成。或者用数组配合取余反向存入数组再正向输出。—5.3.3 求最大公约数1. 概念定义最大公约数GCDGreatest Common Divisor指两个或多个整数共有约数中最大的一个。例如12 和 18 的约数分别有 1,2,3,6 和 1,2,3,6,9,18。它们的最大公约数是 6。2. 算法一枚举法穷举法核心思路从 1 开始遍历到两个数中较小的那个数min(a, b)依次判断能否同时整除这两个数不断更新最大公约数。代码示例inta,b;scanf(%d %d,a,b);intmin(ab)?a:b;// 找出较小值intgcd1;for(inti1;imin;i){if(a%i0b%i0){gcdi;// 不断更新最大公约数}}printf(%d\n,gcd);缺点效率较低。如果 a 和 b 都是很大的质数比如 1000000007循环次数极多在嵌入式系统中非常浪费 CPU 资源。3. 算法二辗转相除法欧几里得算法—— 核心重点数学原理两个整数的最大公约数等于其中较小的数和两数相除余数的最大公约数。即gcd(a, b) gcd(b, a % b)。推导演示求 18 和 12 的最大公约数18 % 12 6 余数不为0继续12 % 6 0 余数为0停止此时除数 6就是最大公约数。代码实现迭代法inta,b,t;scanf(%d %d,a,b);while(b!0){ta%b;// 计算余数ab;// 原来的除数变成被除数bt;// 余数变成新的除数}printf(%d\n,a);// 循环结束时a就是最大公约数易错点变量交换的顺序千万不能错。t a % b; a b; b t;必须依次执行如果写反会导致死循环或结果错误。递归实现拓展翁恺后续课程会讲到intgcd(inta,intb){if(b0)returna;returngcd(b,a%b);}递归代码极简但在嵌入式开发中要考虑栈空间迭代法更安全。4. 算法三更相减损术中国古代算法核心思路gcd(a, b) gcd(a - b, b)假设 a b。不断用大数减小数直到两个数相等为止这个相等的数就是最大公约数。代码逻辑while(a!b){if(ab)aa-b;elsebb-a;}printf(%d,a);缺点如果两个数相差悬殊比如 1000000 和 1减法次数太多性能不如辗转相除法。5. 扩展衍生最小公倍数LCM数学公式LCM(a, b) (a * b) / GCD(a, b)致命易错点溢出a * b可能会超出int的范围溢出。正确的写法是先除后乘a / gcd(a, b) * b。STM32关联在STM32的定时器配置中经常需要根据系统时钟频率和目标频率去计算分频系数Prescaler和重装载值ARR。这本质上就是在找最大公约数或进行比例运算如果计算过程溢出了定时器就会配置错误。
返回列表