C语言中的运算符与表达式

运算符与表达式

什么是运算符?这里举一个例子:
int x,y		//这是声明两个变量

x+y  x-y  x==y x=y
上面的“+、-、==、=”就是运算符,还有很多其他的运算符,下面我们会一一介绍。

什么是表达式:
(x+y)*(x-y)
这就是一个简单的表达式,无论这个表达式多么复杂,他最后都是计算出一个结果。

不同类型表达式的计算

例如:

#include <stdio.h>		//头文件

void main()				//程序入口
{
	char x = 1;			//把1赋给char类型的x
	
	short y = 3;		//把3赋给short类型的y

	int z = x+y;		//把x+y返回到int类型的z里
	printf("%d\n",z);	//以十进制输出结果到控制台
	
	return;				//程序结束
}

这里是两个变量x,y外加一个返回值z,它们分别是三个类型:char、short、int,那么他们是怎么运算的,我们直接去反汇编看一下就行了:
在这里插入图片描述
这里可以看到,程序把x的值存到了eax中,把y的值存到了ecx中,这两个寄存器都是四个字节的,也就是说,在进行相加之前先转换成了int类型,那么int类型又是四个字节,也就是先统一类型,再进行计算,这里统一类型是有先后级的。

	char  <  short  <  int  <  float  <  double 

这里总结一下:

  • char类型跟short类型运算,最后都会转为int类型。
  • 计算最终结果的类型由表达式中数据宽度最大的那个变量决定。

常见的运算符

算术运算符
+  -  *  /  %  ++  --
加减乘除、取余、自加、自减

这里我们主要说一下这个++、–,先上一段代码:

#include <stdio.h>		//头文件

void main()				//程序入口
{
	int x = 1;			//把1赋值给int类型的x里

	x++;				//在当前x的值的基础上加1	

	printf("%d\n",x);	//以十进制输出结果到控制台
	
	return;				//程序结束
}

运行结果:
在这里插入图片描述
那么++是自加1,–自然就是减1了:

#include <stdio.h>		//头文件

void main()				//程序入口
{
	int x = 1;			//把1赋值给int类型的x里

	x--;				//在当前x的值的基础上减1	

	printf("%d\n",x);	//以十进制输出结果到控制台
	
	return;				//程序结束
}

运行结果:
在这里插入图片描述
这个 ++与–可以放在变量前与变量后,放前放后计算出来的结果都是一样的,但是执行顺序有所不同:

	++在前,先自加在进行计算。
	++在后,先进行计算再自加。

改一下代码:

#include <stdio.h>		//头文件

void main()				//程序入口
{
	int x = 1;			//把1赋值给int类型的x里

	x++;				//x自加1
	
	int y = x;			//把x的值赋给y
	
	printf("%d\n",y);	//输出结果到控制台

	return;				//程序结束
}

运行结果:
在这里插入图片描述
反汇编看一下是怎么传值的:
在这里插入图片描述
先看这两行代码:

int x = 1;
x++;

这是它的汇编指令:

mov         dword ptr [ebp-4],1
mov         eax,dword ptr [ebp-4]
add         eax,1
mov         dword ptr [ebp-4],eax

先把1赋给ebp-4,再把ebp-4赋给eax,随后eax再加1,再把1赋值给ebp-4,这一波操作之后x的值就是2了。

接着是这两行代码:

int y = x;
printf("%d\n",y);

这里把2又赋值给了eax,接着把eax赋给ebp+8,接着又把ebp-8赋给了eax,然后eax压栈,输出结果。

mov         eax,dword ptr [ebp-4]
mov         dword ptr [ebp-8],eax
mov         eax,dword ptr [ebp-8]
push        eax
push        offset string "%d\n" (00422fa4)
call        printf (00401
090)
add         esp,8

再来看看++在前会是什么样的结果:

#include <stdio.h>		//头文件

void main()				//程序入口
{
	int x = 1;			//把1赋值给int类型的x里
	
	printf("%d\n",++x);	//进行自加然后输出结果到控制台

	return;				//程序结束
}

反汇编:
在这里插入图片描述
这里可以清楚的看到,程序是先进行了自加,在计算的结果,然后输出,这就是++在前与在后的区别,–同理。

关系运算符
<  <= >  >= !=  ==
小于、小于等于、大于、大于等于、等于、不等于
关系运算符的值只能是0和1
关系运算符的值为真时,结果为1
关系运算符的值为假时,结果为0

例子:

#include <stdio.h>			//头文件

void main()					//程序入口
{
	int a = 10;				//赋值

	int b = 20;			

	int c = a<=b;			//把a<=b的结果返回给c
	
	if(a<=b)					//进行判断
	{
		printf("正确!\n");	//输出判断结果
	}
	else					//否则输出另一种结果
		printf("错误!\n");
	return;					//程序结束
}

看一下运行结果:
在这里插入图片描述
为什么说结果只有0和1呢?下个断点看一下C里的值就知道了:
在这里插入图片描述
如果正确就是1,跟我们程序运行后的结果一致(结果为真)。

逻辑运算符
&&  ||  !
与、或、非
x>y && x<z			只有一个结果
x>y || x<z			只有一个结果

例子:

#include <stdio.h>			//头文件

void main()					//程序入口
{
	int x = 10;				//赋值

	int y = 20;			

	int z = 30;			
	
	int r = x>y && x<z;		//进行与运算,两数相与,同真则真
	
	return;					//程序结束
}

我们去反汇编看一下r的值是多少:
在这里插入图片描述
值为0,很明显这是正确的。

位运算符
<<  >>  ~  |  ^  &
左移、右移、非、逻辑或、异或、逻辑与

例子:

x = 1
y = 2

//与运算,相对应的位都为1的时候,结果才为1
0000 0001
0000 0010 &
-----------
0000 0000

//或运算,相对应的位只要有一个为1,结果就为1
0000 0001
0000 0010 |
-----------
0000 0011

//异或运算,只有两个位不一样的时候,结果为1,反之为0
0000 0001
0000 0010 ^
-----------
0000 0011

//非运算,取反即可
0000 0001 ~
-----------
1111 1110

用程序验证一下:

#include <stdio.h>					//头文件

void main()							//程序入口
{
	int x = 1;						//赋值
	int y = 2;

	printf("与运算:%d\n",x&y);		//输出相对应的结果
	printf("或运算:%d\n",x|y);
	printf("异或运算:%d\n",x^y);
	printf("非运算:%d\n",~x);
	
	return;							//程序结束
}

运行结果:
在这里插入图片描述

赋值运算符
=   拓展赋值

例子:

#include <stdio.h>		//头文件

void main()				//程序入口
{
	int z = 1;			//把1赋值给z
	
	z += 2;				//相当于 int z = z+2;

	printf("%d\n",z)	//输出结果

	return;				//程序结束
}

运行结果:
在这里插入图片描述

运算符的优先级

这里的优先级跟小学数学一样,先算乘除,再算加减,有括号先算括号里的。

例子:

#include <stdio.h>		//头文件

void main()				//程序入口
{
	int x;				//声明变量
	x = 2+3*4-8/2		//赋值
	
	printf("%d\n",x);	//输出结果
	return;				//程序结束
}

运行结果:
在这里插入图片描述

发布了60 篇原创文章 · 获赞 68 · 访问量 8391

猜你喜欢

转载自blog.csdn.net/qq_43573676/article/details/104932587