1. if语句
1.1 if语句
if 语句的语法形式如下:
if(表达式)
语句
如果表达式成立(为真),则语句执行,如果表达式不成立(为假),则语句不执行。
在C语言中,0为假,非0为真,也就是表达式的结果如果是0,则语句不执行,表达式的结果不为0,则语句执行。
例如:输入一个整数,判断是否为奇数
int main()
{
int x = 0;
scanf("%d", &x);
if(x % 2 == 1)
printf("该数是奇数\n");
return 0;
}
得到:
1.2 else
如果一个数不是奇数,那就是偶数,如果任意一个整数,我们要清楚的判断是奇数函数偶数时,可以使用if........else语句,语法形式如下:
if(表达式)
语句1
else
语句2
例子:输入一个整数,判断是否为奇数,是奇数打印奇数,否则打印偶数。
int main()
{
int a = 0;
scanf("%d", &a);//输入一个整数
if(a % 2 == 1)
printf("%d是奇数", a);
else
printf("%d是偶数", a);
return 0;
}
又例如:输入一个年龄,若>=18则输出:成年,否则输出:未成年
int main()
{
int age = 0;
scanf("%d", &age);//输入一个年龄
if(age >= 18)
printf("成年\n");
else
printf("未成年\n");
return 0;
}
1.3 分支中包含多条语句
默认在 if 和 else 语句中默认只控制一条语句,例如:
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)
printf("成年\n");
printf("可以谈恋爱了\n");
return 0;
}
发现无论输入值大于或者小于18岁,都会打印"可以谈恋爱了"。这是因为 if 语句只能控制一条语句,就是printf("成年\n");if 语句为真,则打印;if 语句为假,则不打印。但是对于printf("可以谈恋爱了\n")是独立存在的,无论真假都会输出。如果我们想让 if 语句同时控制2条语句,则可以使用大括号将需要被 if 控制的语句括起来。修改后得到:
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)
{
printf("成年\n");
printf("可以谈恋爱了\n");
}
return 0;
}
1.4 嵌套if
在 if else 语句中,else 可以与另一个 if 语句连用,构成多重判断。
例如:输入一个整数,判断输入的整数是 0 ,还是正数或者负数。代码如下:
int main()
{
int num = 0;
scanf("%d", num);
if(num == 0)
{
printf("这个数是%d\n", num);
}
else
{
if(num > 0)//这就是if else语句中嵌套了一个if else语句
{
printf("这个数是%d\n", num);
}
else
{
printf("这个数是%d\n", num);
}
}
return 0;
}
又例如:输入一个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:非正数。
int main()
{
int num = 0;
scanf("%d", &num);
if(num>0)
{
if(num%2 == 0)
printf("偶数\n");
else
printf("奇数\n");
}
else
{
printf("⾮正数\n");
}
return 0;
}
1.5 悬空else问题
如果有多个 if 和 else ,可以记住,else 总是跟最接近的 if 匹配。
例如:
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
运行得到:
这是因为悬空 else 的问题,如果有多个 if 和 else ,else 总是跟最近的 if 匹配。
并且在排版上,让 else 和 if 语句对齐,让我们以为 else 总是和第一个 if 匹配,当语句不成立的时候,自然想到执行 else 子语句,打印 haha,但实际上 else 是和第二个 if 进行匹配的,这个代码其实是一个if else 语句嵌套在了一个 if 语句中,所以 if 中的条件不成立,嵌套中的 if ... else就不执行了。
实际上代码就是:
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
当我们希望第一个 if 与 else 进行匹配时,可以改为:
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
}
else
printf("haha\n");
return 0;
}
只要带上适当的大括号,代码的逻辑会更加清晰,所以写代码的时候适当加入大括号,让代码的可读性更高。
2. 关系操作符
C语言中用于比较的表达式被称为“关系表达式”, 里面使用的运算符就称为“关系运算符”,主要有下面6个。
- > 大于运算符
- < 小于运算符
- >= 大于等于运算符
- <= 小于等于运算符
- == 相等运算符
- != 不相等运算符
例如:
a == b;
a != b;
a < b;
a > b;
a <= b;
a >= b;
关系表达式通常返回 0 或者 1 ,表示真假
C语言中, 0 表示假,其余非零值表示真。例如, 20 > 12 返回1, 12 > 20返回 0.
关系表达式常用于 if 或者 while 结构。
if (x == 3)
{
printf("x is 3.\n");
}
注意:相等运算符 == 与赋值运算符 = 是两个不同的运算符。有时混淆会导致出现意料之外的结果。例如:
if(a == 3);//判断a与3是否相等
if(a = 3);//将3赋值给a
这两者并不相同,第一条是判断 a 与 3 是否相等,而下面是将3赋值给a,第一条代码只有当a是3时括号内返回1。但第二条代码是将3 赋值给 a,返回3,所以 if 判断总是为真。
为了防止出现该类错误,一些程序员喜欢将变量写在等号右边。
if( 3 == x) ...
这样如果 == 写成 = 时,编译器会报错
还有一个需要避免的错误是:多个关系运算符不宜连用。
i < j < k;
上述示例中,连续使用两个小于运算符。这是合法表达式,但是通常达不到想要的结果, 即表示不了变量 j 在变量 i 和 k 之间。因为关系运算符是从左到右计算,所以是:
(i < j) < k;
如果i < j 则 (i < j)的返回是1,所以 k 只需要大于1,则返回真。若想要判断变量 j 是否在两变量之中,可以使用&&逻辑与运算符。
i < j && j < k;
例如:我们输入一个年龄,如果在18到36岁之间,输出青年。
int main()
{
int age = 0;
scanf("%d", &age);
if( 18 <= age <= 36)
{
printf("是青年\n");
}
return 0;
}
当输入10时,依然输出青年,但是我们修改一下:
int main()
{
int age = 0;
scanf("%d", &age);
if( 18 <= age && age <= 36)
{
printf("是青年\n");
}
return 0;
}
这样修改则成功输出,当在范围内为青年 。
3. 条件操作符
条件操作符也叫三目操作符,需要三个操作数,形式如下:
exp1 ? exp2 : exp3
条件操作符的计算逻辑是:如果exp1是真,exp2计算,计算的结果是整个表达式的结果;如果exp1为假,则exp3计算,计算的结果是整个表达式的结果。
例如将以下代码修改为包含条件操作符的代码:
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
if (a > 5)
b = 3;
else
b = -3;
printf("%d\n", b);
return 0;
}
修改后得到:
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
b = a > 5 ? 3 : -3;
printf("%d\n", b);
return 0;
}
又例如使用表达式实现找两个数中较大值
int main()
{
int a = 0;
int b = 0;
int m = 0;
scanf("%d %d", &a, &b);
int m = a > b ? a : b;
printf("%d和%d两个数中,%d更大\n", a, b, m);
return 0;
}
4. 逻辑操作符:&&,||,!
逻辑运算符提供逻辑判断功能,用于构建更加复杂的表达式,主要有下面三个运算符。
- !:逻辑取反运算符(改变单个表达式的真假)。
- &&:逻辑与运算符,就是并且的意思(当且仅当两端的表达式都为真时,输出真,否则输出假)
- ||:逻辑或运算符,就是或者的意思(当且仅当两端的表达式都为假时,输出假,否则输出真)
注意:C语言中非0为真,0为假
4.1逻辑取反运算符 !
a | !a |
非0 | 0 |
0 | 非0 |
例如,当有一个变量flag,如果flag为假,要做一个事情,就这样可以写一个代码:
int main()
{
int flag = 0;
if(!flag)//flag为0时代表假,但是 !flag则为真
{
printf("实现flag失败");
}
return 0;
}
如果flag为真,则 !flag 则为假,不执行if分支,而flag为假时,!flag为真,执行if语句中的代码。
4.2逻辑与运算符
a | b | a&&b |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
当我们要进行一长串的判断时,可以使用逻辑与运算符&&,使用方法为a&&b,只有逻辑与运算符两端表达式都为真时,才为真。
例如,当一个人,在18到32岁为青年,则代码如下:
int main()
{
int num = 0;
scanf("%d", &num);
if(num > 18 && num < 32)
{
printf("青年\n");
}
return 0;
}
4.3逻辑或运算符
a | b | a||b |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
逻辑或运算符用法与逻辑与运算符相同,a||b,并且只有运算符两端表达式都为假时,得到的才为假。
例如:一年中12或者1或者2月为冬天,用代码表示为:
int main()
{
int month = 0;
scanf("%d", %month);
if(month == 12 || month == 1 || month == 2)
{
printf("%d月是冬天");
}
return 0;
}
闰年的判断
条件1:能被4整除并且不能被100整除
条件2:能被400整除
int main()
{
int year = 0;
scanf("%d", &year);
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
{
printf("是闰年\n");
}
return 0;
}
4.4短路
C语言逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值。
如果左边的表达式满足逻辑运算符的条件,就不会再对右边的表达式求值,这种情况称为“短路”
例如:
if(month >= 3 && month <= 5)
这里如果month的值不符合>=3,则month >= 3为假,我们知道,逻辑与运算符只有两端表达式都为真时,才为真,所以直接满足逻辑运算符的条件,那么不会对右边的month<=5进行求值。
同理对于逻辑或运算符||也一样:
if(month == 12 || month==1 || month == 2)
如果month == 12为真,那么后面的表达式则不会进行,因为逻辑或运算符当且仅当两端表达式都为假时才为假。
想这样仅仅根据左操作数的结果就可以得到整个表达式的结果,不再对右操作数进行计算的运算称为短路求值。
又例如
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
//i = a++||++b||d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
根据我们所学,a++先判断再+1,那么a=0判断为假,使得整个逻辑表达式的结果都知道为假,那么后面的操作数将不进行计算,所以i 为0,a为1,b为2,c为3,d为4
若为:
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ || ++b || d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
得到
因为a先判断为假再+1,无法直接判断逻辑表达式结果,但是b先+1再判断,为真,可以直接判断出逻辑表达式的结果,所以d++不执行,得到上面的结果。
5.switch语句
C语言中还可以使用switch语句来实现分支结构。
switch语句是一种特殊形式的if...else结构,用于盘带你条件有多个结果的情况,将多重的else if改成更易用的形式。
switch (expression) {
case value1: statement
case value2: statement
default: statement
}
上面代码中表达式expression不同的值,执行相应的case分支。如果找不到则执行default分支。
- switch语句后的expression必须是整型表达式
- case后的值,必须是整型常量表达式
5.1 if语句和switch语句对比
例如输入一个整数值,计算除3之后的余数:
int main()
{
int n = 0;
scanf("%d", &n);
if (n % 3 == 0)
printf("整除,余数为0\n");
else if (n % 3 == 1)
printf("余数是1\n");
else
printf("余数是2\n");
return 0;
}
改为使用switch语句,则为:
int main()
{
int a = 0;
scanf("%d", &a);
switch (a % 3)
{
case 0:
printf("得到的余数为0\n");
break;
case 1:
printf("得到的余数为1\n");
break;
case 2:
printf("得到的余数为2\n");
break;
}
return 0;
}
注意
- case和后边的数字之间必须有空格
- 每一个case语句中的代码执行完成后,需要加上break,才可以跳出整个switch语句
5.2 switch语句中的break
如果前面的代码去掉break,则得到:
这是因为switch语句也是分支效果,只有当switch语句中出现break才能跳出switch语句。如果某一个case语句的后边没有break语句,代码会继续往下执行,可能为执行到其他case的语句,知道遇到break语句或者switch语句结束。
break也不是每个case语句都需要,要根据实际情况来看。
例如,输入一个1~7的数字,打印对应的星期几:
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("今天是星期一");
break;
case 2:
printf("今天是星期二");
break;
case 3:
printf("今天是星期三");
break;
case 4:
printf("今天是星期四");
break;
case 5:
printf("今天是星期五");
break;
case 6:
printf("今天是星期六");
break;
case 7:
printf("今天是星期日");
break;
}
return 0;
}
现在我们需要输入1~5时打印今天是工作日,输入6~7时打印今天是休息日。
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("今天是工作日");
break;
case 6:
case 7:
printf("今天是休息日");
break;
}
return 0;
}
5.3 switch语句中的default
在使用switch语句时,可能经常会遇到表达式内的值没有对应的case语句时,这时候要不就不要处理,要不就得在switch语句中加入default语句。
switch (expression) {
case value1: statement
case value2: statement
default: statement
}
switch后的expression的结果不为value1或者value2时,会执行default子句。
例如在之前的打印星期的例子中,加入输入不为1~7时则打印输入错误,请重新输入:
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("今天是星期一");
break;
case 2:
printf("今天是星期二");
break;
case 3:
printf("今天是星期三");
break;
case 4:
printf("今天是星期四");
break;
case 5:
printf("今天是星期五");
break;
case 6:
printf("今天是星期六");
break;
case 7:
printf("今天是星期日");
break;
default:
printf("输入错误,请重新输入");
break;
}
return 0;
}
5.4 switch语句中的case与default的顺序问题
在switch语句中case子句和default子句没有顺序要求,只要顺序满足需求即可。不过通常将default语句放在最后处理。
6. while循环
C语言中提供了三种循环语句,while就是其中一种,while语句的语法结构与if语句非常相似。
6.1 if与while的对比
if(表达式)
{
语句;
}
while(表达式)
语句;//若循环语句较多,可以使用大括号
例如:
int main()
{
if (1)
printf("hehe\n"); //if后边条件满⾜,打印⼀次hehe
return 0;
}
int main()
{
while (1)
printf("hehe\n"); //while后边的条件满⾜,死循环的打印hehe
return 0;
}
6.2 while语句的执行流程
while(表达式)
{
语句;
}
当表达式为真时,执行循环中的语句,当表达式为假时,跳出循环。并且每一次执行完语句后再继续进行判断,是否进行下一次循环。
6.3 while循环的使用
例如使用while语句打印1~10的值:
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i++;
}
printf("\n");
return 0;
}
得到:
6.4 练习
输入一个正的整数,逆序打印这个整数的每一位
例如:输入:1234,输出:4 3 2 1
首先想要得到最低位的数字可以使用%10得到其余数,打印得到最低位时,可以使用/10使得最低位去掉,如此循环,则可以得到其所有值。
int main()
{
int a = 0;
scanf("%d", &a);
while (a)
{
printf("%d ", a % 10);
a /= 10;
}
printf("\n");
return 0;
}
7. for循环
7.1 语法形式
for循环的语法形式如下:
for(表达式1;表达式2;表达式3)
语句;//如果想要加入更多的语句,可以使用大括号
表达式1:用于循环变量的初始化
表达式2:用于循环结束条件的判断
表达式3:用于循环变量的调整
7.2 for循环的执行流程
首先表达式1使得循环变量初始化,然后进行表达式2进行判断,若为真,则执行循环中的语句,后进行表达式3对循环变量进行调整,然后反复执行表达式2的判断,循环中的语句,以及表达式3的调整,直到表达式2的判断为假则跳出循环,例如:
int main()
{
for (int i = 0; i < 5;i++)
{
printf("hehe\n");
}
return 0;
}
得到
例子中i初始化的值为0,i<5成立,执行打印,然后i + 1,然后继续判断,执行,+1,当i = 5时,i<5 不成立,所以跳出循环,一共执行5次。
7.3 for循环的实践
练习:在屏幕上打印1~10的值
int main()
{
for (int i = 1; i < 11; i++)
{
printf("%d ", i);
}
printf("\n");
return 0;
}
得到:
7.4 while循环与for循环对比
while循环:
int main()
{
int i = 1;//初始化
while (i <= 10)//判断
{
printf("%d ", i);
i++;//调整
}
printf("\n");
return 0;
}
for循环:
int main()
{
for (int i = 1; i < 11; i++)
// 初始化 判断 调整
{
printf("%d ", i);
}
printf("\n");
return 0;
}
由此可见,for循环的可视度更高,更加容易解读,并且代码较多时while循环的三部分就比较分散。
7.5 练习
1.计算1~100之间3的倍数的数字之和
int main()
{
int num = 0;
for (int i = 1; i <= 100;i++)
{
if (i % 3 == 0)
{
num += i;
}
}
printf("%d\n", num);
return 0;
}
优化得:
int main()
{
int num = 0;
for (int i = 3; i <= 100;i += 3)//直接得到3的倍数的值
{
num += i;
}
printf("%d\n", num);
return 0;
}
8. do-while 循环
8.1 语法形式
do
{
语句;
}while(表达式);
while和for循环都是先判断,满足条件才进入循环,执行循环语句,如果不满足条件,则跳出循环。
而do-while循环是先执行一次循环语句之后再对表达式真假进行判断,如果为真,则继续循环语句;如果为假,则跳出循环语句。
区别在于你是否需要先执行一次循环语句,若不需要则使用for和while循环,需要则使用do-while循环语句。
8.3 do-while循环示例
在屏幕上打印1~10的值
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i < 11);
printf("\n");
return 0;
}
一般do-while循环使用在循环体至少被执行一次的场景下,所以使用较少。
8.4 练习
输入一个正整数,计算这个数是几位数
例如:输入:1234 输出:4
输入:12 输出:2
int main()
{
int a = 0;
int count = 0;
scanf("%d", &a);
do
{
a /= 10;
count++;
} while (a);
printf("%d ", count);
return 0;
}
这里并不是必须使用do-while循环,但是如果使用其他循环要考虑a = 0的情况,而使用do-while循环则可以直接包括这种情况。
9. break和continue语句
在循环执行的过程中,如果某些情况发生的时候,需要提前终止循环,可以使用break和continue两个关键字,就是应用到循环中的。
- break:其作用是永久终止循环,只要break被执行,直接就会跳出循环,继续往后执行。
- continue:作用是跳过本次continue后边的代码,在for循环和while循环中有所差异。
9.1 while循环中的break和continue
9.1.1 break例子
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;//当i等于5后,就执⾏break,循环就终⽌了
printf("%d ", i);
i = i + 1;
}
return 0;
}
运行得到:
因为打印了1,2,3,4之后第五次碰到了break所以循环终止了。只要break被执行了,break外的第一层循环就终止了。以后我们在循环中,想要在某种条件下终止循环,则可以使用break来完成我们需要的效果。
9.1.2 continue例子
continue是继续的意思,在循环中的作用是跳过本次循环中continue后的代码,继续进行下一次循环的判断。
例如将上面例子中的break用continue来代替,得到:
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;//当i等于5后,就执⾏continue,这次循环里continue后的代码不执行了
//但是由于跳过了i = i + 1的语句,导致其死循环
printf("%d ", i);
i = i + 1;
}
return 0;
}
所以continue使用不当会导致死循环,例如将循环的调整放在continue的后面会导致死循环。
9.2 for循环中的break和continue
9.2.1 break举例
其实和while循环中的break一样,只要for循环中执行到break,则直接中断循环。
例如:
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
break;
printf("%d ", i);
}
return 0;
}
得到:
9.2.2 continue例子
上面例子中的break换成continue,得到:
int main()
{
int i = 1;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;//continue跳过了打印,来到了调整i++
printf("%d ", i);
}
return 0;
}
结果与while循环不一样,这是因为while循环需要写在循环内部,使用continue可能会导致调整的语句被跳过,从而导致死循环,但是for循环的调整是不在循环语句之内,所以不会出现因为跳过调整而导致死循环的情况。
10. 循环的嵌套
前面学习了三种循环while,do while,for循环,这三种循环往往会嵌套在一起才能更好解决问题。
10.1 练习
找出100~200之间的素数,并打印在屏幕上。质数是只能被1和本身整除的数字。
10.2 题目解析:
- 要从100~200之间找出素数,可以使用循环解决
- 假设要判断i是否为素数,只要与2~i-1的数字去试i,需要2~i-1之间的数字,也要使用循环。
- 如果2~i-1之间有数字可以整除i,则 i 就不是素数。
int main()
{
for (int i = 100; i < 201;i++)//生成100~200的数字
{
int flag = 0;
for (int j = 2; j <= i - 1; j++)//生成2~i-1的数字
{
flag = 0;//每次整除初始化flag
if (i % j == 0)//判断不为素数则跳出循环
{
break;
}
else
{
flag = 1;//不能被当前的j整除,继续循环判断有没有数可以整除他
}
}
if (flag == 1)//当2~i-1的数都不能整除i则其为素数
{
printf("%d ", i);
}
}
return 0;
}
11. goto语句
C语言中提供了一种非常特别的语法,就是goto语句和跳转标号,goto语句可以实现在同一个函数内跳转设置好的标号处。
例如:
int main()
{
printf("hehe\n");
goto next;
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}
goto语句如果使用不当,就会导致在函数内部随意跳转,打乱程序的执行流程,使用能不用尽量不去使用,但是在多层循环中,如果需要快速跳转使用goto就非常方便了。
例如:
int main()
{
for ()
{
for ()
{
for ()
{
if (disaster)
goto error;
}
}
}
error:
return 0;
}
这里如果使用break语句需要使用三次才可以跳出循环,因为break一次只能跳出一层循环,而使用goto语句则直接跳出全部循环。
标签:缓进,语句,int,徐图,C语言,break,循环,printf,main From: https://blog.csdn.net/2403_86960956/article/details/141831158