【C语言】初识C语言(中篇)

简介: 【C语言】初识C语言(中篇)

10. 操作符


算数操作符


+        -        *        /        %

算数操作符中的+ - *和平常运算方法相似,我们在这边重点介绍 / 和 %运算符


/ 操作符

为了让我们的讲解更加具有针对性,我们分正数负数两部分进行讲解:

/ 操作符对正数

#include<stdio.h>
int main()
{
    int a = 7 / 2;
    printf("%d\n", a);//3
}



分析:对于上方代码当我们用平时的逻辑,那么这个答案应该是3.5,可在程序中编译运行,结果是 3,我们不禁产生疑惑是不是因为你打印的结果是整形的缘故,其实本身结果还是3.5呢?让我们用代码验证:

#include<stdio.h>
int main()
{
    float f = 7 / 2;
    printf("%f\n",f);//3.000000
}

可当我们再次进行编译运行时,结果是3.000000,因此我们可以得出结论:

除号两端的操作数如果都是整数,执行的是整数除法,至少有一个操作数是浮点数,执行的才是浮点数的除法!!!

对于正数是这样进行运算的,那么负数呢?





/ 操作符对负数

1. #include<stdio.h>
2. int main()
3. {
4.     int i = -2.9;
5.     int j = 2.9;
6.     printf("%d\n",j);//-2
7.     printf("%d\n",j);//2
8.     return 0;
9. }


对于负数运算,我们打印 j 的值,结果为 -2 ,和正数运算规律相似,我们可以看出它们运算都是向0取整的,那么如何理解呢?对于取整,当正负数进行运算时,并不会出现四舍五入的情况,无论正数负数都是向0方向取整!(-2.9向零取整得到2)

如下图所示:


01699781c9134501aff50b08895db1bc.png



小科普

在C语言中,是不是只有一种取整方式?如果有它们分别是怎么实现的?接下来我们来一一了解:


trunc - 取整函数

1. #include<math.h>
2. int main()
3. {
4.      printf("%d\n",(int)trunc(-2.9));//-2
5.      printf("%d\n",(int)trunc(2.9));//2
6. }


Tips:由于trunc函数默认接收的返回值为%f,但是我们这边想输出的是整数所以强制类型转化成int类型。


floor - 地板取整

#include<stdio.h>
#include<math.h>
int main()
{
    printf("%.lf\n",floor(-2.9));//-3
    printf("%.lf\n",floor(-2.1));//-3
    printf("%.lf\n",floor(2.9));//2
    printf("%.lf\n",floor(2.1));//2
}


因为其取整方式和函数名,我们称它为地板取整,什么意思呢,我们编译结果发现负数-2.9的值变成了-3,对于正数2.9的值变成了2

我们可以观察到无论是正数还是负数,在用floor函数进行取整的时候都是变小,我们观察其本质可以总结为-∞取整,如下图所示:


7d470b445ab34127939437424b279e16.png

ceil - +∞取整

#include<stdio.h>
int main()
{
    printf("%.lf\n",ceil(-2.9));//-2
    printf("%.lf\n",ceil(-2.1));//-2
    printf("%.lf\n",ceil(2.9));//3
    printf("%.lf\n",ceil(2.1));//3
}


当我们编译运行程序,可以观察到负数-2.9变为-2-2.1变为-2,正数2.9变为32.1变为3

我们可以观察到ceil函数的取整,结果都会在原来的基础上变大一个整数位,我们总结出该取整方式为+∞取整,如下图所示:

a22b5396cab4483f9d9754adf16dc945.png



round - 四舍五入取整

是的你没有看错,与我们平常思维方式相同的四舍五入取整来了,上代码:

#include<math.h>
int main()
{
    printf("%.lf\n",round(-2.9));//-3
    printf("%.lf\n",round(-2.1));//-2
    printf("%.lf\n",round(2.9));//3
    printf("%.lf\n",round(2.1));//2
}


对于这种取整方式,没什么好说的,就是按照我们平时的思路来,例如当值2.9时,值为3

当值为2.1时,值为2。在当前情况下,凡取整的值大于等于2.5,得出的结果都会变为3


% 操作符


概念:如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r 且0 ≤ r < d。其中,q 被称为商,r 被称为余数。


