C-study(七)

if语句

通过测试条件判断执行哪些语句,所有非零值都是true

if

单条语句不强制使用大括号,出现长语句使用大括号可提高可读性

复合语句强制使用大括号

通用形式

if(expression) // 通常是关系表达式,表达式为0则为假,非0为真
statement // 可以是简单句或复合句,复合语句必须有大括号

如果对expression求值为真,则执行statement,否则跳过statement执行之后的代码;满足条件只执行一次

分支(选择)语句。相当于交叉点,程序要在两条分支中选择执行

const int FREEZING = 0;
float temperature;
int cold_days = 0;
int all_days = 0;

printf("Enter the list of daily low temperatures.\n");
printf("Use Celsius, and enter q to quit. \n");

while (scanf("%f", &temperature) == 1) // 读到非数字字符是退出循环
{
    all_days++;
    if (temperature < FREEZING) // 如果表达式为真(读取值小于0)则执行递增,否则跳过。
        cold_days++;            // 简单语句
}
if (all_days != 0) // 表达式为真(有数据)就打印
    printf("%d days total : %.1f%% were below freezing.\n",
           all_days, 100.0 * (float)cold_days / all_days); // 避免整数除法,先强制转换为浮点数再除
if (all_days == 0)                                         // 表达式为真(没数据)就打印
    printf("No data entered ! \n");

 //  if(joe>ron)
 //  {//复合语句,整个if语句仍然被视为一条语句
 //      joecash++;
 //      pprintf("You lose,Ron\n");
 //  }

if else

在多条语句中做选择
一对if else之间的多条语句必须用{}

if(expression)
statement1
else
statement2

如果对expression求值为真,则执行statement1,否则跳过statement1执行statement2

// 两个if相当于 if else
if (all_days != 0) // 为真执行这一句(打印温度数据),为假执行下一句(打印警告信息)
    printf("%d days total : %.1f%% were below freezing.\n",
           all_days, 100.0 * (float)cold_days / all_days);
else
    printf("No data entered ! \n"); ​​

​​​​在这里插入图片描述

else if

if(expression)
statement1

else if (expression1)
statement2

else if (expression2)
statement3

else
statement4

如果对expression求值为真,则执行statement1,否则判断expression1是否为真,为真执行 statement2,否则判断expression2是否为真,为真执行 statement3,否则执行 statement3

#include <stdio.h>
#define RATE1 0.13230                                       // 首次使用360 kwh的费率 使用符号常量表示不同的费率和费率分界点
#define RATE2 0.15040                                       // 接着再使用108 kwh的费率
#define RATE3 0.30025                                       // 接着再使用252 kwh的费率
#define RATE4 0.34025                                       // 使用超过720kwh的费率
#define BREAK1 360.0                                        // 费率的第1个分界点
#define BREAK2 468.0                                        // 费率的第2个分界点
#define BREAK3 720.0                                        // 费率的第3个分界点
#define BASE1 (RATE1 * BREAK1)                              // 使用360kwh 的费用
#define BASE2 (BASE1 + (RATE2 * (BREAK2 - BREAK1)))         // 使用468kwh的费用
#define BASE3 (BASE1 + BASE2 + (RATE3 * (BREAK3 - BREAK2))) // 使用720kwh的费用
 	double kwh;  // 使用的千瓦时
    double bill; // 电费

    printf("Please enter the kwh used. \n");
    scanf("%lf", &kwh); //%lf 对应double类型
    if (kwh <= BREAK1)  // 根据kwh的值在3个公式之间选择一个,只有在当前条件不成立的条件下执行下一个else
        bill = RATE1 * kwh;
    else if (kwh <= BREAK2) // 360~468 kwh
        bill = BASE1 + (RATE2 * (kwh - BREAK1));
    else if (kwh <= BREAK3) // 468~720 kwh
        bill = BASE2 + (RATE3 * (kwh - BREAK2));
    else // 超过720 kwh
        bill = BASE3 + (RATE4 * (kwh - BREAK3));
    printf("The charge for %.1f kwh is $%1.2f.\n", kwh, bill);

if和else配对规则

没有花括号,else和离得最近的if匹配,除非if被花括号括起来,忽略缩进

在这里插入图片描述

嵌套if

测试模型:

提示用户输入数字
当scanf()返回值为1
分析该数并报告结果
提示用户继续输入

