C-study(五).2

逻辑运算符

连接两个完整的关系表达式。
&& 逻辑与,ab都为真时,a&&b的值真,其余时候假。
|| 逻辑或,ab都为假时,a||b的值假,其余时候真。
! 逻辑非、只需要一个运算对象,a真,!a假,a真,!a假。

逻辑表达式求值顺序:从左往右

&&和II 都是序列点,到&&或||之前副作用都会生效

一旦发现有使整个表达式为假的因素,会立即停止求值
第一个条件不成立时 && 之后的语句都直接跳过

#include <ctype.h>   //为isspace ()函数提供原型
#include <stdbool.h> //为bool、 true、 false提供定义
#define PERIOD '.'
#define STOP '|'         // 标记输入结束
    /*
    if(range>=90 &&range<=100) //不可以用90<=range<=100

    (ch != '"' | | ch != '\'') // 使用 || 两个条件有一个为真时为真,都为假时为假

    if (!(ch != '"')) // 使用 ! 条件为假时为真,为真时为假
    6 > 2 && 3 == 3 为真。 !(6 > 2 && 3 == 3) 为假。

    a>b&&b>c||b>d 相当于 ((a>b)&&(b>c))||(b>d)

    if(num!=0&&12/num==2)//&& 第一个表达式为假(num==0)时,会直接跳过后面的表达式,所以不会出现 除以0的情况
    x != 0 && 20 / x < 5只有在x是非零时才会对第2个表达式求值。

    while(x++<10&&x+y<20) //&&是序列点,可以保证在x+y的时候已经完成了自增操作*/

    char ch;
    int charcount = 0;
    while ((ch = getchar()) != PERIOD) // 读字符并检查是不是.
    {
        if (ch != '"' && ch != '\'') // &&:两个条件都为真时为真,不是"和'时记数
            charcount++;
    }
    printf("There are %d non-quote characters.\n", charcount);

    char c;              // 读入字符
    char prev;           // 读入的前一个字符
    long n_chars = 0L;   // 字符数
    int n_lines = 0;     // 行数
    int n_words = 0;     // 单词数
    int p_lines = 0;     // 不完整的行数
    bool inword = false; // 如果c在单词中,inword 等于true

    printf("Enter text to be analyzed (| to terminate) : \n");
    prev = '\n';                    // 用于识别完整的行
    while ((c = getchar()) != STOP) // getchar便于统计字符 读到|结束循环
    {
        n_chars++; // 统计字符

        if (c == '\n')
            n_lines++; // 统计行

        if (!isspace(c) && !inword) // 不是空格,不在单词内,则在单词开头标记inword,相当于inword==false
        {
            inword = true; // 开始一个新的单词
            n_words++;     // 统计单词
        }

        if (isspace(c) && inword) // 是空格,在单词内,说明一个单词结束,标记inword为false不在单词内
            inword = false;       // 打到单词的末尾

        prev = c; // 保存字符的值
    }
    if (prev != '\n')
        p_lines = 1; // 不完整的一行
    printf("characters = %ld,words = %d,lines = %d,", n_chars, n_words, n_lines);
    printf("partial lines = %d\n", p_lines);

条件运算符 ?:

唯一的三元运算符,每个运算对象都是一个表达式
expression1 ? expression2 :expression3

expression1为真(非0),表达式的值为expression2,否则为expression3

if else语句的便捷方式

#define COVERAGE 350        // 每罐油漆可刷的面积(单位:平方英尺)
//max=(a>b)?a:b; 取最大值
//(5>3)?1:2的值为 1。
//(3>5)?1:2的值为 2。
    int sq_feet;
    int cans;

    printf("Enter number of square feet to be painted : \n");
    while (scanf("%d", &sq_feet) == 1)
    {
        cans = sq_feet / COVERAGE;                   // int除法会被截断
        cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1; // 取余等于0说明刚刚好,不等于0说明多一桶

        printf("You need %d %s of paint . \n", cans, cans == 1 ? "can" : "cans"); // 如果值是1则打印can,否则打印cans
        printf("Enter next value (q to quit) : \n");
    }

