目录
一、C语言是结构化的程序设计语言
C语言是结构化程序设计语言,主要是因为他支持结构化的编程概念,这些概念有助于我们在编写清晰,易于理解和维护程序。
作为一门结构化的程序语言,它的结构化体现在“结构化控制流”上,这使得C语言具备一系列得控制语句,如`if`、`else`、`switch`、`for`、`while`、`do-while`和`goto`,因为这些语句得存在,使得程序得运行能够按照设计者得意图进行精确控制。
同时这一门编程语言,还具有模块化设计,也就是将一个程序分为多个模块或函数,每一个模块负责一项特定的任务,有助于简化程序得开发,提高代码得实用性和可维护性。
为了能够让程序得编写更加契合现实问题,C语言还提供了丰富的运算符,用于构建复杂的表达式,实现各种计算和处理逻辑。此外,单纯的运算符并不能够实现代码逻辑得融合,这还需要一系列语法,并且在语法方面,C语言得灵活性尤为突出,例如指针操作,这使得C语言在处理底层硬件和内存方面非常强大,即使语法的学习较为复杂,但强大得功能是无与伦比得。
二、顺序语句
顺序语句是程序设计语言中最基本的一种语句,表示程序中得指令是按照他们在源代码中出现的顺序依次执行得。
在顺序结构中,程序从上到下依次执行每一条语句,执行完一条语句后,再执行下一条语句,直到语句结束。
顺序语句得执行流程是直线型的,没有分支和循环,是最简单的程序控制结构,确保了程序的可预测性,因为程序的执行结果完全取决于语句的顺序。
以下是一个简单的包含是顺序语句的代码
在这个程序中,所有的语句都是顺序执行的:
1、定义了三个整型变量a,b,sum
2、将数值5赋给变量a
3、将数值10赋值给变量b
4、计算a和b的和,并将结果赋值给变量sum
5、最后使用printf函数将输出变量sum的值
我们不难发现,程序在执行恶的时候是完全线性的,每条语句执行完毕后,紧接着执行下一条语句,直到程序结束。特点是程序按照代码书写的顺序逐条执行
三、选择语句
什么是选择语句呢?我们不妨来看这样一个例子:假设你正在计划周末的活动,你的计划取决于天气情况。如果天气晴朗,你可能会去郊外野餐;如果下雨,你可能会选择在家里看电影;如果天气多云但不下雨,你可能会去购物中心购物。
如果我想利用C语言来完成这样的情景实现,那么选择语句是最好的一种选择。
在上面的代码编写的过程中,我们使用了strcmp
函数来比较用户输入的天气预报和预设的条件。根据输入的天气情况,程序会输出不同的活动计划。
如果天气是晴朗的,程序建议去郊外野餐;如果下雨,程序建议在家看电影;如果多云,程序建议去购物中心购物;如果输入的天气不符合任何预设条件,程序会建议在家里休息。
这个程序中的执行逻辑是:
- 先检查
weather
变量是否等于字符串"晴朗"。 - 如果是,则执行第一个
printf
语句,建议去郊外野餐。 - 如果不是,程序继续检查是否等于"下雨"。
- 如果是,则执行第二个
printf
语句,建议在家看电影。 - 如果还不是,程序再检查是否等于"多云"。
- 如果是,则执行第三个
printf
语句,建议去购物中心购物。 - 如果以上条件都不满足,则执行
else
块中的printf
语句,建议在家里休息。
看得出来,程序在执行的时候,会评估一个或多个条件表达式,这些表达式通常返回一个布尔值(一般来说返回值为0的时候为假,非0为真),然后根据条件判断的结果,程序会选择一个执行路径。如果条件为真,则执行某个代码块;如果条件为假,则执行另一个代码块或者继续进行下一个条件的判断。被选中的代码块将被执行,执行完毕后,程序继续执行后续的代码。
在上述代码中,我们使用了if、else if和else语句,用来实现语句的选择。问题来了,如果只有这一种选择方式,C语言绝不可能在众多语言中脱颖而出,因此在选择语句中,除了if语句,我们还有其他的选择语句,比如switch与case和break搭配的语句。
这两种语句的设计能够满足我们的绝大数需求,它们的对比如下:
-
条件表达式的类型:
if
语句适用于基于任何布尔表达式的条件判断,可以是比较表达式、逻辑表达式或其他返回布尔值的表达式。switch
语句主要用于基于单个整型或枚举类型值的条件判断,也可以是字符型,因为字符在C语言中实际上是以整数形式存储的。
-
多分支的选择:
if
语句通过if
、else if
和else
的链式结构来处理多个条件,每个条件都需要显式地写出完整的判断表达式。switch
语句通过case
标签来列出多个可能的值,每个值只需要写一次,而且不需要写出比较表达式,这使得代码在处理多个离散值时更加简洁和清晰。
-
条件的比较方式:
if
语句在处理每个else if
时都需要进行一次条件比较,直到找到满足条件的分支。switch
语句在内部使用跳转表或哈希表来实现快速的条件匹配,特别是在处理大量的离散值时,switch
语句的性能通常优于if
语句链。
-
默认分支:
if
语句中的else
分支是可选的,用于处理所有条件都不满足的情况。switch
语句中的default
标签也是可选的,用于处理没有case
匹配的情况。
-
表达式的灵活性:
if
语句允许复杂的条件表达式,包括关系运算符、逻辑运算符和任何返回布尔值的函数调用。switch
语句中的case
标签只能是常量表达式,不能是范围或者复杂的条件。、
以下是一个switch语句的简单演示
#include <stdio.h>
int main() {
int dayOfWeek;
printf("请输入一个整数(1-7)来表示星期几:");
scanf("%d", &dayOfWeek);
switch (dayOfWeek) {
case 1:
printf("星期一\n");
break;
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期日\n");
break;
default:
printf("输入错误,请输入1到7之间的整数。\n");
}
return 0;
}
四、循环语句
如果给你一个这样一个问题,让你打印出1至10000的数字,你会选择怎么打印呢?
是这样?
#include<stdio.h>
int main()
{
print("1");
print("2");
print("3");
print("4");
print("4");
print("5");
...
...
...
print("10000");
return 0;
}
如果是这样的话,这也太繁琐了,有没有什么办法,能够简化这一种步骤,然它变得简洁起来呢。答案是有的,就是循环。,下面我们看一下用循环来编写,对比一下。
#include <stdio.h>
int main() {
for (int i = 1; i <= 10000; i++) {
printf("%d\n", i);
}
return 0;
}
真的就是没有对比就没有伤害,这也相差太多了吧。而且我们还能发现,如果用循环的话,我们似乎能够随意修改这个最大值和最小值,让它具备一定的变化性,就可以满足我们的一些需求。
看到这,这个for函数就进入了我们的眼帘,是的,就是for函数。
在这个for函数中,存在三个值
第一个是int i=1;表示这个循环是针对变量i进行的,并且初始值是1。注意,我们写完这个初始值是需要加上;用来表示语句描述完毕了,但是如果我们有多个初始值,中间就用逗号隔开,以此进行区分。
第二个值是条件,即当针对的对象符合这个条件时,就会执行命令,但是!!!命令语句通常只能跟一条,如果想跟多条,就需要加上花括号了!
第三个值是用来调整对象的,这个i++表示再执行完命令后,就再执行i=i+1的命令,完成调整后继续进行条件判断,如果条件依旧成立,就一直循环执行语句,反之终止语句执行,因为已经不符合执行条件了。
当然了,循环跟选择一样,都不只有一个语句能够实现。在C语言中,还有while循环和do while循环,每一个循环都有自己的特色,我们不妨依旧对同一个情景采用不同的循环编写,尝试找出其中的不同。当我们使用while循环时,
#include <stdio.h>
int main() {
int i = 1; // 初始化循环变量
while (i <= 10000) { // 循环条件
printf("%d\n", i); // 打印当前数字
i++; // 循环变量递增
}
return 0;
}
在这个程序中,我们首先初始化一个整型变量i
为1。然后,我们使用while
循环来检查i
是否小于或等于10000。如果是,程序执行循环体内的代码,打印出当前的数字i
,并且i
的值递增1。这个过程一直重复,直到i
的值增加到101,此时循环条件变为假,while
循环结束,程序继续执行后续的代码。由于在这个例子中,循环后面没有其他代码,程序将在此结束。
当我们使用do while 循环时,
#include <stdio.h>
int main() {
int i = 1; // 初始化循环变量
do {
printf("%d\n", i); // 打印当前数字
i++; // 循环变量递增
} while (i <= 10000); // 循环条件
return 0;
}
在这个程序中,我们首先初始化一个整型变量i
为1。然后,我们使用do-while
循环。do-while
循环的特点是先执行循环体一次,然后检查循环条件。如果条件为真,则继续执行循环体;如果条件为假,则循环结束。
在循环体中,程序打印出当前的数字i
,然后将i
的值递增1。循环条件是检查i
是否小于或等于10000。如果条件为真,循环继续;如果条件为假,循环结束。由于do-while
循环至少会执行一次循环体,即使初始条件为假,循环体也会被执行一次,这在某些情况下是非常有用的特性。
综上所述,每一个循环都有自己的特色:
-
for循环:
- 适用于已知循环次数的情况。
- 结构清晰,将初始化、条件和增量操作集中在一起。
- 可以省略初始化、条件或增量操作,但分号不可省略。
-
while循环:
- 适用于循环次数不确定但有一个明确的终止条件的情况。
- 先判断条件,再执行循环体,可能一次也不执行循环体。
-
do-while循环:
- 至少执行一次循环体,然后再判断条件。
- 适用于无论条件是否成立,循环体至少需要执行一次的情况。
- 条件判断在循环体之后,结构上与前两者不同。
五、continue语句和break语句
在循环执⾏的过程中,如果某些状况发⽣的时候,需要提前终⽌循环,这是⾮常常⻅的现象。在C语言中提供了break和continue两个关键字,就是应用到循环中的。
break的作用是用于永久的终止循环,只要break被执行,就会直接跳出循环,继续往后执行;
continue的作用是跳过本次循环中的continue后面的代码,在for循环和while循环中是有差异的。
那么这两个关键字具体怎么实现,我们采取一个例子来帮助我们理解:持续地从用户那里读取整数,直到用户输入了一个特定的值(例如0)来终止循环。
#include <stdio.h>
int main() {
int number;
printf("请输入一系列整数(输入0来结束):\n");
while (1) { // 创建一个无限循环
scanf("%d", &number);
if (number == 0) {
break; // 如果用户输入了0,则退出循环
}
printf("您输入了:%d\n", number);
}
printf("循环已结束。\n");
return 0;
}
在这个情景中,我们使用了一个while
循环,条件设置为1
(永远为真),创建了一个无限循环。程序会一直请求用户输入整数。如果用户输入的整数不是0,程序会打印出这个数。当用户输入0时,break
语句会被执行,导致循环结束,程序继续执行后续的代码,打印出"循环已结束。"。这个例子展示了break
语句如何用于提前退出一个无限循环,使程序在满足特定条件时停止执行。
下面我们提供一个适用于continue语句执行的情景:计算1到10之间所有奇数的和,跳过偶数。
#include <stdio.h>
int main() {
int sum = 0;
int i;
// 遍历1到10之间的数字
for (i = 1; i <= 10; i++) {
// 如果当前数字是偶数,跳过本次循环的剩余部分
if (i % 2 == 0) {
continue;
}
// 累加奇数
sum += i;
}
printf("1到10之间所有奇数的和是:%d\n", sum);
return 0;
}
在这个情景中,我们使用了一个for
循环来遍历数字1到10。在每次循环中,我们检查当前数字i
是否是偶数。如果是,continue
语句会导致本次循环的剩余部分被跳过,即不会将当前的偶数加到sum
变量中。如果当前数字是奇数,continue
语句不会执行,而是将奇数累加到sum
变量中。循环结束后,我们打印出累加的奇数和。
这个例子展示了continue
语句在循环中的使用,它允许我们在满足特定条件时跳过循环的某一次迭代,但继续执行循环的后续迭代。
综上所述,我们能够总结出这两个关键字使用的情景:
break关键字的使用场景:
- 当需要在循环内部提前退出循环时使用
break
。 - 在
switch
语句中,用于退出case
块,防止代码穿透到下一个case
。 - 在嵌套循环中,用于直接退出最内层的循环。
continue关键字的使用场景:
- 当需要跳过循环的当前迭代,继续下一次迭代时使用
continue
。 - 用于避免不必要的计算或操作,提高程序效率。
- 在处理数据集合时,如果某些元素不需要处理,可以使用
continue
跳过这些元素。
六、循环的嵌套
前⾯学习了三种循环 while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决 问题,就是我们所说的:循环嵌套,这⾥我们就看⼀个例⼦。
找出100~200之间的素数,并打印在屏幕上。 注:素数⼜称质数,只能被1和本⾝整除的数字。
题⽬解析:
1. 要从100~200之间找出素数,⾸先得有100~200之间的数,这⾥可以使⽤循环解决。
2. 假设要判断i是否为素数,需要拿2~i-1之间的数字去试除i,需要产⽣2~i-1之间的数字,也可以使⽤ 循环解决。
3. 如果2~i-1之间有数字能整除i,则i不是素数,如果都不能整除,则i是素数。
#include<stdio.h>
int main()
{
int i = 0;
//循环产⽣100~200的数字
for (i = 100; i <= 200; i++)
{
//判断i是否为素数
//循环产⽣2~i-1之间的数字
int j = 0;
int flag = 1;//假设i是素数
for (j = 2; j < i; j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
printf("%d ", i);
}
return 0;
}
通过这道题目,我们能够总结出,面对一个问题的时候,虽然代码的编写过程很重要,但是对于问题的逻辑来说,逻辑的编写是更加重要的,因此我们在编写代码的时候,需要使得我们的思维逻辑清晰,才能够分析好从中的关键部分,我认为这是至关重要的。