#include <stdbool.h>    // bool代替 _Bool类型,用true和 false代替1,0
 	unsigned long num; // 待测试的数
    unsigned long div; // 可能的约数
    bool isPrime;      // 素数标记,循环开始时设置为真,进入if之后设置为假,循环结束后判断真假继而判断是否进入if

    printf("Please enter an integer for analysis; ");
    printf("Enter q to quit. \n");
    while (scanf("%lu", &num) == 1)
    {
        for (div = 2, isPrime = true; (div * div) <= num; div++) // 检查2和根号num之间的数字,是否能被num整除,每次输入新值时都把isPrime设置为true
        {
            if (num % div == 0) // 如果可以整除,是约数,则打印
            {
                if (div * div != num)
                    printf("%lu is divisible by %lu and %lu.\n", num, div, num / div);
                else // 如果是平方,只打印一个约数
                    printf("%lu is divisible by %lu.\n", num, div);
                isPrime = false; // 标记该数不是素数
            }
        }
        if (isPrime)
            printf("%lu is prime . /n", num);
        printf("Please enter another integer for analysis; ");
        printf("Enter q to quit. \n");
    }

    printf("Bye . \n");

continue 和 break

正常情况:在进入循环之后,在下一次循环测试前执行完循环体内所有语句

continue break goto可以使程序流的一处跳转到另一处

continue:跳过本次迭代的剩余部分,并开始下一轮迭代(先执行更新语句),在嵌套循环内只影响包含该语句的内层循环,可以用于所有的循环

break:终止包含它的循环,并继续执行下一阶段,在嵌套循环内只影响包含他的当前循环,所有的循环和switch都可以使用

在这里插入图片描述

//continue
const float MIN = 0.0f;
const float MAX = 100.0f;
float score;
float total = 0.0f;
int n = 0;
float min = MAX;
float max = MIN;

printf("Enter the first score (q to quit) : ");
while (scanf("%f", &score) == 1) // 循环读取输入,直到用户输入非数值数据
{
    if (score < MIN || score > MAX) // 筛选出无效的分数
    {
        printf("%0.1f is an invalid value. Try again: ", score);
        continue;
        /*跳转至while循环的测试条件,跳过处理有效输入部分的代码,开始下一轮循环,继续读取,更简洁,
         * 可以用if else 代替,continue跳过的部分都放在else 或者把if的条件反过来
         * while(getchar()!='\n'); 循环读取并丢弃输入的数据直到行末尾,单独的分号不容易注意到加一个continue 做占位符,提高代码可读性
         *加continue是为了简化代码,如果加上会复杂化代码就不用
         *continue 用在while 跳过之后执行下一条是循环测试条件
         *continue 用在for  跳过之后执行下一条是更新表达式(递增),然后再是测试表达式*/
    }
    printf("Accepting %0.1f:\n", score);
    min = (score < min) ? score : min;
    max = (score > max) ? score : max;
    total += score;
    n++;
    printf("Enter next score (q to quit) : ");
}

if (n > 0)
{
    printf("Average of %d scores is %0.1f.\n", n, total / n);
    printf("Low = %0.1f,high = %0.1f\n", min, max);
}
else
    printf("No valid scores were entered. \n ");


//break
float length, width;
printf("Enter the length of the rectangle : \n");
while (scanf("%f", &length) == 1)
{
    printf("Length = %0.2f : \n", length);
    printf("Enter its width : \n");
    if (scanf("%f", &width) != 1)
        break;
    /*可以用while(scanf("%f %f",&length,&width)==2)用break可以方便显示用户输入的值
     * 加break为了简洁,加上导致不简洁就不加
     * 执行完break,结束当前循环,执行循环下一句,嵌套只跳出当前循环,外层循环需要另一个break
     */
    printf("Width = %0.2f : \n", width);
    printf("Area = %0.2f : \n", length * width);
    printf("Enter the length of the rectangle : \n");
}

//嵌套循环break
int p, q;
scanf("%d", &p);
while (p > 0)
{
    printf("%d\n", p);
    scanf("%d", &q);
    while (q > 0)
    {
        printf("%d\n", p * q);
        if (q > 100)
            break; // 跳出内层循环
        scanf("%d", &q);
    }
    if (q > 100)
        break; // 跳出外层循环
    scanf("%d", &p);
}

switch case default break

多选;根据expression的值跳转到相应的case,执行剩下的所有语句,除非到break语句跳出switch语句;

expresssion 和case标签都必须是整数值,常量或常量表达式

没有case匹配,转至default,否则结束

多个case可以共用一个语句

switch无法根据浮点类型选择无法根据变量在某范围内决定程序流去向,这两种情况使用if else更合适

适用于多个选择,2个选择及更少时使用if else 更简洁
在这里插入图片描述