对于此部分我们依旧是从正数负数两方面进行剖析:

% 操作符对正数

#include<stdio.h>
int main()
{
    int a = 10;
    int d = 3;
    printf("%d\n",a%d);//1
    //因为:a=10,d=3,q=3,r=1 0<=r<d(3)
    //所以:a=q*d+3 -> 10=3*3+1
    return 0;
}
-


代码:基于概念,我们可以理解当前代码的意思(详情见注释)。但我们还有另一种理解方式:% 操作符,关注的是除法后的余数,例如代码中的10%3,我们也可以理解为商3余1,相对于概念,这种方式更加容易接受一些。

Warning:操作符两端的操作数必须是整数!!!



% 操作符对负数

1. int main()
2. {
3.     int a = - 10;
4.     int d= 3;
5.     printf("%d\n",a%d);//-1
6. }



很显然,结果不满足定义中的0<=r<d,故后来就有了一个修订版的定义:


   如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r , q 为整数,且0 ≤ |r| < |d|。其中,q 被称为商,r 被称为余数。


根据定义,这里的结果也能解释了,即-10 = (-3)*3+(-1)。


   在C语言中,%本质为取余,余数的大小,本质取决于商q的,而商都取决于除法运算的取整规则。


   在对于正数的取余和取模在C语言中是相同的,我们发现对于向0取整和向-∞的取整在正数上是同向的,但是对于负数上就完全不同了,因此我们平时遇到的大多都是整数取模,并没有做太多解释。



移位操作符

>>        <<(以后讲解)




位操作符

&         ^(以后讲解)



赋值操作符

=        +=        -=        *=        /=        &=        ^=        |=        >>=



由于赋值操作符便于理解,我们挑两个讲一下(详情见注释):

1. int main()
2. {
3.     int a = 10;//创建变量,并初始化
4.     a = 20;//赋值
5.     a = a+5//等价于 a+=5
6.     a = a-5//等价于 a-=5
7. }



单目操作符


!                 逻辑反操作

-                 负值

+                正值

&                取地址

sizeof         操作数的类型长度(以字节为单位)

~                对一个数的二进制按位取反

--                前置、后置--

++              前置、后置++

*                 间接访问操作符(解引用操作符)

(类型)         强制类型转换



我们常见的操作符比如+都有两个操作数,表示为左操作数+右操作数,这种操作符叫做双目操作符

单目操作符其实就是只有一个操作数的。


在这里,对于!,-,+等操作符都便于理解,而对于&和*我打算之后在指针部分讲解,这里我们着重讲一下--,和++操作符(详情见注释):

#include<stdio.h>
int main()
{
    int a = 10;
    int b = ++a;//前置++,先++后使用
    //a=a+1,b=a
    printf("a=%d b=%d\n",a,b);//11 11
    ---------------------------------
    int a = 10;
    int b = a++;//后置++,先使用,后++
    //b=a,a=a+1
    printf("a=%d b=%d\n",a,b);//11 10
    ---------------------------------
    int a = 10;
    int b = --a;//前置--,先--后使用
    //a=a-1,b=a
    printf("a=%d b=%d\n",a,b);//9 9
    ---------------------------------
    int a = 10;
    int b = a--;//后置--,先使用,后--
    //b=a,a=a-1
    printf("a=%d b=%d\n",a,b);//10 9
}



关系操作符

>         >=         <        <=        !=(不相等)        ==(相等


前几个操作符,也就是对应的大于,大于等于,小于,小于等于等比较关系的操作符,这里我们讲一下后两个操作符。


例1

int main()
{
    int a = 3;
    int b = 3;
    if(a!=b)
    {
        printf("hehe\n");    
    }
    if(a==b)
    {
        printf("haha\n");    
    }
    //结果为hehe
}



运行结果如下:a051db94814245e590600f5cd90bf930.png



观察代码,很简单,判断a和b是否相等,如果相等则输出haha,若不相等输出hehe,因为c此处a和b都等于3,所以打印结果为hehe。


例2

#include<stdio.h>
int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "abcdef";
    if(arr1==arr2)
    {
        printf("==\n");    
    }
    else
    {
        printf("!=\n");    
    }
}


