C语言-第四章-循环

循环

让一段代码重复执行,直到满足设定条件为止。

1 递增和递减运算符

自增或自减,改变的是变量本身的值。如int number=6; number++;则执行完后number自变为7。

2 for循环

打印26个英文字母。

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main()
{
char ch='a';
int i;
for(i=1; i<=26; i++)
printf("%c ", ch++); //这时char的值可以和int互换
return 0;
}

上面for(…)中,第一个表达式是初始条件;第二个表达式必须是一个逻辑表达式,逻辑终点就是在这里确定,最开始i=1,符合i<=26的条件,循环继续;第三个表达式是循环变量,否则会成为死循环,跳不出来。每个表达式之间用“;”隔开。
也可以在for循环里设置多个变量,如:

1
2
for(i=1, j=2; i<=5; i++, j+=2)  //先i=1,再j=2,再比较i是否大于5,再i++,最后j+=2
printf("%5d", i*j);

3 再谈递增和递减运算符

下面三条语句效果相同:

1
2
3
count = count +1;
count += 1;
++count;

而第三条语句,++放在count后和count前有很大区别,如在下例中:

1
2
3
label a:
int count = 5;
total = ++count + 6; //total = 12 & count = 6

执行完第二条语句时,count自增为6并参与运算然后再赋值到左边,total = 6 + 6。但,

1
2
3
label b:
int count = 5;
total = count++ + 6; //total = 11 & count = 6

它是在这条赋值语句执行完后才自增为6,也就是(total = 5 + 6)后再变成6。可以认为label b中第二条语句等价于:

1
2
total = count + 6;
++count;

4 再谈for

4.1 前n个自然数的和:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
long sum = 0L;
int i=1, n, count = 0;
printf("输入整数n:\n");
scanf("%d", &n);
for(; i<=n; i++)
sum += i;
printf("总和是:%d", sum);
return 0;
}

PS:上面的第9、10行可简化为一行:for(; i<=n; sum += i++);

for()语句,括号内是从左到右执行的。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
int m=1,n=3;
for(;m<=8;++m)
{
if(m==n)
break;
}
printf("%d",m); //3
return 0;
}

这个自然数和只作为一个例子,求其和可直接:printf(“%ld”, n*(n+1)/2);

4.2 循环内的break语句

上一章中谈到switch时有引入关键字break,它的意思是跳出语句块执行下一条语句。所以在类似for(;;)这样无限死循环中,可用它来跳出,如:

1
2
3
4
5
6
7
8
char answer = 0;
for(;;)
{
printf("继续输入吗?(y/n)");
scanf("%c", &answer);
if(tolower(answer) == 'n')
break;
}

这里,如果不输入“n”或“N”,则会一直读取输入,执行循环。

5 嵌套循环

循环内还有循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
int i=1;
for(; i<=6; i++)
{
int j=1,sum=0;
for(; j<=i; sum+=j++);
printf("%d\t%d\n",i,sum);
}
return 0;
}

printf语句位于外循环里面,循环里又有一个for循环,每经历一次外循环,初始化j和sum,然后从1开始一直加到当时的i。

写成下面这种方式更容易理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main()
{
int i=1;
for(; i<=6; i++)
{
int j=1,sum=1; //每次外循环都初始化这两个量
printf("1 ");
while(j<i) //另一种循环语句
{
sum+=++j; //sum原值为1,因此除第一次外循环不参与加之外,它从2开始累加,直到加到第i次循环的i
printf("+ %d ",j);
}
printf(" = %d\n",sum);
}
return 0;
}

6 do-while循环

for和while循环都是很检查条件,再执行循环体,也就是如果条件不满足,则一次都不会执行。而do-while语句则至少会执行一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{
int num,renum=0;
printf("输入一个正数:");
scanf("%d", &num);
int temp=num;
do{
renum = 10*renum + temp%10; //往左移一位,加入尾数
temp/=10; //往右移一位,这样可以丢掉已经加的尾数
}while(temp);
printf("%d", renum);
return 0;
}

