初识C语言1(操作符详解)

目录

算术操作符

移位操作符

位操作符

赋值操作符

单目操作符

关系操作符

逻辑操作符

条件操作符

逗号表达式

1.算术操作符

+    -    *    /    %

 算术操作符的话有:加号(+)减号(-)乘号(*)除号(/)取模(%)。大家应该都非常的熟悉,也比较简单,给大家稍微说一下,其中的一些需要注意的地方我给大家讲一下。加号(+):进行加法计算,可以整数相加,字符相加,浮点数相加,减号(-)乘号(*)也一样。

除号(/),我们来看下面的小例子:

 

3/5打印的结果为0。这里就要说一下结果为什么是0,不应该是0.6嘛。

3/5,除号(/)两边的两个操作数是整数,所以这里进行的是整数除法,3/5这里是商0余3,不够除,商0,余了个3。如果把3换成6,6/5打印的结果就是1,这里就是商1余1。这就叫做整数除法

如果我们不想要打印整数,想要的是浮点数呢,我们来看下面的小例子:

 

想要打印出浮点数,除号两端的操作数最少有一个是浮点数,这样执行的就是浮点数的除法。我们就能得到0.6的结果。

因为除号两端有一个是浮点数,所以我们改成float类型。打印的是浮点数,所以用%f。

取模(%)

取模(%)操作符的两个操作数必须为整数。返回的是整除之后的余数。

 

上面例子打印的结果是 1 。

7 % 3求的就是7 / 3的余数,7 / 3的结果是商2余1,所以打印的结果就是1。

2.移位操作符

(<<) 左移操作符   (>>) 右移操作符

(<<) 左移操作符,我们来看下面例子:

 

上面把a向左移动移动一位就是把a的二进制序列向左移动一位。

左移操作的移动规则就是:左边丢弃,右边补0。

所以向左移动一位后求得b的值为4。

(>>) 右移操作符

右移操作符分两种:

算术右移,右边丢弃,左边补原符号位。

逻辑右移,右边丢弃,左边补0。

我们来看下面例子:

 

a的二进制序列:

00000000  00000000  00000000  00000010

向右移动一位的:

00000000  00000000  00000000  00000001

因为a是正数,所以不管是逻辑运算还是算术运算,左边补的都是0。所以得到的b值就是1。

我们可以测试一下当前编译器是采用的算术右移还是逻辑右移,我们用 -1 来测试一下:

负数:-1

我们存放到内存中

说到这里必须给大家交代一个知识点,

整数的二进制表示形式有三种,分别是原码,反码,补码。

原码:直接根据数值写出的二进制序列就是原码。

反码:原码的符号位不变,其他位按位取反就是反码。

补码:反码+1,就是补码。

-1,我们放到a里面怎么放呢,首先我们要写出它的原码,再写出它的反码,再写出它的补码。-1要存放到内存中的话,是以补码的形式存放的。(此算法是针对负数的,正整数原反补相同)。

-1的二进制序列:

原码:10000000  00000000  00000000  00000001

反码:11111111  11111111  11111111  11111110

补码:11111111  11111111  11111111  11111111

现在我们把-1向右移动一位,如果你当前的编译器采用的是算术右移,右边丢弃,左边补原符号位,那么你得到值就还是-1,如果是逻辑右移,右边丢弃,左边补0,那么你得到的值就是01111111 11111111  11111111  11111111,这是一个比较大的值,大家私下里可以自己算一下。

还有一点要跟大家说一下,我们把a向右移动一位,a的值是不变的,我们只是把a向右移动一位的值放到b里面,a的值是不变的。

3.位操作符

(&)按位与    (|)按位或   (^)按位异或

(&)按位与我们看下面的例子:

 

    int a = 3;
    int b = 5;
    //& → 就是按(2进制)位与
    //a → 00000000000000000000000000000011
    //b → 00000000000000000000000000000101
    //对应的2进制位按位与,只要有0,结果就是0,两个都为1结果才是1
    //按位与后的结果 → 00000000000000000000000000000001
    int c = a & b;
    printf("%dn", c);//打印结果是1

(|)按位或我们看下面的例子:

 

    int a = 3;
    int b = 5;
    //| → 按(2进制)位或
    //a → 00000000000000000000000000000011
    //b → 00000000000000000000000000000101
    //对应的2进制位按位或,只要有1有1结果则为1,两个同时为0结果则为0
    //按位或后的结果 → 00000000000000000000000000000111
    int c = a | b;
    printf("%dn", c);//打印结果是7

(^)按位异或我们看下面的例子:

 

    int a = 3;
    int b = 5;
    //^ → 按(2进制)位异或
    //a → 00000000000000000000000000000011
    //b → 00000000000000000000000000000101
    //对应的2进制位按位异或,相同为0,相异为1
    //按位异或后的结果 → 00000000000000000000000000000110
    int c = a ^ b;
    printf("%dn", c);//打印结果是6

这三个操作符的操作数必须都是整数。

4.赋值操作符

(=)赋值操作符  ( +=   -=   *=   /=   %=   <<=   >>=   &=   |=   ^= )复合赋值操作符

(=)赋值操作符 

一个等号(=)叫赋值,两个等号(==)叫判断

 赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己

重新赋值。

int weight = 120;//体重

weight = 89;//不满意就赋值

double salary = 10000.0; salary = 20000.0;//使用赋值操作符赋值。

赋值操作符可以连续使用,比如:

int a = 10;

int x = 0;

int y = 20;

a = x = y+1;//连续赋值(不建议写成这种形式,拆开写,简洁大方,通俗易懂)

