C语言学习之-分支与循环
原创
©著作权归作者所有:来自51CTO博客作者deng_g0708的原创作品,请联系作者获取转载授权,否则将追究法律责任
1. 分支语句误区
1.1 连续判断符号
#include<stdio.h>
int main()
{
int age = 10;
if (18<=age<28)
printf("青年\n");
return 0;
}
执行上面语句时,编译器给出如下warning:
main.c:6:16: warning: result of comparison of constant 28 with boolean expression is always true [-Wtautological-constant-out-of-range-compare]
if (18<=age<28)
~~~~~~~^~~
1 warning generated.
这是因为在if语句中,会先执行18<=age,把得到的结果0(或1)与28进行比较
正确的代码段应该是:
if (18<=age && age<28)
printf("青年\n");
1.2 悬空else:else和离他最近的未匹配的if进行匹配
int a = 0;
int b = 2;
if (a == 0)
if (b==1)
printf("hehe\n");
else
printf("haha\n"); // 会被执行
执行上面语句时,程序输出 haha
, 编译器给出如下warning:
main.c:15:5: warning: add explicit braces to avoid dangling else [-Wdangling-else]
else
^
1 warning generated.
这是悬空else产生的warning,上面代码段的实际运行效果和下面的是一样的:
if (a == 0)
{
if (b==1)
printf("hehe\n");
else
printf("haha\n");
}
2. switch语句
示例:
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;
default:
printf("所输入的数字不是1,2,3,4其中之一\n");
break;
}
注:如果没有 break
语句,则在结束前不会跳出switch语句,这个特性也可以被我们利用,比如如果输入的数字是1~5的话,要求打印工作日,是6或7的话,要求打印休息日,否则打印其他信息:
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break;
case 6:
case 7:
printf("休息日\n");
break;
default:
printf("所输入的数字不是1~7之一\n");
break;
}
return 0;
注意,default是可有可无的,一般用来处理意料之外的case,在顺序,上推荐放在switch语句的最后
3. 循环语句
3.1 while 循环
- while循环的基本使用:
#include <stdio.h>
int main() {
int i = 1;
while (i <= 10) {
printf("%d\n", i);
i++;
}
return 0;
}
- while循环中要注意:
int num;
int b = 1;
while ((num = 1 + 2) == 3)
{
printf("this is a test code\n");
b ++;
if (b == 5)
break;
}
上述循环体中的内容会执行,这也是下面的例子中 while ((ch = getchar()) != '\n')
起作用的原因;
- while循环使用的具体例子:
#include <stdio.h>
#include <string.h>
int main()
{
char ret = 0;
int ch;
char password[20] = {0};
printf("请输入密码:>");
scanf("%s", password);
printf("您输入的密码是:>%s\n", password);
while ((ch = getchar()) != '\n')
{
;
// printf("请忽略本行: ch is %c\n", ch); // 可以放一个空语句 `;`
}
printf("请确认 Y/N :>");
ret = getchar();
printf("ret是:>%c\n", ret);
// if (strcmp(&ret, "Y") == 0)
if ( ret == 'Y')
{
printf("确认成功\n");
}
else
{
printf("放弃确认\n");
}
return 0;
}
3.2 for 循环
- for循环是使用最多的循环结构,for循环的基本使用如下:
#include <stdio.h>
int main() {
int i;
/*打印1~10*/
for (i = 1; i <= 10; i++) {
printf("%d ", i);
}
return 0;
}
- for循环的初始化、判断、调整都可以省略,但是,for循环的判断部分如果被省略,那判断条件就是:恒为真;如果不是非常熟练,建议不要随便省略。
for (; ; ) {
printf("hehe\n");
}
上面的代码就会一直打印 hehe
#include <stdio.h>
int main() {
int i = 0;
int j = 0;
for(i=0; i<3; i++){
for(j=0; j<3; j++){
printf("hehe\n");
}
}
return 0;
}
上面的代码会打印出9个 hehe
,那如果把初始化省略呢?
#include <stdio.h>
int main() {
int i = 0;
int j = 0;
for(; i<3; i++){
for(; j<3; j++){
printf("hehe\n");
}
}
return 0;
}
上面的代码却只会打印出3个 hehe
- for循环的变种
int x;
int y;
for (x = 0, y = 0; x < 2 && y<5; x++, y++)
{
printf("hehe\n");
}
会打印2个 hehe
- 注意事项
int x;
int y;
for (x = 0, y = 0; x = 0; x++, y++)
{
printf("hehe\n");
}
上面不会打印出来 hehe
; 因为判断部分是 x=0
,该表达式的值就是赋值后的 x
的值,所以不会进入到循环体;
3.3 do while 循环
循环语句至少要被执行一次,执行第二次循环语句前会使用while后面的表达式进行判断,为真才执行第二次循环语句;
#include <stdio.h>
int main() {
int i = 1;
do {
printf("%d\n", i);
i++;
} while (i <= 10);
return 0;
}
4. 题目
4.1 计算n的阶乘
int calc_factorial(int num)
{
int res = 1;
while (num)
{
res = res * num;
num --;
}
return res;
}
4.2 计算: 1!+2!+...+10!
int sum = 0;
for (int i= 1; i<=10; i++)
{
sum = sum + calc_factorial(i);
}
4.3 在一个有序数组中查找数字n
- 暴力查找:
#include <stdio.h>
int main()
{
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int num = 10;
int i = 0;
int length = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < length; i++)
{
if (arr[i] == num)
{
printf("找到了, 下标是%d\n", num);
break;
}
}
if (i == length)
printf("没找到\n");
return 0;
}
2:二分查找
#include <stdio.h>
int main()
{
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int num = 10;
int i = 0;
int j = sizeof(arr) / sizeof(arr[0]);
if (num > arr[j - 1] || num < arr[0])
printf("没找到\n");
else
{
while (i < j)
{
int mid = (i + j) / 2;
if (arr[mid] == num)
{
printf("找到了,下标为%d\n", mid);
break;
}
else if (arr[mid] < num)
i = mid;
else
j = mid;
}
if (i >= j)
printf("没找到\n");
}
return 0;
}
- 二分查找的更高效的写法
#include <stdio.h>
int main()
{
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int num = 7;
int i = 0;
int j = sizeof(arr) / sizeof(arr[0]);
if (num > arr[j - 1] || num < arr[0])
printf("没找到\n");
else
{
while (i <= j)
{
int mid = (i + j) / 2;
if (arr[mid] == num)
{
printf("找到了,下标为%d\n", mid);
break;
}
else if (arr[mid] < num)
i = mid + 1;
else
j = mid - 1;
}
if (i > j)
printf("没找到\n");
}
return 0;
}