一、算术运算符

算术运算符很地简单。就是小学数学里面的一些加减乘除操作。只是呢。还是有一些语法细节须要注意的。

1.加法运算符 +

1 int a = 10;
2
3 int b = a + 5;

在第3行利用加法运算符 + 进行了加法运算。再将和赋值给了变量b,终于变量b的值是15

2.减法运算符 或 负值运算符 -

1 int b = 10 - 5;
2
3 int a = -10;

1> 在第1行利用减法运算符 - 进行了减法运算,再将差赋值给了变量b,终于变量b的值是5

2> 在第3行中,这个 - 并非什么减法运算符,而算是一个负值运算符,-10代表的是负十

3.乘法运算符 *

1 int b = 10 * 5;

注意:乘法运算符并非x或者X,而是星号*。

变量b终于的值是50。

4.除法运算符 /

1 double a = 10.0 / 4;
2 double b = 10 / 4;
3
4 printf("a=%f, b=%f \n", a, b);

注意:除法运算符并非÷。而是一个正斜杠 /

1> 第1行中的10.0是浮点型。4是整型,因此会将4自己主动类型提升为浮点型后再进行运算,最后变量b的值是2.5

2> 第2行中的10和4都是整型,计算机中的运算有个原则:同样数据类型的值才干进行运算,并且运算结果依旧是同一种数据类型。

因此。整数除于整数。求出来的结果依旧是整数,会损失小数部分。最后变量b的值是2。

查看输出结果:

3> 假设想让 整数除于整数 不损失精度的话,能够将某个整数强制转换为浮点型数据

1 double a = (double)10 / 4;
2
3 double b = 10 / (double)4;
4
5 double c = (double)10 / (double)4;
6
7 double d = (double) (10 / 4);
  • 10和4之间仅仅要有1个强转为浮点型数据就可以,另外1个整数会自己主动类型提升为浮点型数据。因此。变量a、b、c的值都是2.5。
  • 变量d的情况就不一样了,第7行代码的意思是先计算(10/4)的值,再将(10/4)的值强转为浮点型数据。(10/4)的值是2,将2强转为浮点型数据,那不也就是2么?所以,变量d的值是2

5.模运算符 或称 取余运算符 %

注意:这个%并非除号÷,它是一个取余运算符,或者叫做模运算符。

取余的意思是,取得两个整数相除之后的余数。

比方,5除于2的余数是1,5除于3的余数是2。

因此使用这个%有个原则:%两側必须都为整数。

以下的写法是错误的:

1 int a = 5.0 % 2;

编译器会直接报错,由于5.0并不是整数。

1> 正数取余

1 int a = 5 % 2;
2 int b = 2 % 5;

简单计算可得:变量a的值为1。变量b的值为2

2> 负数取余

1 int a = -5 % 2;
2 int b = 5 % -2;
3 int c = -5 % -2;

利用%求出来的余数是正数还是负数,由%左边的被除数决定,被除数是正数。余数就是正数。反之则反。因此变量a、b、c的值各自是-1、1、-1

6.运算顺序

1> 算术表达式

用算术运算符将数据连接起来的式子,称为“算术表达式”。

比方a + b、10 * 5等。假设表达式比較复杂的话,那么就要注意一下它的运算顺序。

表达式的运算顺序是依照运算符的结合方向和优先级进行的。

2> 结合方向

算术运算符的结合方向是从左到右。比如表达式2+3+4,先计算2+3。

3> 优先级

优先级越高,就越先进行运算,当优先级同样时,參照结合方向。以下是算术运算符的优先级排序:

负值运算符(-) > 乘(*)、除(/)、模(%)运算符 > 加(+)、减(-)运算符

比如表达式4+5*8/-2的计算顺序为:-、*、/、+,最后的结果是-16

4> 小括号

假设须要先计算优先级低的能够使用小括号()括住,小括号的优先级是最高的!

  • 比如4+5*8-2默认的计算顺序是:*、+、-
  • 假设想先运行加法运算。就能够这样写:(4+5)*8-2。最后的结果都是不一样的

二、赋值运算符

赋值运算符又分两种:简单赋值运算符 和 复合赋值运算符。

1.简单赋值运算符 =

1> 简单使用方法

事实上这个等号 = 从讲变量開始就见过它了,它的作用是将右边的值赋值给左边。

1 int a = 10 + 5;

赋值运算符的结合方向是:从右到左,并且优先级比算术运算符低。因此先进行等号=右边的加法运算,运算完成后再将结果赋值给等号右边的变量。

