5.C基础_运算符

 运算符概述

相关名词

对于" a=b+c "

  • 这个式子被称为表达式
  • " = "和" + "被称为运算符
  • 参与运算的b、c被称为操作数
  • " + "操作数的个数为2,所以" + "的运算符分类为双目运算符

优先级

1、除法运算符 " / "

除号的两端都是整数时,结果也为整数。

int a = 7/2;// 7/2=3.5,取整数为3,不进行四舍五入

除号的两端有浮点数时,结果为浮点数(自动类型转换)

int a = 7/2.0;// 7/2=3.5 2.0为double型,因此结果也为double型,保留小数

2、取余运算符 " % "

取余运算符的两个操作数只能为整数

下面为取余运算的应用:

2.1 实现多位数的分离

有一个不知多少位的数(比如说123),现在要将其各个位进行分离存入到一个数组中,要求低位存入低地址(比如1存入buf[2]、2存入buf[1],3存入buf[0])。

代码实现如下:

#include <stdio.h>
#include <math.h>
#include <stdlib.h> 

/* 拆分一个整数,将各个位存入数组,第0位存入个位 */
/* 返回值:动态创建的数组首地址,失败返回NULL */
char* Split_Num(int num){
	
	char* Split_Num_point = NULL;
	char* point_tmp = NULL;
	int digit = 1;//传入num的位数
	int i=0;//循环控制变量 
	int num_tmp = num;
	
	/* 1.遍历,直到个位 */
	while(1){
		
		num_tmp/=10;
		if(num_tmp == 0){ //num/10=0代表已经到达了个位  
			break;
		}
		digit++;
	}
	printf("Debug:digit = %d\n",digit);
	
	/* 2.开辟数组空间 */
	//有多少位就开辟多少空间+1,多的1个空间是用来存'\0' 
	Split_Num_point = (char*)malloc(sizeof(char)*(digit+1));
	point_tmp = Split_Num_point; 
	if(Split_Num_point == NULL){
		printf("malloc err\n");
		return NULL;
	}
	printf("Debug:malloc success\n");
	
	/* 3.从最高位开始,获取每一位的值 */
	num_tmp = num;
	printf("Debug:num_tmp = %d\n",num_tmp);  
	point_tmp += digit;//指针偏移到数组末尾
	*point_tmp = '\0';
	point_tmp--;
	for(i=digit-1;i>0;i--){
		*point_tmp = num_tmp/pow(10,i);
		num_tmp = num_tmp%((int)pow(10,i));
		
		printf("Debug:i=%d,*point_tmp = %d\n",i,*point_tmp);
		printf("Debug:i=%d,num_tmp = %d\n",i,num_tmp);  
		point_tmp--;
	}
	*point_tmp = num_tmp;
	printf("Debug:i=%d,*point_tmp = %d\n",i,*point_tmp);
	
	return Split_Num_point;
}

void print_str(char* str){
	
	char* point = str;
	
	while(*point != '\0'){
		printf("%d",*point);
		point++;
	}
}

int main(){
	
	char* p;
	
	p = Split_Num(87123);
	print_str(p);
	
	return 0;
}

代码使用方法:

将一个int类型的数据传入函数Split_Num,最终返回一个char*的动态开辟的数组首地址。数组的最低位为传入数据的最低位,在上述代码中,传入87123,那么*p就是3。

3、自增自减运算符

"++"、" -- "可以放在变量前(前置),也可以放在变量后(后置)

前置:例如++val,代表先对val进行加1,再进行赋值

后置:例如val++,代表先进行赋值,再对val进行加1

int val_1=0;
int val_2=0;

printf("val_1++ = %d,val_1 = %d\n",val_1++,val_1);//先用再加,打印 0,最终val = 1 
printf("++val_2 = %d,val_2 = %d\n",++val_2,val_2);//先加再用,打印 1,最终val = 1 

4、位运算符

4.1 按位取反(~):

按位取反(~)只能用作于整型数据," ~ "的优先级很高,只比" () "低一级 

对于有符号数和无符号数,取反都是一样的,最高位都会从0->1或1->0。

按位取反时需要考虑变量类型的存储内存大小,具体示例如下:

unsigned int a = 0x20; //0010 0000
a = a >> 2;            //0000 1000
a = ~a;                //1111 0111
printf("%x",a);        //因为int为4字节,所以会再前面补0,取反后会全部变成1
//最终结果为0xfffffff7	

