前言:
学习笔记,参考各路大佬所记录,若有侵犯,请告知删改(我要30天学完!)
参考:二十万字带你入门C语言-史上最强C语言教程(汇总篇)-优快云博客
C 语言教程 | 菜鸟教程
C语言程序设计从入门到进阶【比特鹏哥c语言2024完整版视频教程】(c语言基础入门c语言软件安装C语言指针c语言考研C语言专升本C语言期末计算机二级C语言c语言_哔哩哔哩_bilibili
1.什么是语句(--------Day4---------)
C语言中, 一般一个分号就是一条语句 ,语句可分为以下五类:1. 表达式语句2. 函数调用语句3. 控制语句(分支与循环语句归属于此)4. 复合语句5. 空语句控制语句 用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成, C 语 言有九种控制语句。可分成以下三类:1. 条件判断语句也叫分支语句:if语句、switch语句;2. 循环执行语句:do while语句、while语句、for语句;3. 转向语句:break语句、goto语句、continue语句、return语句。
C语言是结构化的程序设计语言,包括 顺序结构、选择结构、循环结构。
2.分支语句(选择结构-只选择一个)
人生处处充满了选择,每一个选择都是一次道路上的分支,既有但分支又有多分支错综复杂,路在脚下任你踏足,而你为什么这么选,是基于什么条件选择的,选择后又会产生什么样的结果,都是值得我们深思的。
2.1 if语句
语句结构1
if (条件判断表达式语句1)
{
语句1; //如果表达式为真,则执行语句1,否则跳过语句1不执行语句... //若只执行单挑语句可以省略{}大括号(else也一样)
}
条件判断表达式语句使用
语句结构2
if (条件判断表达式语句1)
{
语句1; //如果表达式为真,则执行语句1,否则跳过语句1不执行...
}
else // 也就是不满足上述条件,执行语句2
{
语句2;... ////若只执行单挑语句可以省略{}大括号(else也一样)
}
语句结构3
if (条件判断表达式语句1) //如果表达式1为真,则执行语句1, 并且不再判断后续的else //(if)语句, 否则跳过语句1不执行 ,判断下一个else if语句
{
语句1;...
}
else if (条件判断表达式语句2) //如果表达式2为真,则执行语句2, 并且不再判断后续的//else (if)语句, 否则跳过语句2不执行 ,判断下一个else if语句{
语句2;
...}
...... //可以接多个else if
else //若前面的表达式语句都为假0,则执行语句n
{
语句n;
...
}
所有的if结构中若执行语句只有一条,可以省略{}大括号,if else的分支语句只会选择一条执行语句执行,多个if else 嵌套串联时,else会选择前面最近的一个if,而不是看格式对齐,养成良好的{}代码习惯
练习
#include <stdio.h>
添加一个循环条件即可
2.2 switch语句
格式:switch ( 整型表达式 ){case 整形常量表达式1 ://字符由ASCII码编译的整型关系运算符结果是非0即1的整型语句1 ;case 整形常量表达式2 :语句2 ;...default:
语句n;break;}
说明 :整型表达式的数值与整形常量表达式数值进行对比,若相等,则执行相等项语句及其后所有语句,否则跳出语句。多语句也可不使用{}大括号
break关键字
在switch语句中,我们没办法直接实现分支,搭配break使用才能实现真正的分支。break语句 的实际效果是把语句列表划分为不同的分支部分,若满足则直接跳出switch而不接着执行后续语句。
default子句
如果表达的值与所有的case 标签的值都不匹配怎么办?其实也没什么,结构就是所有的语句都被跳过而已。 程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?你可以在语句列表中增加一条default 子句,把下面的标签default :写在任何一个 case 标签可以出现的位置。 当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个 switch语句中只能出现一条default 子句。 但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case 标签一样执行default子句。编程好习惯 : 在每个 switch 语句中都放一条 default 子句是个好习惯,甚至可以在后边再加一个 break 。
练习
2.判断输出结果