x = y+1;

a = x;

复合赋值符

int x = 10;

x = x+10;//简化一下可以写成下面的方式

x += 10;//复合赋值 

这两种写法是完全等价的两种写法。

5.单目操作符

! 逻辑反操作

- 负值

+ 正值

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

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

-- 前置、后置--

++ 前置、后置++

(!)逻辑反操作符 

操作数只有一个操作符叫单目操作符

我们看一个例子:

这里只会打印hehe,因为!flag为假。

(!) 逻辑反操作符可以让假变成真,真变成假。

我们可以测试一下,

int flag = 0;为假
printf("%d", !flag);我们打印的结果就是1。

反之为flag为1,!flag打印结果为0。

真我们用1表示,假我们用0表示。

 - 负值

正负的意思。看小例子:

a打印的结果就是-10。

+ 正值

a = +a这种写法是可以忽略的,没什么用,所以就省略了。

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

计算一个类型或者变量所占内存的大小。

举例说明:

a的类型是int,sizeof(a)可以计算a所占空间的大小,单位是字节。上例两种写法是等价的,打印结果都是4。我们也可以写成 sizeof a 的形式,把圆括号去掉。这就表面sizeof是一个操作符,不是函数。

sizeof也可以计算数组的大小,看例子

 数组arr是char类型,char类型所占空间的大小是1个字节,arr数组有十个元素,所以上面打印的结果是10,单位是字节。上面两种打印写法是等价的。

我们再看一个列子:

大家觉的上面例子打印的值应该是多少?就不和大家卖关子了,打印的结果分别为2和5。为什么呢,a + 2虽然是个int类型的值,但是s不会因为放了这样一个值空间就变大,而sizeof求的是s所占空间字节的大小,所以第一个打印结果是2。为什么第二个是5呢,因为sizeof内部中放的表达式是不参与运算的。所以a + 2的值不会放到s里,s的值没变。

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

看例子:

    // ~ 对一个数的二进制位按位取反
    //负数在内存中存的是补码,
    //-1的补码1111111111111111111111111111111
    // ~按位取反
    // a的值11111111111111111111111111111111 
    // b的值00000000000000000000000000000000
    int a = -1;
    int b = ~a;
    printf("%dn", b);//结果为0

(本文中的二进制位数都是32位,如果出现少一位或者多一位的现象纯粹是作者手抖)

-- 前置、后置--

++ 前置、后置++

看例子:

前置++,先++,后使用。.

后置++,先使用,后++。

-- 前置、后置-- 同理。

再举个例子:

6. 关系操作符

>    大于运算符

>=  大于等于运算符

<    小于运算符

<=  小于等于运算符

!=   用于测试“不相等”

==  用于测试“相等”

看下面一些例子:

a == b;
a != b;
a < b;
a > b;
a <= b;
a >= b;

 关系表达式通常返回01,表示真伪。C 语言中,0表示伪,所有非零值表示真。比如,20 > 12返回112 > 20返回0。注意,相等运算符==与赋值运算符=是两个不一样的运算符,不要混淆。

关系表达式常用于ifwhile结构。

f (x == 3) {
  printf("x is 3.n");
}

 有时候,可能会不小心写出下面的代码,它可以运行,但很容易出现意料之外的结果。

if (x = 3) ...

 上面示例中,原意是x == 3,但是不小心写成x = 3。这个式子表示对变量x赋值3,它的返回值为3,所以if判断总是为真。

为了防止出现这种错误,有些人喜欢变量写在等号的右边。

if (3 == x) ...

 这样的话,如果把==误写成=,编译器就会报错。

// 报错 
if (3 = x) ...

另一个需要避免的错误是,多个关系运算符不宜连用。

i < j < k

上面示例中,连续使用两个小于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量j的值在ik之间。因为表示运算符是从左到右计算,所以实际执行的是下面的表达式。

(i < j) < k

 上面式子中,i < j返回01,所以最终是01与变量k进行比较。如果想要判断变量j的值是否在ik之间,应该使用下面的写法。

i < j && j < k

7. 逻辑操作符

&&     逻辑与

||        逻辑或

 看下面例子:

 &&:与运算符(两侧的表达式都为真,则为真,否则为伪)。

||:或运算符(两侧至少有一个表达式为真,则为真,否则为伪)。

对于逻辑运算符来说,任何非零值都表示真,零值表示伪。比如,5 || 0会返回15 && 0会返回0

逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。

举个例子:

因为a++是后置++,所以先使用,后++,a为0,根据短路效应,&&前面的值如果为假后面的表达式就不进行计算了,所以最终的结果为1,2,3,4。

这次我们把a的值改为1,因为a为真,根据短路效应,|| 前面的值如果为真后面的表达式就不进行计算了,所以最终的结果为2,3,3,5。

 

 

8.条件操作符

exp1  ? exp2  : exp3                                        exp(表达式的意思)

条件操纵符也叫三目操作符。

( exp1  ? exp2  : exp3 )整体也是一个表达式。

意思为:如果表达式1的结果为真,表达式2计算,表达式3不算,表达式2的结果是整个表达式的结果。如果表达式1的结果为假,表达式2不算,表达式3计算,表达式3的结果是整个表达式的结果。我们来看下面例子:

9.逗号表达式

逗号表达式,从左向右依次计算,整个表达式的结果是最后一个表达式的结果。

所以说c=5,a=a+3结果为6,b=a-4结果为2,c+=5结果为10,所以我们打印的结果d为10。不能只算最后一个表达式的结果,一定要从左向右一次进行计算。

 

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>