分支语句

if-else语句

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hello\n");
else
printf("panghu\n");
return 0;
}
//输出结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hello\n");
else
printf("胖虎\n");
else
printf("panghu\n");
return 0;
}
//输出结果:panghu

观察上面两段代码,输出结果分别是什么?

由此可知:else的匹配规则:else总是与离它最近的未匹配的if匹配,与缩进无关。

switch-case语句

switch()括号内是整形表达式。

case后接整型常量表达式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int i = 0;
scanf("%d" , &i);
switch (i) {
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break;
case 6:
case 7:
printf("休息日\n");
break;
default:
printf("输入错误");
break;
}
return 0;

思考下面代码,输出结果是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main()
{
int n = 1;
int m = 2;
switch (n)
{
case 1:
m++;
case 2:
n++;
case 3:
switch (n)
{//switch允许嵌套使用
case 1:
n++;
case 2:
m++;
n++;
break;
}
case 4:
m++;
break;
default:
break;
}
printf("m = %d, n = %d\n", m, n);
return 0;
}
//5 3

循环语句

continue比较

1
2
3
4
5
6
7
int i = 1;
while (i < 10) {
if (i == 5)
continue;
printf("%d", i);
i++;
}

观察上端代码,打印结果是什么?

结果为1234,然后死循环。

continue是结束本次循环,进入下次循环。当i=5时进入if语句,然后跳出,然后再进入,以此往复。

再看下面的代码:

1
2
3
4
5
6
int i = 0;
for (i = 1; i < 10; i++) {
if (i == 5)
continue;
printf("%d", i);
}

结果是12346789,与while循环相比,这次遇到continue跳出本次循环后能够让i自增,不会进入死循环。

getchar()putchar()

缓存区问题:

char arr[20] = { 0 };
printf("请输入密码\n");
scanf("%s" , arr);
printf("请确认密码 Y/N\n");
int ch = getchar();
if ('Y' == ch) {
    printf("确认成功\n");
}
else {
    printf("确认失败\n");
}

当我输入1234时,还没等确认,直接提示确认失败。

image-20220115154137025

原因是当我输入1234后会按回车换行,也就是\n,此时缓存区会存在\ngetchar()会从缓存区取出\n,ch=\n,不等于Y,弹出确认失败。

如何解决这种问题?

**方法1:**在scanf语句后面加上getchar()来取出\n,这样ch再访问缓存区就为空了。但这样也有弊端,例如当我输入1234 abcd时又出现错误了。

image-20220115154856069

原因是输入格式%s只读取空格之前的内容,而getchar()只能读取一个字符,所以ch再次读取时发现缓存区还有其他字符且不是Y,提示确认失败·。

方法2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char arr[20] = { 0 };
printf("请输入密码\n");
scanf("%s" , arr);
int tmp = 0;
while ((tmp = getchar()) != '\n') {
;
}
printf("请确认密码 Y/N\n");
int ch = getchar();

if ('Y' == ch) {
printf("确认成功\n");
}
else {
printf("确认失败\n");
}

用while循环,多次读取,直到缓存区为空,跳出循环。

赋值和判断

观察下面代码,该代码循环几次?

1
2
3
4
5
int i = 0;
int k = 0;
for (i = 0, k = 0; k = 0; i++, k++)
k++;
return 0;

循环0次。为什么呢?原因是判断部分写成了k=0,=为赋值,使得条件为假,不进入for循环,代码执行0次。

循环的应用:

1
2
3
4
5
6
7
8
//非递归求5的阶乘
int i = 1;
int sum = 0;
int rst = 1;
for (i = 1; i <= 5; i++) {
rst = rst * i;
}
printf("%d", rst);
1
2
3
4
5
6
7
8
9
//求1!+2!+……+5!之和
int i = 1;
int sum = 0;
int rst = 1;
for (i = 1; i <= 5; i++) {
rst = rst * i;
sum += rst;
}
printf("%d", sum);

strcmp()

C 库函数 int strcmp(const char *str1, const char *str2)str1 所指向的字符串和 str2 所指向的字符串进行比较。

该函数返回值如下:

  • 如果返回值小于 0,则表示 str1 小于 str2。
  • 如果返回值大于 0,则表示 str1 大于 str2。
  • 如果返回值等于 0,则表示 str1 等于 str2。

因此比较两个字符串值是否相同时,不能用==,应该用strcmp()函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <string.h>

int main ()
{
char str1[15];
char str2[15];
int ret;


strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");

ret = strcmp(str1, str2);

if(ret < 0)
{
printf("str1 小于 str2");
}
else if(ret > 0)
{
printf("str1 大于 str2");
}
else
{
printf("str1 等于 str2");
}

return(0);
}

rand()srand()

rand():Generates a pseudorandom number. 生成一个伪随机值

int rand( void );

1
2
3
printf("%d\n",rand());
printf("%d\n", rand());
printf("%d\n", rand());

运行上段代码,会发现每次运行结果都一样,这不是我们理想中的随机值。

Use the srand function to seed the pseudorandom-number generator before calling rand.

我们可以用srand()来使伪随机值变化。Sets a random starting point.

void srand( unsigned int seed );

我们可以用时间作为参数,只要每次播种的时间不同,那么生成的种子就不同,最终的随机数也就不同。

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int a;
srand((unsigned)time(NULL));
a = rand();
printf("%d\n", a);
return 0;
}

C语言随机数生成教程,C语言rand和srand用法详解 (biancheng.net)