答案:5 3(注意break只跳出当前一级的选择或者循环,而不是所有)
3.循环语句
3.1 While语句(--------Day5---------)
3.1.1 语法
首先记住While 最基本的使用方式
while ( 表达式语句 ) // 表达式语句非0即1{循环语句 ; //满足条件就执行}
3.1.2 While语句中的“跳出”(continue和break)
continue 在while循环中的作用:continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的条件判断。break 在while循环中的作用:只要遇到break,就停止后期的所有的循环,直接终止循环, while中的break是用于永久终止循环。
通过代码理解【本次】和【所有】的区别

运行结果:

3.1.3 练习
(1)输出什么
2 3 4 6 7 8 9 10 11
注意 i ++;位置对代码的影响
如何打印字符呢??? %c即可
while循环数数??? 不可能的,利用sizeof关键字计算数组长度

依旧是考printf输出格式和sanf输入格式

(4)学生基本信息输入输出_牛客题霸_牛客网
%.2f是直接删除超过两位的小数,如何四舍五入呢???

3.2 for循环(--------Day6---------)
3.2.1 语法
for ( 表达式 1 ; 表达式 2 ; 表达式 3 ){循环语句;}表达式 1表达式 1 为 初始化部分 ,用于初始化循环变量的。(只执行一次)表达式 2表达式 2 为 条件判断部分 ,用于判断循环时候终止。表达式 3表达式 3 为 调整部分 ,用于循环条件的调整。其执行逻辑是:先初始化表达式1 (只执行一次) ,判断表达式2,若成立则运行循环语句并执行表达式3,再次进行判断,重复操作,直到不满足,跳出循环。
3.2.2 for循环的“跳出”
与while语句中的一致(但略有区别)

这里初始化i = 1,与while中不一样是因为for循环时先执行后++,而之前while代码将i++;写在了执行语句的前面,会先加一次,是先++后执行。 因为while循环中的contiue是跳到下一次while中,但是while中没有调整i的数值,而for循环也是跳到这一次for循环中的i++部分再进行下一次判断
3.2.3 for循环的变种
(1)可省略条件
全部省略进入死循环

(2)嵌套

可以尝试做一个9*9乘法口诀表
(3)多个变量

(4)只省略初始化部分

只打印了10个为啥不是10*10个呢???
当i = 0 时,内层循环开始执行,j从0递增到9,打印10次“hehe”,内层循环结束后,j的值为10,i变动时,内层条件不再满足。
3.2.4 练习
1. 请问循环要循环多少次?
#include <stdio.h>int main (){int i = 0 ;int k = 0 ;for ( i = 0 , k = 0 ; k = 0 ; i ++ , k ++ )k ++ ;return 0 ;}
答:0次,因为k=0虽然是赋值语句,但是它的结果是0,判断为假,不执行。
3.3 do...while()循环
3.3.1 语法
do{循环语句;}while(表达式);执行逻辑:先do循环语句后判断(易错)
循环至少执行一次的特性
3.3.2 do while循环中的“跳”(break和continue)
和上面两个循环一样