最后变量a的值是15。

2> 连续赋值

1 int a, b;
2
3 a = b = 10;
  • 在第1行分别定义了int类型的变量a、b
  • 第3行代码的意思:将10赋值给变量b,再把变量b的值赋值给a。

    所以最后变量a、b的值都是10

3> 使用注意

等号=左边仅仅能是变量,不能是常量。常量都是不可变的,怎么能够再次赋值呢?以下的写法是错误的:

1 10 = 10 + 5;

2.复合赋值运算符

  • +=  加赋值运算符。如a += 3+2。等价于 a = a +(3+2)
  • -=  减赋值运算符。

    如a -= 3+2,等价于 a = a -(3+2)

  • *=  乘赋值运算符。如a *= 3+2,等价于 a = a *(3+2)
  • /=  除赋值运算符。

    如a /= 3+2,等价于 a = a /(3+2)

  • %=  取余赋值运算符。如a %= 3+2。等价于 a = a %(3+2)

三、自增运算符和自减运算符

1.简单介绍

  • ++  自增运算符。如a++,++a,都等价于a = a+1
  • --  自减运算符。

    如a--。--a,都等价于a = a-1

注意:你写个5++是错误的。由于5是常量。

2.++a和a++的差别

1> 单独使用++a和a++时,它们是没差别的

1 int a = 10;
2 a++;
1 int a = 10;
2 ++a;

上面两段代码的效果都是让a的值+1,最后a的值都为11

2> 以下这样的情况,++a和a++就有差别了

1 int a = 10;
2
3 int b = ++a;
1 int a = 10;
2
3 int b = a++;

上面两段代码的运行结果是有差别的。

  • 第1段代码:++a的意思是先对a运行+1操作,再将a的值赋值给b。因此最后a、b的值都是11
  • 第2段代码:a++的意思是先将a的值拷贝出来一份,然后对a运行+1操作,于是a变成了11。可是拷贝出来的值还是10,a++运算完成后,再将拷贝出来的值10赋值给了b,所以最后变量b的值是10。变量a的值是11

--a和a--的差别也是一样的。

3> 再来看一个比較刁钻的样例

1 int a = 10;
2
3 a = a++;

非常多人一眼看上去,认为最后a的值应该是11,事实上最后a的值是10。

前面已经说过a++的作用了。这里也是一样的。先将a的值拷贝出来一份。然后对a运行+1操作,于是a变成了11,可是拷贝出来的值还是10。a++运算完成后,再将拷贝出来的值10赋值给了a,所以最后变量a的值是10

四、sizeof

* sizeof能够用来计算一个变量或者一个常量、一种数据类型所占的内存字节数。

int size = sizeof(10);
printf("10所占的字节数:%d", size);

输出结果:,10是int类型的数据,在64bit编译器环境下。int类型须要占用4个字节

* sizeof一共同拥有3种形式

  • sizeof( 变量\常量 )
sizeof(10);

char c = 'a';
sizeof(c);
  • sizeof  变量\常量
sizeof 10;

char c = 'a';
sizeof c;
  • sizeof( 数据类型 )
sizeof(float);

注意,不能够写成sizeof float;

五、逗号运算符

* 逗号运算符主要用于连接表达式,比如:

1 int a = 9;
2 int b = 10;
3
4 a = a+1 , b = 3*4;

* 用逗号运算符连接起来的表达式称为逗号表达式,它的一般形式为:

表达式1, 表达式2, … …, 表达式n

逗号表达式的运算过程是:从左到右的顺序。先计算表达式1。接着计算表达式2,...,最后计算表达式n

* 逗号运算符也是一种运算符,因此它也有运算结果。

整个逗号表达式的值是最后一个表达式的值

1 int a = 2;
2 int b = 0;
3 int c;
4
5 c = (++a, a *= 2, b = a * 5);
6
7 printf("c = %d", c);

++a的结果为3。a *= 2的结果为6,b = a * 5的结果为30。因此,输出结果为:

这里要注意的是,右边的表达式是实用括号()包住的,假设不用括号包住,也就是:

1 c = ++a, a *= 2, b = a * 5;
2 printf("c = %d", c);

输出结果将为:。由于c = ++a也属于逗号表达式的一部分。跟后面的a *= 2以及b = a
* 5是相互独立的

六、关系运算符

1.“真”与“假”

1> 默认情况下。我们在程序中写的每一句正确代码都会被运行。

但非常多时候,我们想在某个条件成立的情况下才运行某一段代码。