char ch;
printf("Give me a letter of the alphabet,and I will give ");
printf("an animal name \nbeginning with that letter.\n");
printf("Please type in a letter; type # to end my act.\n");
while ((ch = getchar()) != '#')
{
    if ('\n' == ch) // 换行,跳过执行下一次循环,重新读字符
        continue;
    /*只能用于循环中,
     *如果switch在循环中,continue可以作为switch的一部分,跳出循环的剩余部分(包括switch的其他部分)*/
    if (islower(ch)) /*只接受小写字母*/
        switch (ch)  // 对圆括号里的表达式求值
        {            // 算一条语句
        case 'a':    // 扫描标签列表直到发现匹配值,标签必须时整数类型或者char类型的常量或常量表达式,不可以是范围
            printf("argali, a wild sheep of Asia\n");
            break; // 让程序离开switch,如果没有break,会从匹配标签开始执行到switch末尾或者有break的地方
        case 'b':
            printf("babirusa, a wild pig of Malay\n");
            break;
        case 'c':
            printf("coati, racoonlike mammal \n");
            break;
        case 'd':
            printf("desman, aquatic,molelike critter\n");
            break;
        case 'e':
            printf("echidna, the spiny anteater\n");
            break;
        case 'f':
            printf("fisher, brownish marten\n");
            break;
        default: // 没有匹配标签时执行,没有default直接执行switch之后的语句
            printf("That's a stumper! \n");
            /*switch结束*/
        }
    else
        printf("I recognize only lowercase letters.\n");
    while (getchar() != '\n')
        continue; /*每次只读第一个字符,每一行的其他字符都丢掉,跳过输入行的剩余部分*/
    printf("Please type another letter or a # . \n");
    /*while循环结束*/
}
printf("Bye!");

//多重标签
char ch;
int a_ct, e_ct, i_ct, o_ct, u_ct;
a_ct = e_ct = i_ct = o_ct = u_ct = 0;
printf("Enter some text; enter # to quit. \n");
while ((ch = getchar()) != '#')
{
    switch (ch)
    {
    case 'a': // 多重标签,没有关联break,直接执行下一条语句
    case 'A':
        a_ct++;
        break;
    case 'e':
    case 'E':
        e_ct++;
        break;
    case 'i': // 如果是i,匹配到当前,一直执行到下一条break
    case 'I':
        i_ct++;
        break;
    case 'o':
    case 'O':
        o_ct++;
        break;
    case 'u':
    case 'U':
        u_ct++;
        break; // 后面接default,break可以省略,加上避免添加新case时遗漏break
    default:
        break;
        // switch结束
    }
}
// while循环结柬
printf("number of vowels:A  E   I   O   U\n");
printf("%4d %4d %4d %4d %4d\n", a_ct, e_ct, i_ct, o_ct, u_ct);

goto

goto part2; //goto 标签名,标签名遵守变量命名规则,跳转至相应标签语句

part2: printf(“Redfined analysis:\n”);//冒号用于分割标签和标签语句,goto跳转或者正常流程到这里都会执行

goto的大部分功能都可以被现有语法代替,除了从嵌套循环中跳出

字符输入输出函数

不需要转换说明,只处理字符,通常定义在stdio.h

stdio.h

getchar

不带参数,从输入队列中返回下一个字符

ch=getchar(); //相当于 scanf(“%c”,&ch);

putchar

打印字符参数

putchar(ch); //相当于printf(“%c”,ch);

ctype.h

包含专门处理字符的函数原型

接受一个字符作为参数,如果属于特殊类别,则返回真,否则返回0

tolower(ch);不会修改原始的参数,只会返回已修改的值

ch=tolower(ch); //把ch转换为小写字符

在这里插入图片描述

include <stdio.h>
#define SPACE ' ' // SPACE表示单引号-空格-单引号
    char ch;
    ch = getchar(); // 读取一个字符
    while (ch != '\n')
    /* 当一行未结束时  相当于while((ch=getchar())!='\n')
     * !=左侧运算对象为(ch=getchar()),要对该表达式求值先调用getchar(),然后把函数返回值赋值给ch
     * 赋值表达式的值是赋值运算符左侧运算对象的值,即ch
     * 即为 ch!=' '
     * !=优先级比=高,所以括号括起来ch=getchar()
     */
    {
        if (ch == SPACE) // 留下空格 使用!isalpha(ch)判断不是字符
            putchar(ch); // 该字符不变
        else
            putchar(ch + 1); // 改变其他字符,字符实际作为整数存储,转换为int类型计算
        ch = getchar();      // 获取下一个字符
    }
    putchar(ch); // 打印换行符

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值