• C语言基础学习day04


    运算符、表达式和语句

    循环简介

    #include <stdio.h>
    #define ADJUST 7.31
    int main(void)
    {
        const double SCALE=0.333;
        double shoe,foot;
        printf("Shoe size (men's) foot length
    ");
        shoe=3.0;
        while(shoe<18.5)
        {
            foot=SCALE*shoe+ADJUST;
            printf("%10.1f %15.2f inches
    ",shoe,foot);
            shoe=shoe+1.0;
        }
        printf("if the shoe fits,wear it.
    ");
        
        return 0;
        
    }

    当程序第一次到达while循环时,会检查圆括号中的条件是否为真,条件为真,程序进入块中继续执行,把尺码转换成英寸

    然后打印计算的 结果。下一条语句把 shoe增加1.0,使shoe的值为4.0:

    shoe = shoe + 1.0;
    此时,程序返回while入口部分检查条件。

    为何要返回while的入口部分?因为上面这条语句的下面是右花括号(}),代码使用一对花括号 ({})来标出while循环的范围。花括号之间的内容就是要被重复执行的内 容。花括号以及被花括号括起来的部分被称为块(block)。现在,回到程序中。因为4小于18.5,所以要重复执行被花括号括起来的所有内容(用计算机术语来说就是,程序循环这些语句)。该循环过程一直持续到shoe的值为19.0。此时,由于19.0小于18.5,所以该条件为假:
    shoe < 18.5
    出现这种情况后,控制转到紧跟while循环后面的第1条语句。该例中, 是最后的printf()语句。

    基本运算符

    赋值运算符:=

    在编写代码时要记住,=号左侧的项必须是一个变量名。实际上,赋值运算符左侧必须引用一个存储位置。最简单的方法就是使用变量名。不过,后面章节还会介绍“指针”,可用于指向一个存储位置。概括地说,C 使用可修改的左值(modifiable lvalue) 标记那些可赋值的实体。

    “项”(如,赋值运算符左侧的项)的就是运算对象(operand)。运算对象是运算符操作的对象。例如,可以把吃汉堡描述 为:“吃”运算符操作“汉堡”运算对象。类似地可以说,=运算符的左侧运算对象应该是可修改的左值

    #include<stdio.h>
    int main(void)
    {
        int jane,tarzan,cheeta;
        cheeta =tarzan =jane =68;
        printf("                  cheeta  tarzan  jane
    ");
        printf("first round score %4d %8d %8d
    ",cheeta,tarzan,jane);
        
        return 0;
    }

    许多其他语言都会回避该程序中的三重赋值,但是C完全没问题。赋值 的顺序是从右往左:首先把86赋给jane,然后再赋给tarzan,最后赋给 cheeta

    运行结果:

    cheeta tarzan jane
    first round score 68 68 68

    加法运算符:+

    加法运算符(addition operator)用于加法运算,使其两侧的值相加。例如,语句:

    printf("%d", 4 + 20);

    打印的是24,而不是表达式
    4 + 20
    相加的值(运算对象)可以是变量,也可以是常量。

    乘法运算符:*

    该程序打印数字1~20及其平方

    #include<stdio.h>
    int main(void)
    {
        int num=1;
        while (num <21)
        {
            printf("%4d%6d
    ",num,num*num);
            num=num+1;
        }
        return 0;
    }
    #include<stdio.h>
    #define SQUARES 64
    int main(void) 
    {
        const double CROP =2E16;
        double current,total;
        int count =1;
        printf("square   grains   total    ");
        printf("fraction  of  
    ");
        printf("added     grain     ");
        printf("world             total
    ");
        total=current=1.0;
        printf("%4d %13.2e %12.2e %12.2e
    ", count,current,total,total/CROP);
    
        while (count<SQUARES)
        {
            count=count+1;
            current=2.0*current;
            total=total+current;
            printf("%4d %13.2e %12.2e %12.2e
    ",count,current,total,total/CROP);
        } 
        printf("That's all.
    ");
        
        return 0;
    }

    当遇到error: stray '241' in program错误的解决方法:该错误是指源程序中有非法字符,需要将非法字符去掉。一般是由于coder使用中文输入法或者从别的地方直接复制粘贴代码造成的。代码中出现了中文空格,中文引号, 各种中文标点符号都会出现,简单修改一下就OK了

    除法运算符:/

    #include<stdio.h>
    int main(void)
    {
        printf("integer division:5/4 is %d
    ",5/4);
        printf("integer division:6/3 is %d
    ",6/3);
        printf("integer division:7/4 is %d
    ",7/4);
        printf("floating division: 7./4. is %1.2f
    ",7./4.);
        printf("mixed division:7./4 is %1.2f
    ",7./4);
        return 0;
    
    }

    运行结果:

    注意,整数除法会截断计算结果的小数部分(丢弃整个小数部分),不 会四舍五入结果。混合整数和浮点数计算的结果是浮点数。

    实际上,计算机不能真正用浮点数除以整数,编译器会把两个运算对象转换成相同的类型。 本例中,在进行除法运算前,整数会被转换成浮点数。

    C99标准以前,C语言给语言的实现者留有一些空间,让他们来决定如何进行负数的整数除法。一种方法是,舍入过程采用小于或等于浮点数的最大整数。当然,对于3.8而言,处理后的3符合这一描述。但是-3.8 会怎样? 该方法建议四舍五入为-4,因为-4 小

    于-3.8.但是,另一种舍入方法是直接丢 弃小数部分。这种方法被称为“趋零截断”,即把-3.8转换成-3。在C99以前, 不同的实现采用不同的方法。但是C99规定使用趋零截断。所以,应把-3.8 转换成-3

    运算符优先级

    #include<stdio.h>
    int main(void)
    {
        int top,score;
        top=score=-(2+5)*6+(4+3*(2+3));
        printf("top = %d,score = %d
    ",top,score);
        return 0;
    }

    输出结果:-23

    sizeof运算符和size_t类型

    sizeof运算符以字节为单 位返回运算对象的大小(在C中,1字节定义为char类型占用的空间大小。过去,1字节通常是8位,但是一些字符集可能使用更大的字节

    #include<stdio.h>
    int main(void)
    {
        int n = 0;
        size_t intsize;
        intsize = sizeof(int);
        printf("n = %d, n has %zd bytes; all ints have %zd bytes.
    ",n,sizeof n,intsize);
        
        return 0;
    }

    运行结果:

    n = 0, n has 4 bytes; all ints have 4 bytes.

    C 语言规定,sizeof 返回 size_t 类型的值。这是一个无符号整数类型, 但它不是新类型,size_t是语言定义的标准类型

    C有一个 typedef机制,允许程序员为现有类型创建别名。例如,

    typedef double real;

    这样,real就是double的别名。现在,可以声明一个real类型的变量:
    real deal; // 使用typedef

    编译器查看real时会发现,在typedef声明中real已成为double的别名,于是把deal创建为double 类型的变量。类似地,C 头文件系统可以使用 typedef 把 size_t 作为 unsigned int 或unsigned long的别名。这样,在使用size_t类型 时,编译器会根据不同的系统替换标准类型

    求模运算符:%

    负数求模如何进行?C99规定“趋零截断”之前,该问题的处理方法很 多。但自从有了这条规则之后,如果第1个运算对象是负数,那么求模的结 果为负数;如果第1个运算对象是正数,那么求模的结果也是正数:
    11 / 5得2,11 % 5得1
    11 / -5得-2,11 % -2得1
    -11 / -5得2,-11 % -5得-1
    -11 / 5得-2,-11 % 5得-1
    如果当前系统不支持C99标准,会显示不同的结果。实际上,标准规 定:无论何种情况,只要a和b都是整数值,便可通过a - (a/b)*b来计算a%b。

    例如,可以这样计算-11%5:

    -11 - (-11/5) * 5 = -11 -(-2)*5 = -11 -(-10) = -1

     递增运算符:++

    该运算符以两种方式出现:

    第1种方式,++出现在其作用的变量前面, 这是前缀模式;

    第2种方式,++出现在其作用的变量后面,这是后缀模式。

    #include<stdio.h>
    int main(void)
    {
        int a=1,b=1;
        int a_post,pre_b;
        a_post=a++;//后缀递增 
        pre_b=++b;//前缀递增
        printf("a   a_post    b   pre_b   
    ");
        printf("%1d  %5d  %5d  %5d
    ",a,a_post,b,pre_b);
        return 0; 
    }

    运行结果:

    a和b都递增了1,但是,a_post是a递增之前的值,而b_pre是b递增之后 的值。这就是++的前缀形式和后缀形式的区别

    x*y++表示的是(x)*(y++),而不是(x+y)++。不过后者无 效,因为递增和递减运算符只能影响一个变量(或者,更普遍地说,只能影 响一个可修改的左值),而组合x*y本身不是可修改的左值。

    不要混淆这两个运算符的优先级和它们的求值顺序。假设有如下语句:

    y = 2;
    n = 3;
    nextnum = (y + n++)*6;
    nextnum的值是多少?把y和n的值带入上面的第3条语句得:
    nextnum = (2 + 3)*6 = 5*6 = 30
    n的值只有在被使用之后才会递增为4。根据优先级的规定,++只作用 于n,不作用与y + n。除此之外,根据优先级可以判断何时使用n的值对表达 式求值,而递增运算符的性质决定了何时递增n的值。

    如果n++是表达式的一部分,可将其视为“先使用n,再递增”;而++n则表示“先递增n,再使用”。

    #include<stdio.h>
    void main()
    {
        int i=5,j=5,p,q;
        p=(i++)+(i++)+(i++);
        q=(++j)+(++j)+(++j);
        printf("%d,%d,%d,%d",p,q,i,j);
    }

    输出结果:18,22,8,8

    表达式和语句

    表达式

    表达式(expression)由运算符和运算对象组成(运算对象是运算符操作的对象)。最简单的表达式是一个单独的运算对象,以此为基础可以建立复杂的表达式

    运算对象可以是常量、变量或二者的组合。一些表达式由子 表达式(subexpression)组成(子表达式即较小的表达式)

    语句

    语句(statement)是C程序的基本构建块。一条语句相当于一条完整的 计算机指令。在C中,大部分语句都以分号结尾 

    语句可分为简单语句和复合语句。简单语句以一个分号结尾。

    如下所示:

    赋值表达式语句:   toes = 12;

                                         在变量说明中,不允许连续给多个变量赋初值
    函数表达式语句:   printf("%d ", toes);
    空语句:          ;  /* 什么也不做 */

                                         只有分号组成的语句为空语句,在程序中空语句可用来做空循环体
    复合语句(或块)由花括号括起来的一条或多条语句组成。

    如下面的 while语句所示:
      while (years < 100)
      {
        wisdom = wisdom * 1.05;
        printf("%d %d ", years, wisdom);
        years = years + 1;
      }

    类型转换

    基本的类型转换规则

    1.当类型转换出现在表达式时,无论是unsigned还是signed的char和short 都会被自动转换成int,如有必要会被转换成unsigned int(如果short与int的大 小相同,unsigned short就比int大。这种情况下,unsigned short会被转换成 unsigned int)。

       在K&R那时的C中,float会被自动转换成double(目前的C不是这样)。由于都是从较小类型转换为较大类型,所以这些转换被称为升级 (promotion)。

    2.涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别。

    3.类型的级别从高至低依次是long double、double、float、unsignedlong long、long long、unsigned long、long、unsigned int、int。例外的情况是,当 long 和 int 的大小相同时,unsigned int比long的级别高。

      之所以short和char类型没有列出,是因为它们已经被升级到int或unsigned int。

    4.在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类 型。这个过程可能导致类型升级或降级(demotion)。所谓降级,是指把一 种类型转换成更低级别的类型。

    5.当作为函数参数传递时,char和short被转换成int,float被转换成 double。函数原型会覆盖自动升级。
       类型升级通常都不会有什么问题,但是类型降级会导致真正的麻烦。原因很简单:较低类型可能放不下整个数字。例如,一个8位的char类型变量储存整数101没问题,但是存不下22334。

    待赋值的值与目标类型不匹配时规则

    1.目标类型是无符号整型,且待赋的值是整数时,额外的位将被忽略。 例如,如果目标类型是 8 位unsigned char,待赋的值是原始值求模256。
    2.如果目标类型是一个有符号整型,且待赋的值是整数,结果因实现而异。
    3.如果目标类型是一个整型,且待赋的值是浮点数,该行为是未定义的

    字符串数据的输入输出

    putchar函数是字符输出函数,其功能在显示器上输出单个字符,其一般形式为:

    putchar(字符变量);

    putchar('A');   //输出大写字母A
    putchar(x);    //输出字符变量x的值
    putchar('101');   //也是输出字符A
    putchar('
    ');      //换行

    对控制字符则执行控制功能,不在屏幕上显示

    使用本函数前必须要用文件包含命令:

    #include<stdio.h>或#include“stdio.h”

    #include<stdio.h>
    
    void main()
    {
        char a='B',b='o',c='k';
        putchar(a);putchar(b);putchar(b);putchar(c);putchar('	');
        putchar(a);putchar(b);
        putchar('
    ');
        putchar(b);putchar(c);
    }

    getchar函数(键盘输入函数)

    getchar函数的功能从键盘上输入一个字符

    其一般形式为:

    getchar();

    通常把输入的字符赋予一个字符变量,构成赋值语句,如:

    char c;

    c=getchar();

    void main()
    {
        char c;
        printf("input a character
    ");
        c=getchar();
        putchar(c);
    
    }
  • 相关阅读:
    判断一个点是否在一个不规则多边形内算法
    vue-cli 3.0 安装和创建项目流程
    微信小程序分享朋友圈的实现思路与解决办法
    vue2.0中关于active-class
    Nginx服务启动脚本
    Linux系统优化
    URL检测脚本
    Mysql读写分离php脚本
    Memcahed服务异常监控脚本
    一致性哈希算法PHP测试片段
  • 原文地址:https://www.cnblogs.com/yangyuqing/p/10246018.html
Copyright © 2020-2023  润新知