比方微信的这个界面:

假设用户点击了注冊button。我们就运行“跳转到注冊界面”的代码;假设用户点击了登录button,我们就运行“跳转到登录界面”的代码。假设用户没做出不论什么操作,就不运行前面所说的两段代码。像这样的情况的话能够使用条件语句来完毕,可是我们临时不学习条件语句,先来看一些更基础的知识:怎样推断一个条件成不成立。假设这个都不会推断,还运行什么代码。

2> 在C语言中,条件成立称为“真”,条件不成立称为“假”。因此。推断条件是否成立。就是推断条件的“真假”。那怎么推断真假呢?C语言规定,不论什么非0值都为“真”,仅仅有0才为“假”。也就是说。108、-18、4.5、-10.5等都是“真”,0则是“假”。

2.关系运算符的简单使用

C语言中还提供了一些关系运算符。能够用来比較两个数值的大小。

  • <   小于。

    比方a<5

  • <=  小于等于。

    比方a<=5

  • >   大于。比方a>5
  • >=  大于等于。比方a>=5
  • ==  等于。

    比方a==5

  • !=  不等于。比方a!=5

关系运算符的运算结果仅仅有2种:假设条件成立。结果就为1。也就是“真”;假设条件不成立。结果就为0。也就是“假”。

1 int a1 = 5 > 4; // 1
2
3 int a2 = 5 < 4; // 0

3.关系运算符的使用注意

1> 关系运算符中==、!=的优先级相等。<、<=、>、>=的优先级相等。且前者的优先级低于后者

比如2==3>1 :先算3>1。条件成立,结果为1。再计算2==1,条件不成立,结果为0。因此2==3>1的结果为0。

2> 关系运算符的结合方向为“从左往右”

比如4>3>2 :先算4>3,条件成立,结果为1。再与2比較,即1>2。条件不成立。结果为0。因此4>3>2的结果为0。

3> 关系运算符的优先级小于算术运算符

比如3+4>8-2 :先计算3+4。结果为7。再计算8-2,结果为6。最后计算7>6,条件成立。结果为1。因此3+4>8-2的结果为1。

七、逻辑运算符

有时候,我们须要在多个条件同一时候成立的时候才干运行某段代码,比方:用户仅仅有同一时候输入了QQ和password,才干运行登录代码,假设仅仅输入了QQ或者仅仅输入了password。就不能运行登录代码。

这样的情况下,我们就要借助于C语言提供的逻辑运算符。

C语言提供了3个逻辑运算符:&&(逻辑与)、||(逻辑或)、!(逻辑非)。注意:这些都是英文字符,不要写成中文字符。

跟关系运算符一样,逻辑运算的结果仅仅有2个:“真”为1,“假”为0

1.&& 逻辑与

1> 使用格式

“条件A && 条件B”

2> 运算结果

仅仅有当条件A和条件B都成立时,结果才为1,也就是“真”;其余情况的结果都为0,也就是“假”。

因此,条件A或条件B仅仅要有一个不成立,结果都为0,也就是“假”

3> 运算过程

  • 总是先推断条件A是否成立
  • 假设条件A成立,接着再推断条件B是否成立:假设条件B成立。“条件A && 条件B”的结果就为1,即“真”。假设条件B不成立,结果就为0,即“假”
  • 假设条件A不成立,就不会再去推断条件B是否成立:由于条件A已经不成立了,无论条件B怎样。“条件A && 条件B”的结果肯定是0。也就是“假”

4> 举例

逻辑与的结合方向是“自左至右”。

比方表达式 (a>3) && (a<5)

  • 若a的值是4:先推断a>3,成立。再推断a<5,也成立。因此结果为1
  • 若a的值是2:先推断a>3。不成立,停止推断。因此结果为0
  • 因此,假设a的值在(3, 5)这个范围内,结果就为1;否则。结果就为0

5> 注意

  • 若想推断a的值是否在(3, 5)范围内,千万不能写成3<a<5,由于关系运算符的结合方向为“从左往右”。

    比方a为2。它会先算3<a,也就是3<2,条件不成立,结果为0。

    再与5比較。即0<5,条件成立,结果为1。因此3<a<5的结果为1,条件成立,也就是说当a的值为2时,a的值是在(3,
    5)范围内的。这明显是不正确的。正确的推断方法是:(a>3) && (a<5)

  • C语言规定:不论什么非0值都为“真”。仅仅有0才为“假”。因此逻辑与也适用于数值。比方
    5 && 4的结果是1,为“真”;-6 && 0的结果是0,为“假”

