printf("sum is %d, length of array is %d", sum, len); }
intmain(void) {
int len = 10; int a[5];
for (int i = 0; i < 5; i++) { scanf("%d", &a[i]); }
sum_array(a, len / 2);
return0; } // 我们输入:1 2 3 4 5 // 输出: sum is 15, length of array is 5
我们将上面的程序改写为:
#include<stdio.h>
voidsum_array(int a[], int i) {
int len = i; int sum = 0;
for (int i = 0; i < len; i++) { sum += a[i]; if (i == len - 1) { i += 5; } }
printf("sum is %d, length of array is %d", sum, i); }
intmain(void) {
int i = 10; int a[5];
for (int i = 0; i < 5; i++) { scanf("%d", &a[i]); }
sum_array(a, i / 2);
return0; } // 我们输入:1 2 3 4 5 // 输出: sum is 15, length of array is 5
用简单的描述一下作用域和生存期:
作用域:限定某个名字的可用性的代码范围就是该名字的作用域
生存期:变量值存在的时间
块:一个花括号{}就是一个块。
通常来说,变量的作用域和生存期都是在一个块内。
上面第二个程序的执行结果和第一个完全一样,我们现在来一步一步分析一下:
// 新的块(函数)中,i 是一个新的变量,mian 函数中的 i 在这里不再生效(作用域和生存期失效) // 这个 i 就是实参的值,也就是 5 voidsum_array(int a[], int i) {
int len = i; int sum = 0; // for 语句内 i 的情况和 mian 函数中的一样 for (int i = 0; i < len; i++) { sum += a[i]; // 为了证明 for 语句内的 i 和外面形参 i 完全不同,在即将退出循环时,我将 i 增加了 5, // 所以退出循环时里面的 i 的值为 10 if (i == len - 1) { i += 5; } } // 最后输出的 i 依然是形参 5 printf("sum is %d, length of array is %d", sum, i); }
intmain(void) {
int i = 10; int a[5]; //在 for 语句这个块内重新声明的 i ,这个 i 和上面的 i 是完全不同的变量。 // 修改 for 语句内的 i 不会影响外面的 i ,虽然外面的 i 在 for 语句内依然生效,但是可以理解为里面的 i 将其覆盖了 // 正所谓谁的地盘谁做主 for (int i = 0; i < 5; i++) { scanf("%d", &a[i]); } // for 语句执行结束后,里面的 i 被自动回收了。i 不再生效。 // 所以下面的 i 就是外部的 i,也就是 10 sum_array(a, i / 2);
我们可以用数组来模拟这种数据结构。用一个变量 top 标记当前栈顶的位置。如果数据压栈,则将 top 自增;如果数据出栈,则将 top 自减。我们需要写很多函数来实现这种数据结构,比如 压栈,出栈,判满,判空等等。我们可以将 表示栈顶的变量 top 和 表示栈的数组定义为全局变量。这里有一段代码(不是完整的程序):
#include<stdbool.h>// C99 only
#define STACK_SIZE 100 intstack[STACK_SIZE]; int top = -1;
此时,print_all_row 打印的不是 10 行,而是 1 行。第一次调用 print_one_row 函数返回时, i 的值将为 11 ,不满足 for 的控制表达式,循环退出。
所以,全局变量建议不要使用。
程序:猜数
程序产生一个 1 ~ 100 的随机数,用户尝试用尽可能少的次数猜出这个数。程序运行如下:
Guess the secret number between 1 and 100. A new number has been chosen. Enter guess:55 Too low; try again. Enter guess:65 Too high; try again. Enter guess: 60 You won in 3 guesses! Play again?(Y/N) n
printf("Guess the secret number between 1 and 100.\n"); do { generate_secret_number(); printf("A new number has been chosen.\n"); read_guesses(); printf("Play again?(Y/N)"); scanf(" %c", &command);// 注意 %c 前的空格,这很重要 printf("\n"); } while (command == 'y' || command == 'Y');
/**************************************************************************** * * generate_secret_number: Initilizes the random number generator using the * time of day.Randomly selects a number between * 1 and MAX_NUMBER and stores it in secret_number * *****************************************************************************/
voidgenerate_secret_number() {
srand((unsigned)time(NULL));
secret_number = rand() % MAX_NUMBER + 1; }
/***************************************************************** * * read_guesses:Repeatedly reads user guesses and gives hints * When guess is right,prints the total number of * guesses and returns * ******************************************************************/
voidread_guesses() {
int guess, count = 0;
for (;;) { printf("Enter guess: "); scanf("%d", &guess); count++; if (guess > secret_number) { printf("Too high; try again\n"); } elseif (guess < secret_number) { printf("Too low; try again.\n"); } else { printf("You won in %d guesses!\n\n", count); return; } }
printf("Guess the secret number between 1 and 100.\n"); do { secret_number = generate_secret_number(); printf("A new number has been chosen.\n"); read_guesses(secret_number); printf("Play again?(Y/N)"); scanf(" %c", &command); printf("\n"); } while (command == 'y' || command == 'Y');
// 同花是五张牌相同花色 for (i = 0; i < SUIT; i++) { if (card->numSuit[i] == 5) card->flush = true; }
// 顺子是五张连续的牌,中间不能隔断 i = 0; // 找到数组种第一张存在的牌 while (card->numRank[i] == 0) i++; count = 0; for (; i < RANK && card->numRank[i] != 0; i++) { count++; } // 顺子必须是五张 if (count == CARD) { card->straight = true; return; // 顺子肯定不是对子 }
for (i = 0; i < RANK; i++) { if (card->numRank[i] == 4) card->four = true; if (card->numRank[i] == 3) card->three = true; if (card->numRank[i] == 2) ++card->pair; } }
voidprintResult(CardType* card) {
if (card->flush && card->straight) printf("Stright flush\n"); elseif (card->four) printf("Four of a kind\n"); elseif (card->three && card->pair == 1) printf("Full house\n"); elseif (card->flush) printf("flush\n"); elseif (card->straight) printf("straight\n"); elseif (card->three) printf("Three of a kind\n"); elseif (card->pair == 2) printf("Two pairs\n"); elseif (card->pair == 1) printf("pair\n"); else printf("High card\n"); printf("\n\n"); }