4.2 按位异或(^):

按位异或(^)具有0与某个数异或等于它本身的性质,即:0^n=n

按位异或实现原地交换:

#include <stdio.h>

int main(){
	
	int a=0x78;
	int b=0x12;	
	a=a^b;  
	b=a^b;//b=0x78
	a=a^b;//a=0x12
	printf("a=%x,b=%x\n",a,b);	
	/* 运算过程解释 */	
	/*
	a=原a^原b
	
	b=a^原b
	 =(原a^原b)^原b
	 =原a^(原b^原b)
	 =原a^0
	 =原a
	
	a=a^b
	 =原a^原b^b
	 =原a^原b^原a
	 =(原a^原a)^原b
	 =0^原b
	 =原b	
	*/
	return 0;
} 

4.3 移位(<<  >>):

移位(<<  >>)只能用作于整型数据。

对于无符号数,移位后的空位补0。

  • 左移就相当于*2^n,比如0000 0001<<2,就时0x01*2^2 = 4,即:0000 0100
  • 右移就相当于/2^n,比如0000 0100>>2,就时0x04/2^2 = 1,即:0000 0001 

对于有符号数,右移位后符号位正数补0,负数补1(左移不补),其余操作与无符号数一致。

  • 左移(负数):比如1000 0001<<1,这是个负数,所以最高位不补,结果为0000 0010
  • 左移(正数):比如0000 0001<<1,这是个正数,所以最高位不补,结果为0000 0010
  • 右移(负数):比如1000 0001>>1,这是个负数,所以最高位补1,结果为1100 0000
  • 右移(正数):比如0000 0001>>1,这是个正数,所以最高位补0,结果为0000 0000

4.4 按位与、按位或( &  | )

任意数 & 0 = 0,因此按位与(&)常常用作对某一位进行清零

任意数 | 1 = 1,因此按位或( | )常常用作对某一位进行置1

任意数 ^ 1 = 取反,因此按位异或(^)常常用作对某一位进行取反

  • 清0第n位:a &= ~(1<<n)
  • 置1第n位:a |= (1<<n)
  • 取反第n位:a ^= (1<<n)

5、关系运算符

关系运算符就是>、<、==、!=这些。在使用关系运算符时,应该将常量放在左边,变量放在右边,以减少" == "写为" = "时查不出bug的情况

例如应该写为 if(-1==val),而不是 if(val == -1)

6、逻辑运算符

逻辑运算符就是&&、||、! 这些。其中&&、||具有短路特性,即:表达式从左往右执行,若左边已经能决定表达式结果,则后面不再执行。

  • &&短路特性:左边为0时,右边不再执行
  • ||短路特性:左边为1时,右边不再执行

验证例程如下:

int a = 0, b = -1, c = 3, d = 4;
c = a++ && ++ b && d++;
printf(“a = %d\n b = %d\n c = %d\n d = %d\n”, a, b, c, d);

因为a++为先用再加,所以是a=0进行&&运算。0已经能决定&&运算,因此++b、d++都不再运行。最终结果为a=1、b=-1、c=0、d=4

编程规范:

因为短路特性的存在,在编程中应该将最可能为1的表达式放在||左边,最可能为0的表达式放在&&左边,以达到最大程度的使用短路特性,提高代码执行效率。

7、条件运算符

条件运算符的形式为:<条件>?<表达式1>:<表达式2>

  • 若条件为1,值为表达式1的值
  • 若条件为0,值为表达式2的值

验证例程如下:

int x,y=25;
x=70;
y= x++ > 70 ? 100 : 20 ;
printf("x=%d y=%d",x,y); 

因为x++为先用再加,所以是x=70进行>70的判断,结果为假,y被赋值为20。因为x++,所以x值为71。

8、逗号运算符

逗号运算符从左向右执行各个表达式,值为最后一个表达式的值。

验证例程如下:

int x,y,z;
z=(x=y=5,x++);
printf("x=%d,y=%d,z=%d",x,y,z);	

首先运行x=y=5,这是x=5、y=5;再运行x++,因为x++为先用再加,所以表达式值为5而不是6,因此z被赋值为5。最终结果为x=6、y=5、z=5。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值