2.||  逻辑或

1> 使用格式

“条件A || 条件B”

2> 运算结果

当条件A或条件B仅仅要有一个成立时(也包含条件A和条件B都成立)。结果就为1。也就是“真”。仅仅有当条件A和条件B都不成立时,结果才为0,也就是“假”。

3> 运算过程

  • 总是先推断条件A是否成立
  • 假设条件A成立,就不会再去推断条件B是否成立:由于条件A已经成立了。无论条件B怎样。“条件A || 条件B”的结果肯定是1,也就是“真”
  • 假设条件A不成立。接着再推断条件B是否成立:假设条件B成立。“条件A || 条件B”的结果就为1,即“真”。假设条件B不成立,结果就为0,即“假”

4> 举例

逻辑或的结合方向是“自左至右”。比方表达式 (a<3) || (a>5)

  • 若a的值是4:先推断a<3。不成立。再推断a>5,也不成立。因此结果为0
  • 若a的值是2:先推断a<3。成立,停止推断。因此结果为1
  • 因此。假设a的值在(-∞, 3)或者(5, +∞)范围内。结果就为1;否则。结果就为0

5> 注意

C语言规定:不论什么非0值都为“真”,仅仅有0才为“假”。因此逻辑或也适用于数值。比方 5 || 4的结果是1,为“真”;-6
|| 0的结果是1。为“真”;0 || 0的结果是0,为“假”

3.!   逻辑非

1> 使用格式

“! 条件A”

2> 运算结果

事实上就是对条件A进行取反:若条件A成立,结果就为0,即“假”。若条件A不成立,结果就为1,即“真”。

也就是说:真的变假,假的变真。

3> 举例

逻辑非的结合方向是“自右至左”。

比方表达式 ! (a>5)

  • 若a的值是6:先推断a>5,成立,再取反之后的结果为0
  • 若a的值是2:先推断a>3。不成立,再取反之后的结果为1
  • 因此。假设a的值大于5,结果就为0;否则,结果就为1

4> 注意

  • 能够多次连续使用逻辑非运算符:!(4>2)结果为0,是“假”,!!(4>2)结果为1,是“真”,!!!(4>2)结果为0,是“假”
  • C语言规定:不论什么非0值都为“真”,仅仅有0才为“假”。因此。对非0值进行逻辑非!运算的结果都是0。对0值进行逻辑非!运算的结果为1。!5、!6.7、!-9的结果都为0,!0的结果为1

4.优先级

逻辑运算符的优先级顺序为: 小括号() > 负号 - > ! > 算术运算符 > 关系运算符 > && > ||

  • 表达式!(3>5) || (2<4) && (6<1) :先计算 !(3>5)、(2<4)、(6<1),结果为1,式子变为1 || 1 && 0,再计算1 && 0,式子变为1 || 0,最后的结果为1
  • 表达式3+2<5||6>3 等价于 ((3+2) < 5) || (6>3),结果为1
  • 表达式4>3 && !-5>2 等价于 (4>3) &&  ((!(-5)) > 2) ,结果为0

八、三目运算符

1.N目运算符

  • 像逻辑非(!)、负号(-)这样的仅仅连接一个数据的符号,称为“单目运算符”。比方!5、-5。
  • 像算术运算符、关系运算符、逻辑运算符这样的连接二个数据的负号,称为“双目运算符”。比方6+7、8*5、5>6、4 && 0、
  • 以此类推,连接3个数据的运算符,应该称为“三目运算符”

2.三目运算符

C语言提供了唯一一个三目运算符:条件运算符。

1> 使用格式

表达式A ? 表达式B : 表达式C

2> 运算结果

假设表达式A成立,也就是为“真”,条件运算符的结果就是表达式B的值,否则,就为表达式C的值

3> 结合方向和优先级

  • 优先级顺序为:算术运算符 > 关系运算符 > 条件运算符 > 赋值运算符
  • 条件运算符的结合方向是“从右至左”
1 int a = 3>4 ? 4+5 : 5>4 ? 5+6 : 6>7+1;

上面的代码等价于

1 int a = (3>4) ? (4+5) : ( (5>4) ? (5+6) : (6>(7+1)) );

简化一下就是

1 int a = 0 ? 9 : ( 1 ? 11 : 0 );

继续简化为

1 int a = 0 ? 9 : 11;

所以a的值是11

 

九、位运算符