3.4 练习
1. 计算 n 的阶乘
2. 计算 1!+2!+3!+……+10!
3. 在一个有序数组中查找具体的某个数字 n 。(讲解二分查找)
4. 编写代码,演示多个字符从两端移动,向中间汇聚。
5. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则 提示登录成,如果三次均输入错误,则退出程序
4. goto语句
4.1 介绍
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号,goto 语句是一种无条件跳转指令,可以让程序控制流直接跳转到函数内的指定标签位置。虽然 goto 语句在某些场景下非常有用,但过度使用会导致代码结构混乱(即所谓的 "spaghetti code"),因此需要谨慎使用。
语法:
goto label; // 跳转到标签位置
...
label: // 标签声明(标识符后加冒号)
{
statement; // 标签后的语句
}
- 标签:是一个标识符(遵循变量命名规则),后跟一个冒号
:,必须与goto位于同一函数内。- 执行流程:当执行到
goto label;时,程序会立即跳转到label:处继续执行。
(1) 跳出多层嵌套循环
当需要从深层嵌套的循环中立即退出时,goto 比多个 break 语句更简洁:
for (...) {
for (...) {
if (condition)
goto exit_loop; // 直接跳出两层循环
}
}
exit_loop:
// 继续执行后续代码
(2) 错误处理
在函数中统一处理错误情况,避免重复代码:
int func() {
// 分配资源
int* ptr = malloc(sizeof(int));
if (!ptr)
goto error;
// 执行操作...
if (error_condition1)
goto error;
// 更多操作...
if (error_condition2)
goto error;
// 成功返回
return 0;
error:
// 统一释放资源
free(ptr);
return -1;
}
(3) 实现状态机
在简单状态机中控制状态转换:
int state = 0;
start:
switch (state) {
case 0:
// 状态0处理
state = 1;
goto start;
case 1:
// 状态1处理
state = 2;
goto start;
case 2:
// 状态2处理
break;
}
4.2 禁用场景
- 跨函数跳转:
goto不能跳转到其他函数内的标签。 - 破坏结构化编程:避免在复杂代码中随意使用
goto,例如:// 糟糕的示例:代码逻辑混乱 goto step2; step1: printf("Step 1\n"); goto step3; step2: printf("Step 2\n"); goto step1; step3: printf("Step 3\n"); - 跳过变量初始化:
goto不能跳过变量初始化语句,否则会导致编译错误:goto skip; int x = 10; // 不能跳过初始化
4.3 案例
关机程序
若打不了中文不知道,开cmd可以,可以尝试进行如下操作

补充
getchar()与putchar()
getchar()和putchar()是 C 语言标准库中用于字符输入输出的函数,属于stdio.h头文件。
getchar()用于从标准输入(通常是键盘)读取单个字符,返回类型为int(以处理 EOF 标志)。
putchar()用于向标准输出(通常是屏幕)写入单个字符,参数类型为int,但实际只处理低 8 位(即一个字符)
与 scanf() 和 printf() 的区别
(1)输入输出单位
scanf()和printf()支持格式化输入输出,可以处理多种数据类型(如%d,%f,%s)。getchar()和putchar()仅处理单个字符,效率更高,适合简单字符操作。
(2)缓冲区的处理方式
scanf()会跳过空白字符(如空格、换行),直到读取到有效数据,可能残留换行符在缓冲区。getchar()直接读取输入缓冲区的下一个字符(包括换行符\n),不会跳过任何字符。
所以有:while ((c = getchar()) != '\n' && c != EOF); // 清空缓冲区
(3)返回值
scanf()返回成功匹配的参数个数,失败返回EOF。getchar()直接返回读取的字符(ASCII 值),失败或遇到文件结束返回EOF。printf()返回输出的字符数。putchar()返回写入的字符,失败返回EOF。
(4)对比
getchar()比scanf("%c")更高效,因为后者需要解析格式字符串。putchar()比printf("%c")更直接,减少格式化开销。

输入缓冲区
输入缓冲区是计算机系统中用于临时存储输入数据的内存区域,通常在程序读取输入前暂存数据。其作用包括协调输入设备与处理速度的差异、减少频繁I/O操作的开销等。常见于键盘输入、文件读取、网络通信等场景。
输入缓冲区的工作原理
- 数据暂存:输入设备(如键盘)将数据先写入缓冲区,程序按需从缓冲区读取,避免直接访问硬件导致的延迟。
- 行缓冲与全缓冲
- 行缓冲:遇到换行符或缓冲区满时触发读取(如终端输入)。
- 全缓冲:缓冲区填满后才触发读取(如文件操作)。
清除输入缓冲区的方法
在C中,输入函数(如scanf)可能遗留换行符或无效数据,需手动清除缓冲区:
#include <stdio.h>
void clear_input_buffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF); // 逐字符读取直至换行或文件末尾
}
sizeof关键字与strlen()函数