按位运算符

~ :按位取反,一元运算符。
& :按位与运算符
| :按位或运算符
^ :按位异或运算符
<<:左移运算符,num<<n,num左移n位(*2n)。左边丢掉右边补0。
>> :右移运算符,num>>n,num右移n位(/2n)。右边丢掉左边补0。
在这里插入图片描述

int x = 2;   // 010
int y = 3;   // 011
// x & y = 2;   // 010
// y << x = 12; // 1100

其他运算符

sizeof运算符和size_t类型

sizeof:返回运算对象的字节大小,一元运算符
返回size_t类型的值,是语言定义的标准类型
%zd 或者%u %lu

// 使用C99新增的%zd转换说明--如果编译器不支持%zd, 请将其改成%u或%lu
int n = 0;
size_t intsize;// sizeof返回值,是无符号整型(的typedef别名),相当于 typedef unsigned int size_t
intsize = sizeof(int);//运算对象可以是类型或具体数据对象,是类型时必须加()
printf("n = %d,n has %zd bytes; all ints have %zd bytes. \n",
       n, sizeof n, intsize);//是具体对象()可以省略

() 强制类型转换运算符

(目标类型)

mice = 1.6+1.7;//3.3->3 先计算,在转换
mice = (int)1.6+(int)1.7;//先转换1+1

强制转换超出范围时依然会出错
显示选择合适的类型,强制类型转换指明转换类型,避免出现不正确的自动转换

逗号运算符 ,

性质:
保证从左往右求值,
是一个序列点,逗号左侧的副作用会在执行逗号右侧之前发生

逗号表达式的值是右侧项的值

const int FIRST_OZ = 46; // 2013邮资
const int NEXT_OZ = 20;  // 2013邮资
int ounces, cost;
printf(" ounces   cost\n");
/*
* 初始化表达式的逗号是两个值都可进行初始化
* 更新表达式的初始化可使两个值每次迭代都变化
* 
* x=(y=3,(z= ++y +2)+5)先给y赋3,y++为4,4+2为6赋给z,6+5赋给x
* i=5,500;相当于i=5;500;
* i=(5,500);相当于i=500;
*/
for (ounces = 1, cost = FIRST_OZ; ounces <= 16; ounces++, cost += NEXT_OZ)
    printf("%5d $%4.2f\n", ounces, cost / 100.0);

类型转换

在语句和表达式中应使用类型相同的变量和常量

基本转换规则

1、升级
unsigned和signed的char和short会被自动转换为int
如果short和int的大小相同,unsigned short 比int大时会自动转换为unsigned int
float会自动转换为double

2、涉及两种类型的运算,两个值会被分别转为两个类型的更高级别

3、级别从高到低:
long double
double
float
unsigned long long
long long
unsigned long
long
unsigned int(当long=int,unsigned int >long)
int
当long和int大小相同时,unsigned int比long级别高

4、赋值时计算的最终结果会被转换成被赋值变量的类型,包括升级和降级

5、函数参数传递,char和short被转换为int,float被转换为double,函数原型会覆盖升级

降级可能会导致放不下整个数字
整型转换为无符号整型,额外的位被忽略,eg:目标类型是8位无符号整型,原始值求256模

char ch;
int i;
float fl;
fl = i = ch = 'C';
/*
1字节的ASCII存储在ch中
转换为ASCII中C对应的整数67,四字节存储在i中
67转换为浮点数存储在fl中
*/
printf("ch=%c,i=%d,fl=%2.2f\n", ch, i, fl);
ch = ch + 1;       /*转换成整数67+1,结果是4字节整数68然后截断1字节存在ch*/
i = fl + 2 * ch;   /*ch转换为4字节整数68,乘以2,转换为浮点数和fl相加,转换为int存储在i*/
fl = 2.0 * ch + i; /*ch转换为浮点数,乘以2,把i转换为浮点数,相加存在fl*/
printf("ch=%c,i=%d,fl=%2.2f\n", ch, i, fl);
ch = 1107; /*超出范围取256模*/
printf("Now ch = %c\n", ch);
ch = 80.89; /*截断*/
printf("Now ch = %c\n", ch);