我们知道用==和!=可以判断是否相等,那么对于字符串呢?他们是否相等,当我们编译后,发现它们是不相等的!因为arr1和arr2是字符串首元素地址,开辟的空间不同,所以地址当然不同,如果要比较两个字符串的大小可以用strcmp函数,接下来看修改后的代码:

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "abcdef";
    if(strcmp(arr1,arr2)==0)
    {
        printf("==\n");    
    }
    else
    {
        printf("!=\n");    
    }
}


再次运行1aa501a7a5154c3d8adcce4cc2322031.png



对于strcmp这个函数使用时需要应用头文件#include<string.h>,如果返回的值为0,则两个字符串相等。

逻辑操作符

&& - 逻辑与 - 并且        || - 逻辑或 - 或者

int main()
{
    int a= 3;
    int b = 0;
    int c = a && b;
    printf("%d\n",c);//真为1,假为0
    if(a&&b)
    {
        printf("hehe\n");    
    }
    if(a||b)
    {
        printf("haha\n);
    }
}


运行得

b7bbc7985c7b4e4ab9cbfb3e8a0d5d69.png


分析:&&的返回值是这样规定的,如果两个数都为真,则值为1,反之则为0。

对于本代码由于a&&b为0,故不打印hehe,||的值是有一个为真则为真,值为1,反之为0。

这里由于a||b为真,所以打印haha。



条件操作符

exp1?exp2:exp3

#include<stdio.h>
int main()
{
    int a = 10;
    int b = 0;
    b = (a>5?3:-3);
    printf("%d\n",b);//3
    return 0;
}

分析:条件操作符使用时先判断表达式1,如果表达式1结果为,则输出第一个值,否则为第二个值,改题中因为a>10,所以打印结果为3。当然,这段代码也可以用if        else语句来表示:

#include<stdio.h>
int main()
{
    int a = 10;
    int b = 0;
    if(a>5)
    {
        b=3;    
    }
    else
    {
        b=-3;    
    }
    printf("%d\n", b);
}



逗号表达式


exp1, exp2, exp3, …expN


#include<stdio.h>
int main()
{
    int a=3;
    int b=5;
    int c=0;
    int d= (a+=2,b=b-c+a,c=a+b);
    //      a=5   b=10   c=5+10     
    printf("%d\n",d);
}

分析:对于逗号表达式其特点为从左往右依次计算,整个表达式的结果是最后一个表达式的结果,因此在代码中d的值也就是15。


下标引用、函数调用和结构成员

[]        ()        .        ->


对于这类操作符我们讲解一下[ ]操作符:

1. #include<stdio.h>
2. int main()
3. {
4.     int arr[10] = {0};
5.     arr[4]=5;
6.     return 0;
7. }


分析:对于上述代码就是引用下标4,将arr[4]的位置上赋值5。

和一些操作符相同,[ ]也有两个操作数,例如arr 和 4是两个操作数,对于这个代码写成4[arr]也可以,但是这种写法不仅让人难以理解,而且比较挫,我们可千万不要写出这样的代码!!!


相关文章
|
程序员 编译器 C语言
初识C语言——C语言基础知识(一)
初识C语言——C语言基础知识(一)
73 0
初识C语言——C语言基础知识(一)
|
C语言
C语言基础练习(3)
C语言基础练习(3)
77 2
|
6月前
|
存储 程序员 C语言
C语言(1)----C语言是什么?基本概念介绍
C语言(1)----C语言是什么?基本概念介绍
64 3
|
3月前
|
编译器 Linux C语言
C语言基础
C语言基础
41 0
|
C语言
初识C语言——C语言基础知识(二)
初识C语言——C语言基础知识(二)
59 0
|
存储 编译器 C语言
初识C语言——C语言基础知识(四)
初识C语言——C语言基础知识(四)
53 0
|
C语言
c语言基础题2
c语言基础题2
104 0
|
程序员 编译器 C语言
初识C语言(5)C语言一些基本常识
初识C语言(5)C语言一些基本常识
65 0
|
C语言
初识C语言(0基础开始)一
初识C语言(0基础开始)一
75 0
|
C语言 C++
初识C语言(0基础开始)二
初识C语言(0基础开始)二
150 0