总结:
sizeof是关键字,计算单位是字节,会计算字符串所有长度(包括'\0'),一般习惯/sizeof(数组(0))将单位化为1用于计算数组长度,不过字符char占一个字节可不除。
strlen()是函数,只计算到'\0'(不包含)的长度,单位为1,若没有则直到找到为止,所以arr4和arr6输出为随机值
strcmp函数
字符串比较大小函数,它会按照字典序对两个字符串进行比较,区分大小写。
- 函数原型:
int strcmp(const char *s1, const char *s2); - 返回值:
- 若返回值小于 0,表示
s1小于s2 - 若返回值等于 0,表示
s1等于s2 - 若返回值大于 0,表示
s1大于s2
- 若返回值小于 0,表示

数组传参
数组传参实际上传入的是数组的首地址,即是地址则为指针变量

system函数
system函数是标准库提供的一个用于执行操作系统命令的接口。它允许程序在运行时调用外部命令,实现与操作系统的交互,system函数的核心作用是在程序中执行操作系统的 shell 命令也就是运行cmd.exe。
函数原型与头文件
#include <stdlib.h>
int system(const char *command);
- 参数:
command:指向包含系统命令的字符串指针(如"shutdown -s -t 60")。- 若为
NULL,则检查系统命令处理器是否存在。
- 返回值:
- 成功:返回命令执行后的退出状态码(由操作系统决定)。
- 失败:返回
-1(例如命令处理器无法启动)。 - 特殊情况:若
command为NULL且系统支持命令处理器,则返回非零值。
Windows关机
shoutdown是 Windows 系统中用于关机、重启、注销等操作的命令,通过添加不同的参数,可精确地指定执行的操作和时间。WIN + R 键输入cmd控制,以下是其常见参数及用法介绍:
/s:用于关闭计算机。例如shutdown /s,会弹出自动关机对话框,默认 30 秒后关机;若使用shutdown /s /t 0,则会立即关闭本地计算机。/r:用于重启计算机。如shutdown /r /t 0,表示立即重启计算机。/a:用于取消正在进行的关机或重启操作。但需注意,取消命令必须在倒计时内执行,对于立即关机(/t 0)无法取消。/f:强制关闭正在运行的程序。当系统中有未保存的工作或未响应的程序时,默认shutdown会等待程序响应,使用此参数可强制终止所有程序,如shutdown /s /f /t 0。/m \\计算机名:指定远程计算机进行关机或重启操作。例如,shutdown /s /m \\192.168.1.100 /t 0表示远程关闭 IP 地址为 192.168.1.100 的计算机。/t xxx:设置关机或重启前的倒计时时间,单位为秒。例如,shutdown /s /t 60表示 60 秒后自动关机。/c "说明文字":添加关闭原因,最大支持 512 个字符。例如,shutdown /s /m \\192.168.1.100 /t 30 /c "系统维护,稍后重启",会在远程关机时向目标计算机用户显示此说明。/l:注销当前用户。此参数不能与/m或/d参数一起使用。/g:关闭计算机,然后重新启动,并确保所有注册的应用程序都重新启动。/p:在不等待超时或警告的情况下关闭本地计算机,常与/d和/fflags 一起使用。/h:使计算机进入休眠状态,可与/f参数一起使用。/hybrid:关闭计算机并为快速启动做准备,必须与/s参数一起使用。/e:用于查看计算机意外关闭的原因。/o:将计算机引导至高级启动菜单选项并重新启动。eg:
shutdown -s -t 60该命令用于设置计算机在 60 秒后自动关机。其中,-s参数表示关闭本地计算机,-t参数用于设置关机倒计时,单位为秒,这里指定为 60 秒。
shutdown -a这个命令的作用是取消当前已经设置好的关机操作。如果你之前使用shutdown -s -t等命令设置了定时关机,但后来又想取消该关机计划,那么只需在命令提示符或运行窗口中输入shutdown -a并回车,就可以取消正在等待执行的关机任务,让计算机恢复正常运行状态,不会再按照之前设置的时间关机。
练习(上一节)
第一题 C
第二题 static有无的区别 8,10,12,14,16
第三题 B, A应当为1字节,与类型无关
转义字符
若float不行改成double,精度更高,例外0.0默认为double类型,0.0f则为float
初始化时,最好赋值,否者容易随意赋值,int a = 0; float b = 0.0f; double c = 0.0;
注意整数除以整数还是整数,整数除以整数.0即是浮点数运算,加上.0他好你也好
大作业:猜数字游戏
知识预知
(1)时间戳获取
time 函数:获取当前系统时间(从1970 年 1 月 1 日 00:00:00 UTC到现在的秒数),也称为时间戳(Unix Timestamp)
-
原型
#include <time.h>
time_t time(time_t *timer);
- 参数:
timer:指向time_t类型的指针,用于存储时间值。若为NULL,则直接返回时间值。
- 返回值:
- 成功:返回当前时间戳(
time_t类型,通常是long int)。 - 失败:返回
(time_t)-1(极少发生)。
- 成功:返回当前时间戳(
time_t current_time;
current_time = time(NULL); // 直接获取时间戳
// 或
time(¤t_time); // 通过指针存储时间戳
printf("当前时间戳: %ld\n", (long)current_time);
(2)获取随机值
srand 函数:初始化随机数种子
srand()设置随机数生成器的种子值(seed)。若不调用srand,默认种子为1,导致每次运行程序时rand()生成相同的随机序列。只调用一次。
-
原型
#include <stdlib.h>
void srand(unsigned int seed);
- 参数:
seed:无符号整数,作为随机数生成的起始值。
rand 函数:生成伪随机数
功能
生成伪随机整数,范围为0到RAND_MAX(标准库定义的常量,至少为32767)。
原型
#include <stdlib.h>
int rand(void);
- 返回值:
- 生成的伪随机整数(
int类型)。
- 生成的伪随机整数(
示例
// 生成0-99之间的随机整数
int random_num = rand() % 100;
// 生成100-200之间的随机整数
int min = 100, max = 200;
int random_range = min + (rand() % (max - min + 1));
// 生成0.0-1.0之间的随机浮点数
double random_float = (double)rand() / RAND_MAX;
三者协作流程
- 获取时间戳:
time(NULL)。 - 设置随机种子:
srand(time(NULL))。 - 生成随机数:
rand()。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// 初始化随机种子
srand((unsigned int)time(NULL));
// 生成10个随机数
for (int i = 0; i < 10; i++) {
printf("随机数 %d: %d\n", i+1, rand() % 100);
}
return 0;
}
猜数字游戏实例
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 打印游戏菜单
void menu()
{
printf("**********************************\n");
printf("*********** 1.play **********\n");
printf("*********** 0.exit **********\n");
printf("**********************************\n");
}
// 猜数字游戏的核心逻辑
// RAND_MAX是标准库定义的常量,表示rand函数能返回的最大随机数
void game()
{
// 生成1-100之间的随机整数
int random_num = rand() % 100 + 1;
int input = 0;
printf("游戏开始,请猜一个1-100之间的数字!\n");
while (1)
{
printf("请输入猜的数字>:");
scanf("%d", &input);
if (input > random_num)
{
printf("猜大了,再小一点!\n");
}
else if (input < random_num)
{
printf("猜小了,再大一点!\n");
}
else
{
printf("恭喜你,猜对了!正确答案就是%d\n", random_num);
break; // 猜对后跳出循环结束游戏
}
}
}
int main()
{
int input = 0;
// 用当前时间作为随机数种子
// 确保每次运行程序时生成不同的随机序列
srand((unsigned)time(NULL));
// 主循环:使用do-while确保至少执行一次菜单选择
do
{
menu(); // 显示菜单
printf("请选择>:");
scanf("%d", &input);
switch (input)
{
case 1:
game(); // 开始游戏
break;
case 0:
printf("游戏已退出,欢迎下次再来!\n");
break;
default:
printf("选择错误,请输入1或0!\n");
break;
}
} while (input); // 当用户输入0时退出循环
return 0;
}
结语
代码规范是自己的习惯养成的,多写多敲,多看多想,多读多学













756

被折叠的 条评论
为什么被折叠?