带参函数

void pound(int n); // ANSI函数原型声明,表明该函数接受一个 int 类型的参数 ,且没有返回值

const int S_PER_M = 60;         // 1分钟的秒数
const int S_PER_H = 3600;       // 1小时的秒数
const double M_PER_K = 0.62137; // 1公里的英里数
	int times = 5;
    char ch = '!'; // ASCII码是33
    float f = 6.0f;
    pound(times); // int 类型的参数,把实参5传递给函数,把5赋值给形参,即把times的值拷贝给函数中的新变量n
    pound(ch);    // 和pound((int)ch);相同,根据函数声明自动转换
    pound(f);     // 和pound((int)f);相同,如果函数声明没提供参数类型,则不会转换,只会自动升级为double,使用时错误

    double distk, distm; // 跑过的距离(分别以公里和英里为单位 )
    double rate;         // 平均速度(以英里/小时为单位)
    int min, sec;        // 跑步用时(以分钟和秒为单位 )
    int time;            // 跑步用时(以秒为单位)
    double mtime;        // 跑1英里需要的时间,以秒为单位
    int mmin,msec;       // 跑1英里需要的时间,以分钟和秒为单位
    printf("This program converts your time for a metric race\n");
    printf("to a time for running a mile and to your average\n");
    printf("speed in miles per hour.\n");
    printf("Please enter, in kilometers, the distance run, \n");
    scanf("%lf", &distk); // %lf 表示读取一个 double 类型的值
    printf("Next enter the time in minutes and seconds,\n");
    printf("Begin by entering the minutes.\n");
    scanf("%d", &min);
    printf("Now enter the seconds,\n");
    scanf("%d", &sec);
    time = S_PER_M * min + sec;    // 把时间转换成秒
    distm = M_PER_K * distk;       // 把公里转换成英里
    rate = distm / time * S_PER_H; // 英里/秒X秒/小时=英里/小时
    mtime = (double)time / distm;  // 时间/距离 =跑1英里所用的时间
    mmin = (int)mtime / S_PER_M;   // 求出分钟数
    msec = (int)mtime % S_PER_M;   // 求出剩余的秒数
    printf("You ran %1.2f km (%1.2f miles) in %d min,%d sec.\n", distk, distm, min, sec);
    printf("That pace corresponds to running a mile in %d min,", mmin);
    printf("%d sec.\nYour average speed was %1.2f mph,\n", msec, rate);

void pound(int n)
/*ANSI 风格函数头
返回值类型 函数名(返回值类型 形参名) ,不需要参数或返回值时用void,
括号内就包括形参变量的声明,形参的变量名是函数私有的,不会和其他处相同名称发生冲突
实际函数调用传递的值为实参*/
{ 
    while (n-- > 0)
        printf("#");
    printf("\n");
}

相关推荐

  1. 2024/5/2 C++

    2024-07-11 22:32:05       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 22:32:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 22:32:05       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 22:32:05       58 阅读
  4. Python语言-面向对象

    2024-07-11 22:32:05       69 阅读

热门阅读

  1. 使用Ultralytics YOLO进行模型验证

    2024-07-11 22:32:05       23 阅读
  2. 数据库(mysql)忘记密码解决办法

    2024-07-11 22:32:05       21 阅读
  3. GET正常,POST获取不到数据

    2024-07-11 22:32:05       20 阅读
  4. scoop安装在D盘

    2024-07-11 22:32:05       22 阅读
  5. 华为机考真题 -- 密码解密

    2024-07-11 22:32:05       19 阅读
  6. 设计模式——单例模式

    2024-07-11 22:32:05       21 阅读
  7. C# 反射

    2024-07-11 22:32:05       19 阅读
  8. Ubuntu 软件源404not found原因及解决办法

    2024-07-11 22:32:05       17 阅读
  9. 拓扑排序(算法篇)

    2024-07-11 22:32:05       23 阅读
  10. SQL 存储过程

    2024-07-11 22:32:05       24 阅读
  11. 大数据面试题之数据湖

    2024-07-11 22:32:05       21 阅读