所谓位运算就是对每个二进制位进行运算。C语言一共提供了6种位运算符。仅仅能对整数进行操作。各自是:&按位与、|按位或、^按位异或、<<左移、>>右移、~取反。

1.& 按位与

1> 使用形式:整数a & 整数b

2> 功能:整数a和b各相应的二进位相与。仅仅有相应的两个二进位均为1时。结果位才为1,否则为0。參与运算的数以补码方式出现。

3> 举例:比方9&5,事实上就是1001&101=1,因此9&5=1

4> 规律:

  • 同样整数相&的结果是整数本身。比方5&5=5
  • 多个整数相&的结果跟顺序无关。比方5&6&7=5&7&6

2.| 按位或

1> 使用形式:整数a | 整数b

2> 功能:整数a和b各相应的二进位相或。仅仅要相应的二个二进位有一个为1时,结果位就为1,否则为0。參与运算的数以补码方式出现。

3> 举例:比方9|5,事实上就是1001|101=1101。因此9|5=13

4> 规律:

  • 同样整数相|的结果是整数本身。

    比方5|5=5

  • 多个整数相|的结果跟顺序无关。比方5|6|7=5|7|6

3.^ 按位异或

1> 使用形式:整数a ^ 整数b

2> 功能:整数a和b各相应的二进位相异或。

当相应的二进位相异(不同样)时,结果为1,否则为0。

參与运算的数以补码方式出现。

3> 举例:比方9^5,事实上就是1001^101=1100,因此9^5=12

4> 规律:

  • 二进制中。与1相^就会取反。与0相^保持原位
  • 同样整数相^的结果是0。比方5^5=0
  • 多个整数相^的结果跟顺序无关。比方5^6^7=5^7^6
  • 因此得出结论:a^b^a = b

4.~ 取反

1> ~为单目运算符,具有右结合性,使用形式:~整数a

2> 功能:对整数a的各二进位进行取反(0变1,1变0)

3> 举例:比方~9,事实上就是~(0000 0000 0000 0000 0000 0000 0000 1001)=(1111 1111 1111 1111 1111 1111 1111 0110),因此~9=-10

5.<< 左移

1> <<是双目运算符。使用形式:整数a<<正数n

2> 功能:把整数a的各二进位所有左移n位,高位丢弃,低位补0。左移n位事实上就是乘以2的n次方。

3> 举例:3<<4,3本来是0000 0011,左移4位后变成了0011 0000。因此3<<4 = 48 = 3 * 24

4> 须要注意的是:因为左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性

6.>> 右移

1> >>是双目运算符,使用形式:整数a>>正数n

2> 功能:把整数a的各二进位所有右移n位,保持符号位不变。

右移n位事实上就是除以2的n次方。

3> 举例:32>>3,32本来是0010 0000,右移3位后变成了0000 0100,因此32>>3 = 4 = 32 / 23

最新文章

  1. System.IO中的File、FileInfo、Directory与DirectoryInfo类(实例讲解)
  2. 【读书笔记】读《JavaScript模式》 - 对象创建模式
  3. iis6兼容32位运行
  4. 实现MySQL的Replication
  5. bind() to 0.0.0.0:80 failed (98: Address already in use)
  6. 文件和目录之link、unlink、remove和rename函数
  7. 修改.htaccess实现子目录绑定示例分享
  8. Java中的数据类型及相互转换方法
  9. Jsp笔记(1)
  10. loaded some nib but the view outlet was not set
  11. Oracle10g数据泵EXPDP和IMPDP备份与恢复数据
  12. hadoop,yarn和vcpu资源配置
  13. storybody中页面跳转
  14. 1020. Tree Traversals (25) -BFS
  15. AJAX跨域请求详解
  16. Tarjan求割点 || Luogu P3388 【模板】割点(割顶)
  17. xpath详细讲解
  18. ssh登录原理及免密登录配置
  19. 十行代码--用python写一个USB病毒 (知乎 DeepWeaver)
  20. 6-3 矩阵链成 uva 442

热门文章

  1. 算法提高 道路和航路 SPFA 算法
  2. poj1703 Find them, Catch them(并查集的应用)
  3. JVM-String常量池与运行时常量池
  4. PHP特性整合(PHP5.X到PHP7.1.x)
  5. FileZilla Server-Can’t access file错误解决方法
  6. CCNA2.0笔记_HSRP
  7. 把以逗号分隔的字符串转换成list
  8. 初识md5碰撞与crc32碰撞
  9. jquery仿jquery mobile的select控件效果
  10. 多线程中wait和notify的理解与使用