上例将一个正整数反转。

7 continue

它和break一样,可以跳出循环。只continue是跳过本次循环,而break是跳到最近一个外循环。以查寝为例,当查到某个寝室有妹子时,continue跳过这个寝室,查下一个寝室;而break是直接跳过本层,查下一层。

8 小游戏

屏幕显示一串数字,一秒后删除,如果输入正确3次,增加数字长度。下面是原书代码。原作者提示:当代码可以编译时,应该编译它,但不执行,确保每次写的代码都可以编译。

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* Program 4.12 Simple Simon */
#include <stdio.h> /* For input and output */
#include <ctype.h> /* For toupper() function */
#include <stdbool.h> /* For bool, true, false */
#include <stdlib.h> /* For rand() and srand() */
#include <time.h> /* For time() and clock() */

int main(void)
{
/* Records if another game is to be played */
char another_game = 'Y';

/* true if correct sequence entered, false otherwise */
int correct = false;

/* Number of sequences entered successfully */
int counter = 0;

int sequence_length = 0; /* Number of digits in a sequence */
time_t seed = 0; /* Seed value for random number sequence */
int number = 0; /* Stores an input digit */

time_t now = 0; /* Stores current time - seed for random values */
int time_taken = 0; /* Time taken for game in seconds */

/* Describe how the game is played */
printf("\nTo play Simple Simon, ");
printf("watch the screen for a sequence of digits.");
printf("\nWatch carefully, as the digits are only displayed"
" for a second! ");
printf("\nThe computer will remove them, and then prompt you ");
printf("to enter the same sequence.");
printf("\nWhen you do, you must put spaces between the digits. \n");
printf("\nGood Luck!\nPress Enter to play\n");
scanf("%c", &another_game);

/* One outer loop iteration is one game */
do
{
correct = true; /* By default indicates correct sequence entered */
counter = 0; /* Initialize count of number of successful tries*/
sequence_length = 2; /* Initial length of a digit sequence */
time_taken = clock(); /* Record current time at start of game */

/* Inner loop continues as long as sequences are entered correctly */
while(correct)
{
/* On every third successful try, increase the sequence length */
sequence_length += counter++%3 == 0;

/* Set seed to be the number of seconds since Jan 1,1970 */
seed = time(NULL);

now = clock(); /* record start time for sequence */

/* Generate a sequence of numbers and display the number */
srand((unsigned int)seed);
int i = 1; /* Initialize the random sequence */
for(; i <= sequence_length; i++)
printf("%d ", rand() % 10); /* Output a random digit */

/* Wait one second */
for( ;clock() - now < CLOCKS_PER_SEC; );

/* Now overwrite the digit sequence */
printf("\r");
int r = 1; /* go to beginning of the line */
for(; r <= sequence_length; r++)
printf(" "); /* Output two spaces */

if(counter == 1) /* Only output message for the first try */
printf("\nNow you enter the sequence - don't forget"
" the spaces\n");
else
printf("\r"); /* Back to the beginning of the line */

/* Check the input sequence of digits against the original */
srand((unsigned int)seed);
int q = 1; /* Restart the random sequence */
for(; q <= sequence_length; q++)
{
scanf("%d", &number); /* Read an input number */
if(number != rand() % 10) /* Compare against random digit */
{
correct = false; /* Incorrect entry */
break; /* No need to check further... */
}
}
printf("%s\n", correct? "Correct!" : "Wrong!");
}

/* Calculate total time to play the game in seconds)*/
time_taken = (clock() - time_taken) / CLOCKS_PER_SEC;

/* Output the game score */
printf("\n\n Your score is %d", --counter * 100 / time_taken);

fflush(stdin);

/* Check if new game required*/
printf("\nDo you want to play again (y/n)? ");
scanf("%c", &another_game);

}while(toupper(another_game) == 'Y');
return 0;
}

9 练习

9.1 乘法表

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>

