一个C语言的基本教程—语句篇

文章目录

  • 6. 让我们来处理这些数据
      • (1).语句和代码块
      • (2).如果a不等于10的话...(if-else语句)
      • (3).如果情况不止一种...(else-if子句)
      • (4).如果情况还是不止一种...(switch-case语句)
      • (5).我想多猜两次啊!(while与for循环)
        • while循环
        • do-while循环
        • for循环
        • break语句与continue语句
      • 小结

6. 让我们来处理这些数据

前面提了这么多数据的基本操作,我们应该拿它们来做点什么事情。

(1).语句和代码块

  我们之前好像提到过{ }(花括号)和;(分号)这两个东西,他们在C语言中有着非常重要的作用
  花括号扩入的代码都处在相同的一个域之中,也就是说,花括号里的内容处于一个更小的范围中,我们把没有任何花括号的域叫做全局作用域,而花括号里则为一个局部作用域,花括号中还可以嵌套存在花括号,那就是局部作用域下的局部作用域,他们的范围越来越小,那么引入局部作用域的作用是什么呢?

#include 
int main()
{
    int a = 1;
    {
        int a = 2;
        printf("a = %d\n", a);
    }
    printf("a = %d\n", a);
    return 0;
}

试试运行这段代码,你会得到以下结果:
p7

  是不是很神奇,明明我在花括号中给a赋值为2了,之后的printf打印出来a的值还是1。那么我们就不难理解了,作用域主要作用于变量,根据变量所在的位置可以分为全局变量和局部变量。
  不过大家遇到更多的花括号应该还是在语句之中,例如马上我们就要提到的if-else语句,for循环语句,while循环语句,switch语句等等,我们会用花括号把一系列语句框起来,这样便于在满足条件时,执行所有我们需要C语言做的事情。
  而分号的作用比较简单,他代表一个语句的结束,例如我们上面说的

    int a = 2;

就有这个分号,他代表给a的赋值已经结束了。

(2).如果a不等于10的话…(if-else语句)

#include 
int main()
{
    int a = 10, input = 0;
    scanf("%d", &input);
    printf("You're right!\n");
    return 0;
}

  有这么一个简单到你不愿意玩的游戏,叫做猜数游戏,我们指定a为10,让大家来猜一猜,a是多少呢?当猜到10的时候,我们就要告诉玩家,你猜对了,但如果猜的不是10,那我们就要告诉他你猜错了,怎么做呢,如果像上面这么写代码,那无论猜多少都会输出"You’re right!"了,这样不太好吧。
  所以我们可以应用if-else语句来控制一下这个游戏的过程。我们改造代码如下:

#include 
int main()
{
    int a = 10, input = 0;
    scanf("%d", &input);
    if (input == a) {
        printf("You're right!\n");
    }
    else {
        printf("You're wrong! The correct answer is %d\n", a);
    }
    return 0;
}

  这样的语句就叫做if-else语句,它的基本结构如下:

if (condition) {
    // Some functions...
}
else {
    // Some functions...
}

  if后跟着一个圆括号框起来的条件语句,比如改造的猜数游戏中的input == a, 当这个条件成立的时候,执行if语句后面所跟的代码块里的内容,那么如果条件不成立,就执行else后的语句块中的内容。当然,if语句不一定要跟着else:

if (condition) {

}

  当condition成立的时候,执行语句,如果condition不成立,那就什么都不做,跳过这一段代码。
  当然,if语句也不一定要跟着代码块,如果只有一句代码的时候,这么写也是可以的:

if (condition) printf("...");

  这样的操作可以减少代码的行数,当然具体怎么写就要看个人的习惯了。

(3).如果情况不止一种…(else-if子句)

  如果说我们想让这个猜数游戏更加智能一点,玩家输入一个数字之后,如果猜错了,程序不仅告知猜错了,还可以告知猜大了还是小了,那怎么办呢?相信聪明的你已经想到了下面这样的办法:

#include 
int main()
{
    int a = 10, input = 0;
    scanf("%d", &input);
    if (input == a) {
        printf("You're right!\n");
    }
    else {
        if (input > a) {
            printf("%d is bigger than %d\n", input, a);
        }
        else {
            printf("%d is smaller than %d\n", input, a);
        }
        printf("You're wrong! The correct answer is %d\n", a);
    }
    return 0;
}

  这样就好多了,猜一个数字还能给出反馈,不过这样写有点繁琐,加入说我们有很多层判断,我们就需要一层一层的嵌套else和if,还记得之前说的吗,else和if之后都可以不需要代码块,所以我们可以把其他的情况改造为这样:

if (condition) {

}
else if (condition2) {

}
else {

}

  也就是说,毕竟我们之后的内容都存在if的代码块之中了,就可以不需要再多写一层花括号了,然后我们也可以用很多很多这样的else-if组成一个比较完善的条件语句,通过if和else if假定条件,如果都不成立的话就执行else中的内容,于是我们的猜数游戏就改造成立这个样子:

#include 
int main()
{
    int a = 10, input = 0;
    scanf("%d", &input);
    if (input == a) {
        printf("You're right!\n");
    }
    else if (input > a) {
        printf("%d is bigger than %d\n", input, a);
        printf("You're wrong! The correct answer is %d\n", a);
    }
    else{
        printf("%d is smaller than %d\n", input, a);
        printf("You're wrong! The correct answer is %d\n", a);
    }
    return 0;
}

(4).如果情况还是不止一种…(switch-case语句)

  在C语言中,除了if-else,还有一种switch-case语句也可以作为条件语句使用,它的基本结构是:

switch (expression) {
    case value1:
        // Some expression
        break;
    case value2:
    ...
    default:
}

  switch-case中的case子句的写法在C语言中可以说是非常少见的了,case后的冒号范围内可以执行多条语句,而在别的语句中,一般会使用花括号将他们框起来,在每一个case的最后一般会加上一个break语句,break的意思是跳出当前,switch-case的执行顺序比较奇怪,首先按照expression的值向各个case去匹配,匹配到了之后执行对应case中的语句执行完了之后又会继续执行下一个case的语句,尽管我们都知道expression的值已经不符合下一个case了,它会一直执行到最后一个case或碰到default才停止,所以这时候我们就需要使用break来避免它继续往下执行
  default子句是当expression在前面的所有case中一个都没有匹配,执行其中的内容,default子句的最后不需要加break

(5).我想多猜两次啊!(while与for循环)

  我们的游戏现在已经可以根据玩家猜的结果输出对应的字符串了,这很好,但是我们只给了玩家一次机会,这一次结束了程序立马消失了,一点体验都没有!那如果想要多猜一次,怎么办呢?有的人可能会这么做:

#include 
int main()
{
    int a = 10, input = 0, second = 0;
    scanf("%d", &input);
    if (input == a) {
        printf("You're right!\n");
    }
    else if (input > a) {
        printf("%d is bigger than a\n", input);
        scanf("%d", &input);
        second = 1;
    }
    else{
        printf("%d is smaller than a\n", input);
        scanf("%d", &input);
        second = 1;
    }

    if (second) { // 通过这个second变量判断是不是输入了第二次
        if (input == a) {
            printf("You're right!\n");
        }
        else if (input > a) {
            printf("%d is bigger than a\n", input);
        }
        else {
            printf("%d is smaller than a\n", input);
        }
    }
    printf("a = %d\n", a);
    return 0;
}

一个C语言的基本教程—语句篇_第1张图片

  你还还真是聪明,这回可以猜两次了,可如果我想猜三次,难道我还需要在写一组这样的if-else语句吗?既然每次都是差不多的,我们可以利用循环语句来帮助我们完成这样重复的部分。

while循环

  while循环的基本结构如下:

while (condition) {
    // Some functions here...
}

  和if语句的结构差不多的,这里的condition同样也是条件语句,当满足条件的时候就执行while后的代码块的内容,与if相同,后面如果只有一条语句,后面也可以不用加花括号了,就像下面这样:

#include 
int main()
{
	int a = 0;
	while (a < 100) a++;
	printf("a = %d\n", a);
	return 0;
}

  while循环一般用于知道循环条件,但是不能确定具体循环次数的情况,如果说,我们希望让玩家没有猜中数字之前,一直继续,直到猜中为止,我们把代码改造如下:

#include 
int main()
{
    int a = 10, input = 0;
    scanf("%d", &input);
    while (input != a) {
        if (input > a) {
            printf("%d is bigger than a\n", input);
            scanf("%d", &input);
        }
        else {
            printf("%d is smaller than a\n", input);
            scanf("%d", &input);
        }
    }
    printf("You're right!\n");
    printf("a = %d\n", a);
    return 0;
}

一个C语言的基本教程—语句篇_第2张图片

  太棒了!这样一来我们用很少的代码实现了一个可以一直继续的游戏!
  如果我们想要循环一直执行下去,即死循环,我们可以将condition设为1,即:

while (1) {
    // Some functions here...
}

  这样就可以一直执行下去了(如果你退不出程序了,在Windows下可以按Ctrl+C结束程序

do-while循环

  do-while循环与while循环类似,一般也用于不确定次数的循环,其结构如下:

do {
    // Some functions here...
} while (condtion);

  这个语句与while一样,具有while和condition,不过要执行的语句是写在do后的语句块中的,它与while循环最大的区别是,无论condition是否成立,do语句块的代码都会先执行一次,执行完了之后,再开始判断是否符合条件,它可以等价于:

A_function();
while (A_condtion) {
    A_function();
}

  不过记住哦,一般的语句如果以代码块的花括号" } “结尾,就不需要加分号,而do-while的while后没有语句块,所以需要加上分号。(当然也是存在” }; “结尾的东西的,之后我们提到的struct(结构体)和union(联合),以及你之后可能会学习的C++中的class(类),他们都是以” }; "结尾的)。

for循环

  新的问题,小明认为一个100以内的猜数游戏,如果6次都猜不中,那肯定是这个人太笨了,于是他决定只给玩家6次机会,那我们怎么实现这个限制次数呢?我们可以利用一个计数变量cnt:

#include 
int main()
{
    int a = 10, input = 0, cnt = 0;
    scanf("%d", &input);
    cnt++;
    while (cnt < 6) {
        if (input > a) {
            printf("%d is bigger than a\n", input);
        }
        else if (input < a) {
            printf("%d is smaller than a\n", input);
        }
        else {
            printf("You're right!\n");
            printf("a = %d\n", a);
            break; // 跳出循环,之后会说
        }
        cnt++;
        if (cnt <= 6) scanf("%d", &input);
    }
    if (cnt >= 6) {
        printf("Try again later!\n");
    }
    return 0;
}

  非常好,这样就限制了猜数的次数,不过有的时候你会发现这个cnt好像有点不太好确定,特别是在这个跳出循环的边界条件,当然,边界条件依旧是需要考量的问题,但是我们可以用for循环来减少一些麻烦,for循环的结构如下:

for (expression1; expression2; expression3) {
    // Some functions here...
}

  3个expression用分号相互隔开,三个表达式有着他们特定的含义:
    expression1:一般为循环开始时执行的内容,之后的循环中不会再执行
    expression2:for循环的判断条件,与while保持一致,如果满足这个条件则会继续进行循环
    expression3:每一次循环要执行的操作
  举个例子,比如说我们要求这样一个累加式:
∑ n = 1 100 n = ? \large\sum\limits_{n=1}^{100}n = ? n=1100n=?
我当然知道你可以很快告诉我答案,但是我想让计算机帮我算算看,那我们可以这么写:

#include 
int main()
{
    int i = 0, sum = 0;
    for (i = 1; i <= 100; i++) {
        sum += i;
    }
    printf("1 + 2 + ... + 100 = %d\n", sum);
    return 0;
}

p10

  相当快的,C语言帮助我们完成了这个计算过程,那我们也可以利用for循环来改造猜数游戏:

#include 
int main()
{
    int a = 10, input = 0, success = 0;
    for (int i = 0; i < 6; i++) {
        scanf("%d", &input); // 每次循环都猜一次数字
        if (input > a) {
            printf("%d is bigger than a\n", input);
        }
        else if (input < a) {
            printf("%d is smaller than a\n", input);
        }
        else {
            printf("You're right!\n");
            printf("a = %d\n", a);
            success = 1;
            break; // 跳出循环,之后会说
        }
    }
    if (!success) {
        printf("Try again later!\n");
    }
    return 0;
}

  非常好,你又学会了一个新的语句,不过在for循环的第一个表达式那里好像有点不一样,我们写的是(int i = 0; i < 6; i++),这和在外面int i = 0;然后再写(i = 0; i < 6; i++)有什么区别呢?还记得我们之前提过的作用域吗?for循环后的语句块也会形成一个更小的局部作用域,如果在for的圆括号中写入int i = 0,则是在for这个语句对应的代码块内定义一个变量i,且赋值为0,当for循环结束后,这个i就会因为代码块执行结束而消失,所以如果在循环时,没有将循环变量保存下来的需求时,可以在for循环的圆括号内声明变量,如果需要保存下来,那可就千万别这么做了

  for循环的运用还是有相当多的门道的,例如说我们需要顺着打印一串数字出来,可以这么写:

#include 
int main()
{
    for (int i = 0; i < 10; i++) {
        printf("%d\t", i);
    }
    printf("\n");
    return 0;
}

p11

  如果要倒着打印呢?那我们也让i倒过来:

#include 
int main()
{
    for (int i = 9; i >= 0; i--) { // 从9开始,依次递减,直到小于0停止
        printf("%d\t", i);
    }
    printf("\n");
    return 0;
}

p12

  其实第三个表达式也不一定只能是i+1,也可以像下面这样,打印一串奇数:

#include 
int main()
{
    for (int i = 1; i < 10; i+=2) {
        printf("%d\t", i);
    }
    printf("\n");
    return 0;
}

p13

循环变量也可以不止一个嘛!看看下面这个例子,我们可以打印一串点:

#include 
int main()
{
    for (int i = 1, j = 10; i <= 10; i++, j--) {
        printf("(%d, %d)\n", i, j);
    }
    printf("\n");
    return 0;
}

p14

  还有更多更多的操作,怎么样去用for循环,就全看你的想法了!

  for循环其实可以和while循环进行相互转换,一个如下的for循环:

for (expression1; expression2; expression3) {
    ...
}

实际上可以等价于

expression1;
while (expression2) {
    ...
    expression3;
}

  如果要用for写一个死循环,我们只要不填expression2或者让expression2永远达不到即可,不过这也是一个坑,有的时候我们可能会让循环变量i自增,但是循环结束的条件却是i >= 0,这样一来条件永远达不到,就会一直循环下去,下次写代码的时候可要记得检查一下哦

break语句与continue语句

break语句好像很常见啊,我们在switch,for和while中都见到了它的身影,break是一个终结循环的语句,当执行到它后,switch,for和while等语句都会立刻停止执行,然后跳出他们对应的代码块,举个例子:

#include 
int main()
{
    int a = 0, b = 0;
    while (a < 100) {
        a++;
        if (a == 50) {
            break;
            b = 1;
        }
    }
    printf("a = %d, b = %d\n", a, b);
    return 0;
}

  结果a等于50, b等于0,这便是因为在a等于50的时候,循环就被终止了,而终止是立刻执行的,所以之后的b = 1这句话也不会再执行了。
continue语句语句的意思是继续执行,当然不是说它什么都不做了,而是跳过当前这一次循环,但是不会跳出循环,例如我们希望求这样一个和:
∑ n = 1 40 n + ∑ n = 50 100 n = ? \large\sum\limits_{n=1}^{40} n + \sum\limits_{n=50}^{100} n = ? n=140n+n=50100n=?
  如果把for循环拆成两个,写上去多少有点冗余了,毕竟我们的C语言还是很快的,所以可以这么写:

#include 
int main()
{
    int i = 0, sum = 0;
    for (i = 1; i <= 100; i++) {
        if (i > 40 && i < 50) continue;
        sum += i;
    }
    printf("sum = %d\n", sum);
    return 0;
}

p15

  因为continue,达到条件之后当i处于41~49之间时,sum += i都没有被执行,我们简单加这么一行代码就解决了这个问题,真不错啊!

小结

  语句也真的是很重要的内容呢,我们可以通过各种控制语句的组合来操作数据,帮助我们完成许许多多的事情!当然,我知道可能大家听说过臭名昭著的goto语句,因为goto时常被滥用,如今的教程中已经不再建议使用,其实其余各种语句配合,也能实现goto的功能,所以我们就不再需要学习goto了(在C语言中)。在下一篇中我们将介绍C语言中一个非常重要的部分:函数

你可能感兴趣的:(一个C语言的基本教程,c语言,算法,c++)