李洪强iOS开发之【零基础学习iOS开发】【02-C语言】08-基本运算

news/2023/6/8 18:52:41

计算机的基本能力就是计算,所以一门程序设计语言的计算能力是非常重要的。C语言之所以无所不能,是因为它不仅有丰富的数据类型,还有强大的计算能力。C语言一共有34种运算符,包括了常见的加减乘除运算。这讲就对C语言中的运算符做一个详细介绍。

一、算术运算符

算术运算符非常地简单,就是小学数学里面的一些加减乘除操作。不过呢,还是有一些语法细节需要注意的。

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> 默认情况下,我们在程序中写的每一句正确代码都会被执行。但很多时候,我们想在某个条件成立的情况下才执行某一段代码。比如微信的这个界面:

如果用户点击了注册按钮,我们就执行“跳转到注册界面”的代码;如果用户点击了登录按钮,我们就执行“跳转到登录界面”的代码。如果用户没做出任何操作,就不执行前面所说的两段代码。像这种情况的话可以使用条件语句来完成,但是我们暂时不学习条件语句,先来看一些更基础的知识:如何判断一个条件成不成立。如果这个都不会判断,还执行什么代码。

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和密码,才能执行登录代码,如果只输入了QQ或者只输入了密码,就不能执行登录代码。这种情况下,我们就要借助于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

 

转载于:https://www.cnblogs.com/LiLihongqiang/p/5676020.html


https://dhexx.cn/news/show-43312.html

相关文章

优秀工程师-UIResponder

在iOS中UIResponder类是专门用来响应用户的操作处理各种事件的&#xff0c;包括触摸事件(Touch Events)、运动事件(Motion Events)、远程控制事件(Remote Control Events,如插入耳机调节音量触发的事件)。我们知道UIApplication、UIView、UIViewController这几个类是直接继承自…

李洪强iOS开发拓展篇—UIDynamic(重力行为+碰撞检测)

iOS开发拓展篇—UIDynamic(重力行为碰撞检测) 一、重力行为 说明&#xff1a;给定重力方向、加速度&#xff0c;让物体朝着重力方向掉落 1.方法 &#xff08;1&#xff09;UIGravityBehavior的初始化 - (instancetype)initWithItems:(NSArray *)items; item参数 &#xff1a;里…

SwiftUI 教程之如何在 2 秒内实现自动滚动功能

使用 SwiftUI 进行开发令人惊讶。它确实使得只需几行代码就可以实现一些很酷的功能。今天,我们来实现自动滚动。当您创建聊天应用程序时,此技术特别有用。我将尽可能简要地解释它。 准备你的 UI struct AutoScrollList: View {var body: some View {VStack {Button("S…

【零基础学习iOS开发】【02-C语言】09-流程控制

前言 1.默认的运行流程 默认情况下&#xff0c;程序的运行流程是这样的&#xff1a;运行程序后&#xff0c;系统会按书写顺序执行程序中的每一行代码。比如下面的程序 1 #include <stdio.h>2 3 int main()4 {5 6 printf("Hello-1\n");7 printf(&qu…

SwiftUI 4 新功能之掌握 WeatherKit 和 Swift Charts

SwiftUI 4 新功能之掌握 WeatherKit 和 Swift Charts 今年在 WWDC22 上有很多令人兴奋的新框架和 API 让我们投入其中。然而,我对 WeatherKit 和 Swift Charts 感到非常兴奋,因为我们现在终于有了对天气数据和绘制数据集的原生 1 方支持。 在本文中,我们将研究如何将两者结…

iOS开发拓展篇—UIDynamic(捕捉行为)

iOS开发拓展篇—UIDynamic(捕捉行为) 一、简介 可以让物体迅速冲到某个位置&#xff08;捕捉位置&#xff09;&#xff0c;捕捉到位置之后会带有一定的震动 UISnapBehavior的初始化 - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point; …

SwiftUI 完整项目之音乐学习卡片类App 开机引导页 图文列表页 详细设置页(教程含源码)

SwiftUI 完整项目之音乐学习卡片类App(教程含源码) 实战需求 这是一个基本的SwiftUI应用程序,可帮助音乐家了解可用的不同类型的麦克风以及如何最好地应用它们。 开机引导页图文列表页详细设置页本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技…

8.14. JSON Types

8.14. JSON Types8.14.JSON类型JSON data types are for storing JSON (JavaScript Object Notation) data, as specified in RFC 71591. Such data can also be stored as text, but the JSON data types have the advantage of enforcing that each stored value is valid ac…

Tkinter 教程之10个经典程序代码 数字时钟(教程含源码)

Tkinter 是 Python 编程语言中最好的模块之一。它专门用于创建图形用户界面。有了这个模块,我们可以创建一些很棒的程序。在本文中,我们尝试创建一个简单而有趣的程序。我们将特别关注简单的 GUI 以更好地理解 Tkinter。 目录 带有 Tkinter 的clock使用 Tkinter 更改颜色背景…

李洪强漫谈iOS开发[C语言-012]-C语言基本数据类型

// // main.m // 08 - 基本数据类型 // // Created by vic fan on 16/7/16. // Copyright © 2016年 李洪强. All rights reserved. // 基本数据类型 计算机中,C语言中有丰富的数据类型<Mac为标准> 有整数类型 int(4 个字节) short int(2个字节) long int(8个字…