int main(void)
{
int table_size = 0; /* Table size */

printf("Enter the table size (from 2 to 12): ");
scanf("%d", &table_size);
if(table_size>12)
{
printf("\nTable size must not exceed 12 - setting to 12");
table_size = 12;
}
else if(table_size<2)
{
printf("\nTable size must be at least 2 - setting to 2");
table_size = 2;
}
int row = 0 ;
for( ;row<=table_size ; row++)
{
printf("\n");
int col = 0 ; /* Start new row */
for( ;col<=table_size ; col++)
{
if(row == 0) /* 1st row? */
{ /* Yes - output column headings */
if(col == 0) /* 1st column? */
printf(" "); /* Yes - no heading */
else
printf("|%4d", col); /*No - output heading */
}
else
{ /* Not 1st row - output rows */
if(col == 0) /* 1st column? */
printf("%4d", row); /* Yes - output row label */
else
printf("|%4d", row*col); /* No - output table entry */
}
}
if(row == 0 ) /* If we just completed 1st row */
{ /* output separator dashes */
printf("\n");
int col=0 ;
for( ;col<=table_size ; col++)
printf("_____");
}
}
printf("\n");
return 0;
}

9.2 ASCII码表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <ctype.h>

int main(void)
{
char ch = 0;
int i = 0 ; /* Character code value */
for( ;i<128 ; i++)
{
ch = (char)i;
if(ch%2==0)
printf("\n");
printf(" %4d %c",ch,(isgraph(ch) ? ch : ' '));
}
printf("\n");
return 0;
}

9.3 扩展ASCII码表

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
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <ctype.h>

int main(void)
{
char ch = 0;
int i = 0 ; /* Character code value */
for(; i<128 ; i++)
{
ch = (char)i;
if(ch%2==0)
printf("\n");
printf(" %4d",ch);
if(isgraph(ch))
printf(" %c",ch);
else
switch(ch)
{
case '\n':
printf(" newline",ch);
break;
case ' ':
printf(" space",ch);
break;
case '\t':
printf(" horizontal tab",ch);
break;
case '\v':
printf(" vertical tab",ch);
break;
case '\f':
printf(" form feed",ch);
break;
default:
printf(" ");
break;

}

}
printf("\n");
return 0;
}

9.4 猜迷游戏

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h> /* I added this for the exercise */
#include <ctype.h> /* I added this for the exercise */

int main(void)
{
int chosen = 15; /* The lucky number */
int guess = 0; /* Stores a guess */
int count = 3; /* The maximum number of tries */
const int MAXVALUE = 20; /* I added this for the exercise */
char answer = 'N'; /* I added this for the exercise */

printf("\nThis is a guessing game.");

/* I changed the following statement for the exercise */
printf("\nI have chosen a number between 1 and %d"
" which you must guess.\n", MAXVALUE);
do /* I added this for the exercise */
{ /* I added this for the exercise */

chosen = rand()*(MAXVALUE-1.0)/RAND_MAX +1.0; /* I added this for the exercise */
/* The calculation for chosen will be done as a floating-point calculation */
/* because of the 1.0 in the first parentheses forces this. The result of */
/* the calculation will be automatically converted to type int because */
/* chosen is of type int. */

count = 3; /* I added this for the exercise */
for( ; count>0 ; --count)
{
printf("\nYou have %d tr%s left.", count, count == 1 ? "y" : "ies");
printf("\nEnter a guess: "); /* Prompt for a guess */
scanf("%d", &guess); /* Read in a guess */

/* Check for a correct guess */
if (guess == chosen)
{
printf("\nYou guessed it!\n");
return 0; /* End the program */
}

/* Check for an invalid guess */
if(guess<1 || guess > 20)
printf("I said between 1 and 20.\n ");
else
printf("Sorry. %d is wrong.\n", guess);
}
printf("\nYou have had three tries and failed. The number was %d\n",
chosen);
printf("Do you want another go(Y or N)? "); /* I added this for the exercise */
scanf(" %c", &answer); /* I added this for the exercise */
} while(toupper(answer) == 'Y'); /* I added this for the exercise */
return 0;
}