前言:
什么是语句? C语言可分为以下五类:
表达式语句
函数调用语句
控制语句
复合语句
空语句
语句:C语言中,由分号隔开的句子就是一条语句
如:
#include
int main()
{
3 + 5;//表达式语句
printf("haha\n");//函数调用语句
;//空语句
return 0;
}
C语言中用非零表示真,用零表示假,即:逻辑真,逻辑假
三大语法结构:顺序结构、分支(选择)结构、循环结构
/知识点汇总/
控制语句:用于控制程序的执行流程,以实现程序的各种结构方式,由特定的语句定义符组成,C语言有九种控制语句
可以分为三类:
1.条件判断语句/分支语句:if语句、switch语句
2.循环执行语句:do while语句、whule语句、foe语句
3.转向语句:break语句、goto语句、continue语句、return语句
C语言中的顺序结构,逻辑很简单,就是代码一条一条的按顺序执行。
有双分支、多分支选择结构
if语句的语法结构:
a、形式一:if(表达式)
语句;
a、形式二:if(表达式)
语句1;
else
语句2;
a、形式三:if(表达式1)
语句1;
else if(表达式2)
语句2;
...
else
语句n;
2.1.1 、if—else语句例程1
/*例程2.1.1*/
#include <stdio.h>
int main()
{
int age;
scanf("%d",&age);
//形式一:
if (age >= 18)
printf("成年");
//形式二:
if (age >= 18)
printf("成年");
else
printf("未成年");
//形式三:
if (age >= 18)
printf("成年");
//区分逻辑真,age=60也可输出,故不满足条件
//else if (18 <= age <= 28)
else if (age>=18 && age <= 28)
printf("青年");
else
printf("发展");
return 0;
}
2.1.2 、if多分支例程1
//age<18 --- 未成年
//18~30 ---- 青年
//31~50 ----- 中年
//51~70 ------ 中老年
//71~99 ------ 老年
//>99 ----- 老寿星
//嵌套写法---待简化
#include
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("未成年人\n");
else
{
if (18 <= age && age <= 30)
printf("青年\n");
else
{
if (age >= 31 && age <= 50)
printf("中年\n");
else
{
if (age >= 51 && age <= 70)
printf("中老年\n");
else
{
if (age >= 71 && age <= 99)
printf("老年\n");
else
printf("老寿星\n");
}
}
}
}
return 0;
}
2.1.3 、if多分支例程 1— 代码优化
//代码优化 ---多分支
//写法一:
#include
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("未成年人\n");
else if (18 <= age && age <= 30)
printf("青年\n");
else if (age >= 31 && age <= 50)
printf("中年\n");
else if (age >= 51 && age <= 70)
printf("中老年\n");
else if (age >= 71 && age <= 99)
printf("老年\n");
else
printf("老寿星\n");
return 0;
}
//理解写法二:
#include
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("未成年人\n");
else if (age <= 30)//在上一条的if语句判断下,已经排除了<18的范围哦,但是这种写法的顺序不可改变
printf("青年\n");
else if (age <= 50)
printf("中年\n");
else if (age <= 70)
printf("中老年\n");
else if (age <= 99)
printf("老年\n");
else
printf("老寿星\n");
return 0;
}
2.2.1、强调代码规范性例程1
/*例程2.1.2*/
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("haha");
else
printf("hehe");
//此时,该代码不会打印
//因为代码不规范,else理解为就近原则,是与第二个if组合的
return 0;
}
//例程纠正,正确按照逻辑输出
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if (b == 2)
{
printf("haha");
}
else
{
printf("hehe");
}
}
return 0;
}
2.2.2 、强调代码规范性例程2
/*代码规范性例程2*/
//不规范书写
if (codition){
return x;
}
return y;
//规范书写,加括号划分清楚
if (codition)
{
return x;
}
else
{
return y;
}
2.2.3、强调代码规范性例程3
/*代码规范性例程3*/
//避免错误
if(num == 5)
printf("666");
//更好的书写,避免输入为赋值符
if(5 == num)
printf("6868");
2.2.4 、易错例程1
#include
int main()
{
int age = 0;
scanf("%d", &age);//20
if (18 <= age <= 30)//写法C语言的语法错误,因为18<=age成立为非零为1真,1<=30也为真
printf("青年\n");
return 0;
}
2.2.5 、易错例程2
#include
int main()
{
int age = 0;
scanf("%d",&age);
if (age >= 18)
printf("成年人\n");
//故意格式未对齐,容易造成的易错误解
printf("遵纪守法\n");//这条语句总会被执行,因为通常if语句只会跟一条语句,所以分号后的语句照常执行
int num = 20;
if (num >= 18)
{
printf("成年人\n");
printf("遵纪守法\n");//通过加大括号就可以解决if后跟多条语句
}
return 0;
}
a、判断一个数是否为奇数
b、奇数:除二余一
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d",&n);
if (n % 2 == 1)
{
printf("奇数YES\n");
}
else
{
printf("NO\n");
}
return 0;
}
a、输出一百以内的奇数
b、奇数:除二余一
#include <stdio.h>
int main()
{
//方法一:结合for语句
for (int i = 1; i <= 100; i++)
{
int js = i % 2;
if (1 == js)
{
printf(" %d", i);
}
}
printf("\n\n");
//方法二:结合while语句
int num = 1;
while (num >= 1 && num <= 100)
{
if (1 == num % 2)
{
printf(" %d",num);
}
num++;
}
printf("\n");
return 0;
}
打印100以内的奇数方法二:
#include
int main()
{
int i = 1;
while (i <= 100)
{
if (i % 2 == 1)
printf("%d ", i);
i++;
}
//简化
//while (i <= 100)
//{
// printf("%d ", i);
// i+=2;
//}
return 0;
}
附加题:打印100以内奇数的和
#include
int main()
{
int i = 1;
int sum = 0;
for (i=0;i <= 100;i++)
{
if (i % 2 == 1)
{
printf("%d ", i);
sum = sum + i;
}
}
printf("\n%d\n", sum);
return 0;
}
小结:
(1)注意代码的规范性
(2)注意判断的语句赋值符 = 与关系运算符 == 的应用
(3)注意 if—else 语句的对应
switch也属于分支结构,常常用于多分支的情况
switch语句的语法结构如下:
swich(表达式)
{
case 常量1: 语句1 ;break;
case 常量2: 语句2;break;
...
case 常量n: 语句n;break;
default 语句n+1;break;
}
2.4.1 、switch语句例程1
/*例程2.2.1*/
#include <stdio.h>
int main()
{
int day = 0;
printf("请输入一个整数:");
scanf("%d",&day);
switch (day)//switch语句的参数只能整型/字符型/枚举型/字符串型
{
case 1: //case的参数需要为常数
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("无效\n");
break;
}
return 0;
}
小结:
发现例程1,会额外输出不想要的结果
提出break关键字 ---- 实现switch语句中跳出对应分支的效果、
相当于一个隔断效果
2.4.2 、switch语句例程1代码优化
添加break
#include
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
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;
}
return 0;
}
2.4.3 、switch语句例程2
实现1~6工作日 ,7休息日
#include
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
printf("工作日weekday\n");
break;
case 7:
printf("休息日weekend\n");
break;
}
return 0;
}
小结:
根据例程1和2,输入超纲的数字时,没有提示性输出。故引出default关键字
2.4.4 、switch语句例程2代码优化
default关键字 — 默认case语句以外的输出方式
#include
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
printf("工作日weekday\n");
break;
case 7:
printf("休息日weekend\n");
break;
default://实现即使输入错误,也有一个反馈性的提示
printf("输入错误,请再次输入!!!\n");
}
return 0;
}
2.4.5 、switch语句易错例程1
/*例程2.2.5*/
#include <stdio.h>
int main()
{
int n = 1;
int m = 2;
switch (n)
{
case 1:
m++;//3
//没有break跳出,所以继续执行case2,依次类推...
case 2:
n++;//2
case 3:
switch (n)//嵌套switch语句,n = 2
{
case 1:
n++;
case 2: //n=2的入口
m++;//4
n++;//3
break;//跳出本switch语句
}
case 4:
m++;//5
break;//跳出本switch语句
default:
break;
}
printf("m = %d,n = %d\n",m,n);//m = 5,n = 3
return 0;
}
小结:
(1)switch语句的参数只能整型/字符型/枚举型/字符串型
(2)case的参数需要为常数
(3)break在switch语句的正确使用
循环语句:
while语句、for语句、do while语句
语法格式:与if语句结构类似
while(条件)
{
语句;
}
举例说明:
#include
int main()
{
if (1)//执行一次
printf("haha\n");
while (1)//死循环
printf("haha\n");
return 0;
}
while语句例程1
说明:打印1~10
#include
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ",i);
i++;
}
return 0;
}
getchar() — 获取(输入)一个字符
int getchar(void);
从键盘与系统缓冲区中读取一个字符,返回值是一个整型,读取失败或文件末尾就返回EOF(-1)
即:读取成功返回字符的ASCII码值,读取失败或遇到文件末尾时,返回EOF(-1)
putchar() — 输出一个字符
int putchar(int character);
#include
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)//当是一个有效字符为真就执行
//window环境下,用Ctrl + Z组合键退出
{
putchar(ch);
}
return 0;
}
#include
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
{
if (ch < '0' || ch > '9')//意味着,只能将0~9的字符有效输出
continue;
putchar(ch);
}
return 0;
}
清空缓冲区的应用1
#include
int main()
{
char password[20];
printf("请输入密码:>");//abcdef\n
scanf("%s",password);
//缓冲区会暂时存入键盘的输入数据
//\n会被getchar拿出,所以会直接进行(Y/N)的判断,导致与理想结果不同
getchar();//所以这个getchar是来清空缓冲区的\n字符的,后面就可正常等待缓冲区的输入了
printf("请确认(Y/N):");
int ch = getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
清空缓冲区的应用2
说明:scanf函数以空格或换行标志着结束
优化 3.2.3代码
#include
int main()
{
char password[20];
printf("请输入密码:>");//abcdef qqqqqq\n
scanf("%s", password);
//缓冲区会暂时存入键盘的输入数据
while (getchar() != '\n')//清楚缓冲区直到清楚最后一个'\n'换行结束,用来解决存在空格的情况
{
;//当不等于'\n',就执行空语句。依次消耗缓冲区的数据
}
//这个是来清空缓冲区的,后面就可正常等待缓冲区的输入了
printf("请确认(Y/N):");
int ch = getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
语法格式:
for(表达式1;表达式2;表达式3)//或者说:初始化部分、循环判断部分、调整部分
{
循环语句;
}
举例说明:
#include
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
printf("%d ",i);
}
return 0;
}
for语句例程
初始化的问题
#include
int main()
{
//写法一:正常初始化i
int i = 0;//初始化i
for (i = 1; i < 10; i++)
{
printf("%d ", i);
}
printf("\ni = %d\n", i);//正常打印i
//C99 写法二:在for初始化部分初始化i
for (int i = 1; i < 10; i++)
{
printf("%d ", i);
}
printf("\ni = %d\n", i);//无法正常打印i,i只能在for语句中使用,作用域仅限于fou循环语句中
return 0;
}
1.不可在for循环体内修改变量,防止for循环失去控制
2.建议for语句的循环控制变量的取值采用"前闭后开区间"的写法(即:使得代码的参数具备一定的含义)
3.不随意省略for语句的三个表达式(初始化、判断、调整部分均可省略,但是判断条件省略,意味着恒为真)
for语句例程1
#include
int main()
{
int i = 0;
//易错1
for (i = 0; i < 10; i++)
{
printf("%d ",i);//死循环 6
i = 5;//一般不会在循环体内执行调整部分
}
//易错2
for (i = 0; i < 10; i++)
{
if(i = 5)//写成赋值,同样更改调整部分
printf("%d ", i);//死循环 5
}
//所以不建议在循环体更改调整部分
return 0;
}
for语句例程2
#include
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//数组下标 ---- 0~9
int i = 0;
for (i = 0; i < 10; i++)//[0,10) --- 左闭右开
{
printf("%d ",arr[i]);
}
for (i = 0; i < 10; i++)//[0,9] --- 左闭右闭
{
printf("%d ", arr[i]);
}
return 0;
}
for语句例程3
#include
int main()
{
for (; ;)//恒为真,死循环
{
printf("haha\n");
}
return 0;
}
for语句例程4
//正常写法
#include
int main()
{
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; i < 3; j++)
{
printf("haha\n");//9次haha
}
}
return 0;
}
//省略写法
#include
int main()
{
int i = 0;
int j = 0;
for (; i < 3; i++)
{
for (; i < 3; j++)//因为内部的for循环执行三次结束后j = 3,继续执行i++,i=2,进入内部for循环,j=3不再初始化,所以不再进入内部for循环了
{
printf("haha\n");//3次haha
}
}
return 0;
}
for语句中可有多个表达式作为条件判断
判断循环多少次
#include
int main()
{
int i = 0;
int k = 0;
for (i = 0, k = 0; k = 0; i++, k++)
{
k++;//0次 因为判断部分,k = 0,0恒为假,不执行代码
}
return 0;
}
语法格式:
do
{
循环语句;
}while(表达式);
do while语句特点:
循环至少执行一次,使用性比较局限,所以不常使用
举例说明:
//打印1~10
#include
int main()
{
int i = 1;
do
{
printf("%d ",i);//1 2 3 4 5 6 7 8 9 10
i++;
} while (i <= 10);
return 0;
}
由C语言提供了可以"随意滥用"的goto语句和标记跳转的标号。
不常使用,主要用于一些多层次的嵌套之后,更快速的跳出嵌套
与break区别是一层一层的跳出
语法格式:
flag:
语句/循环/嵌套语句;
goto flag;
注意:
(1)、goto语句的局限性,不能跨函数跳转。
(2)、只能在同一个函数内部跳转,所以”随意“不等于为所欲为
goto语句例程1
例如:随意的跳转,所谓指哪儿跳哪儿
#include
int main()
{
//flag:
printf("hehe\n");
printf("haha\n");
//goto flag;
goto end;
printf("heihei\n");
end:
printf("666666\n");
return 0;
}
goto语句例程2
一次跳出两层或多层循环
#include
int main()
{
for(...)
{
for (...)
{
for (...)
{
goto exti;
}
}
}
exti:
ptintf("666\n");
return 0;
}
#include
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;//当i = 5时,在while循环中执行continue,会跳过后面的语句,回到判断条件继续执行。
//判断时钟i=5,所以导致一直在此处循环
printf("%d ", i);//代码结果就是:1 2 3 4 死循环
i++;
}
return 0;
}
小结:
while中 continue的作用:
跳过本次循环,本次循环后面的语句不执行,直接去判断部分,看是否进行下次循环
#include
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;//当i = 5时,在while循环中执行break,会跳出整个while循环语句,继续执行while循环语句后面的代码。
printf("%d ", i);//代码结果就是:1 2 3 4
i++;
}
printf("\nhaha\n");
return 0;
}
小结:
while循环中的break是永久的终止循环,只要遇到break,循环就终止
continue和break的应用易错例程3
#include
int main()
{
int i = 1;
while (i <= 10)
{
i++;//i++提前
if (i == 5)//注意:= 和 ==的区别
continue;
printf("%d ", i);//代码结果就是:2 3 4 6 7 8 9 10 11
}
return 0;
}
#include
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)//跳过第五次循环,不执行后面的打印,跳到调整部分执行i++
continue;
printf("%d ", i);//1 2 3 4 6 7 8 9
}
return 0;
}
小结:
在for循环语句中continue,会跳过本次循环,跳过后面的代码部分,跳到for语句的调整部分继续执行
#include
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)//跳出循环
break;
printf("%d ", i);//1 2 3 4
}
return 0;
}
小结:
break在while和for循环中,效果相同,跳出循环
#include
int main()
{
int i = 1;
do
{
if (i == 5)
continue;
printf("%d ", i);//1 2 3 4 死循环
i++;
} while (i <= 10);
return 0;
}
小结:
continue跳出本次循环以及后面的语句
#include
int main()
{
int i = 1;
do
{
if (i == 5)
break;
printf("%d ", i);//1 2 3 4
i++;
} while (i <= 10);
return 0;
}
小结:
break在while和for与do while循环中,效果相同,跳出循环