c语言之系统的认识操作符

                                                                        -

目录

                                                                        -

1.算术操作符

2.移位操作符

3.位操作符(只适用于整形)

 4.赋值操作符(=)

5.单目操作符

6.关系操作符

7.逻辑操作符

8.条件操作符

9.逗号表达式

10.下标引用,函数调用和结构成员

11.表达式求值

1.隐式类型转换

2.算数转换(若类型的大小大于等于整形)

3.操作符的属性


1.算术操作符

+   -   *   /   %

 / 

整数的除法  1/2->0

浮点数的除法 1.0/2->0.5

若想用/实现浮点数除法则/号两边至少有一个小数

%:计算的是整除后的余数,取模操作符的的两端必须是整数

2.移位操作符

>>右移操作符      

<<左移操作符      移动的是二进制位

移位操作符只针对整型数

ps:正的整数的原码·反码·补码相同;负的整数的原码·反码·补码需要计算

反码 : 原码最高位不动,其余位按位取反得到反码

补码 : 反码加1,得到补码
整数在内存中存的是补码

二进制在整数中的三种形式
//7
00000000000000000000000000000111//原码  最高位为0表示整数
00000000000000000000000000000111//反码
00000000000000000000000000000111//补码
//-7
10000000000000000000000000000111//原码  最高位为1表示负数
11111111111111111111111111111000//反码  原码最高位不动,其余位按位取反得到反码
11111111111111111111111111111001//补码  反码加1,得到补码
//整数在内存中存的是补码
#include<stdio.h>//左移操作符
int main()
{
	int a=7;
	int b=a<<1;//左边丢弃,右边补零
	printf("%d\n",a);
	printf("%d\n",b);
	return 0;
}
7
14

--------------------------------
Process exited after 0.00511 seconds with return value 0
请按任意键继续. . .
#include<stdio.h>//右移操作符
int main()
{
	int a=7;
	int b=a>>1;
	printf("%d\n",a);
	printf("%d\n",b);
	return 0;
}
7
3

--------------------------------
Process exited after 0.07812 seconds with return value 0
请按任意键继续. . .

右移操作符分为

算数位移:右边丢弃,左边补原符号位

逻辑位移:右边丢弃,左边补零                          采用的位移方式取决于编辑器
 值得注意的是对于位移操作符,不要移动负数位,这个是标准位定义的

3.位操作符(只适用于整形)

&:按(2进制)位与         |:按(2进制)位或          ^:按(2进制)位异或

&:对应的2进制位按位与,两个二进制位中如果有0,则对应的结果为0,同时为1时按位与的结果才为1

|:对应的2进制为只要有1则为1,两个同时为0时才为0

^:相同为0,相异为1 

#include<stdio.h>//按与的认识
int main()
{
	int a=3;
//00000000000000000000000000000011--   3的补码
	int b=-5;
//11111111111111111111111111111011--   5的补码
	int c=a&b; 
//对应的2进制位按位与,两个二进制位中如果有0,则对应的结果为0,同时为1时按位与的结果才为1
//所以c的2进制为
//00000000000000000000000000000011
	printf("%d\n",c);
	return 0;
}

3

--------------------------------
Process exited after 0.08177 seconds with return value 0
请按任意键继续. . .
#include<stdio.h>//按位或的认识
int main()
{
	int a=3;
	int b=-5;
	int c=a|b;//对比3与-5的补码,对应的2进制为只要有1则为1,两个同时为0时才为0
//00000000000000000000000000000011---3的补码
//11111111111111111111111111111011--- -5的补码
//11111111111111111111111111111011---对应的a|b的二进制(补码)
//11111111111111111111111111111010---c的原码
//10000000000000000000000000000101---对应的反码
	printf("%d\n",c);
	return 0;
}
-5

--------------------------------
Process exited after 0.07843 seconds with return value 0
请按任意键继续. . .
#include<stdio.h>//异或的认识
int main()
{
	int a=3;
	int b=-5;
	
	int c=a^b;//相同为0,相异为1 
	//00000000000000000000000000000011---3的补码
    //11111111111111111111111111111011--- -5的补码
    //11111111111111111111111111111000---  对应的补码
	//11111111111111111111111111110111---   对应的反码
	//10000000000000000000000000001000---     对应的原码。即打应的值 
	printf("%d\n",c);
	return 0;
}
-8

--------------------------------
Process exited after 0.08288 seconds with return value 0
请按任意键继续. . .

关于^的运用(不创建变量,实现交换两个变量的值)

int a=3;                                             3^3=0     0^5=5     则3^3^5=5

int b=5;                 (二进制的后三位) 011         000             3^5^3=5

a=a^b; a=3^5                                    011         101             可知^支持交换律

b=a^b;3^5^5----b=3                           000         101

a=a^b;3^5^3----a=5                           

 4.赋值操作符(=)

区分赋值与初始化

int a=0//初始化
a=999//赋值

赋值可以连续使用

int a=10;
int x=0;
int y=20;
a=x=y+1;//分两步1   x=y+1
               2   a=x

复合赋值符

+=   -=   *=…………………………
int a=1;    a+=b; 等价于   a=a+b
int b=9;    

5.单目操作符

目录

单目操作符:只有一个操作数
!        逻辑取反
-        负值
+        正值
&        取地址
sizeof   操作数的类型长度
~        对一个数的二进制按位取反
--       前置`后置--
++       前值·后置++
*        间接访问操作符(解引用操作符)
(类型)   强制转换类型

关于单目操作符的理解

---------------------------------------
!的理解
#include<stdio.h>
int main()
{
	int flag=3;
	if(flag)//flag为真进入 
	{
	}
	if(!flag)//flag为假进入 
	{
	}
	return 0;
} 
---------------------------------------
-的理解
#include<stdio.h>
int main()
{
	int a=-10;
	int b=-a;
	printf("%d\n",a);
	printf("%d\n",b);
	return 0;
} 
-10
10


Process exited after 0.08284 seconds with return value 0
请按任意键继续. . .
---------------------------------------
&的理解
#include<stdio.h>
int main()
{
	int a=-10;
	printf("%p\n",&a);//取出变量在内存中的起始地址 
	return 0;//可知a占4个字节,而&a只是取出了第一个字节的地址 
} 
000000000062FE1C


Process exited after 0.07649 seconds with return value 0
请按任意键继续. . .
---------------------------------------
sizeof的理解(计算的是变量所占内存空间的大小,单位是字节)
ps:sizeof是操作符不是函数
#include<stdio.h>
int main()
{
	int a[]={1,2,3,4,5,6,7,8,9,0};
	printf("%d\n",sizeof(a));//存放数组名时,计算的是整个数组的大小
	return 0;
} 
40


Process exited after 0.0728 seconds with return value 0
请按任意键继续. . .
---------------------------------------
~的理解
#include<stdio.h>
int main()
{
    int a=0;//~是二进制按位取反
	//00000000000000000000000000000000-----补码
	//11111111111111111111111111111111----->~a
	//11111111111111111111111111111110----->~a反码
    //10000000000000000000000000000001----->~a的原码
	printf("%d\n",~a); 
	return 0;
} 
-1


Process exited after 0.1595 seconds with return value 0
请按任意键继续. . .
~的应用
#include<stdio.h>
int main()
{
    int a=13;//~是二进制按位取反
	//00000000000000000000000000001101    把第二位0改成一 
    //00000000000000000000000000000010理解为1<<1  a按位或1<<   
    //00000000000000000000000000001111     即可完成对第二位的改变
	//对其中的某一个为该变的时候,可以对要改变位数按位或上1<<n,n位要改变的位数 
	a|=(1<<2);
	printf("%d\n",a); 
	return 0;
} 
13

Process exited after 0.2208 seconds with return value 0
请按任意键继续. . .
---------------------------------------
对++于--的理解
#include<stdio.h>
int main()
{
    int a=3;
    int b=++a;//前置++,先++后使用 
	printf("%d\n",a);
	printf("%d\n",b); 
	return 0;
} 
4
4


Process exited after 0.1716 seconds with return value 0
请按任意键继续. . .
#include<stdio.h>
int main()
{
    int a=3;
    int b=a++;//后置++,先使用后 ++
	printf("%d\n",a);
	printf("%d\n",b); 
	return 0;
} 
4
3


Process exited after 0.176 seconds with return value 0
请按任意键继续. . .
---------------------------------------
对*(解引用操作符)的理解
#include<stdio.h>
int main()
{
    int a=10;
    int *p=&a;//p的类型为int*,是一个指针变量 
    *p=20;//对p进行解引用,或者说通过p里面的地址找到他所指向的对象 
	printf("%d\n",a);
	return 0;
}
20

Process exited after 0.1633 seconds with return value 0
请按任意键继续. . .
---------------------------------------
对()强制类型转换的理解
#include<stdio.h>
int main()
{
    //int a=3.14;类型不一致可能会丢失数据 
    int a=(int)3.14;
	printf("%d\n",a); 
	return 0;
} 
3

Process exited after 0.1763 seconds with return value 0
请按任意键继续. . .

对*的扩展,或者说*p等价于a

6.关系操作符

目录

>
>=
<=
!=    用于测试不相等
==    用于测试相等
if('abc'=='abcdefg')//这样写并不是在比较两个字符串的内容,这样写是在比较这两个字符串的地址
两个字符串比较相等应该用库函数strcmp()

7.逻辑操作符

&&:逻辑与

||:逻辑或

#include<stdio.h>
int main()
{
    int a=9;
	int b=0;
	int c=a&&b;//a或b都为真时结果为真
	int d=a||b;//a或b有一个为真时结果为真
//引用&&或||时只有两种结果0(假)和1(真)
	printf("%d%d\n",c,d); 
	return 0;
} 
#include<stdio.h>//关于&&的理解
int main()
{
    int i=0,a=0,b=2,c=3,d=4;
    i=a++&&++b&&d++;//当有结果为0的表达式出现时,后面就都不会继续运行
    printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
	return 0;
} 
a=1
b=2
c=3
d=4

--------------------------------
Process exited after 0.1574 seconds with return value 0
请按任意键继续. . . 
#include<stdio.h>//对||的理解
int main()
{
    int i=0,a=1,b=2,c=3,d=4;
    i=a++||++b||d++;//当有结果为1的表达式出现时,后面就不继续运行
    printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
	return 0;
}
a=2
b=2
c=3
d=4

--------------------------------
Process exited after 0.06952 seconds with return value 0
请按任意键继续. . .

8.条件操作符

表达式1?表达式2:表达式3

若表达式1为真,则计算表达式2,表达式3跳过

若表达式1为假,则计算表达式3,表达式2跳过

(a>5?b=3:b=-3)
等价于 
if(a>5)
        b=3;
 else
        b=-3;

可以用条件表达式来比较两个数的大小

9.逗号表达式

(就是用逗号隔开的的多个表达式)

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

#include<stdio.h>
int main()
{   
    int a=1;
    int b=2;
    int c=(a>b,a=b+10,b=a+1); 
    printf("a=%d\nb=%d\nc=%d\n",a,b,c); 
	return 0;
} 
a=12
b=13
c=13

--------------------------------
Process exited after 0.07875 seconds with return value 0
请按任意键继续. . .
if(a=b+1,c=a/2,d>0)//起作用的是左后一个语句,但a=b+1,c=a/2也会计算,并改变a于c的值

10.下标引用,函数调用和结构成员

int a[10]={0};
    a[7]=8;//[]为操作符,下标引用 
    a即数组首元素的地址
    a+7即跳过7个元素,指向了第8个元素
    a[7]等价于*(a+7)等价于*(7+a)等价于7[a]
----------------------------------------------
int add(int x,int y)
{
	//函数定义 
	return x+y;
 } 
 int main()
 {
 	int a=10;
 	int b=20;
 	//函数调用 
 	int c=add(a,b);//()就是函数调用操作符 
 	return 0;
 }
----------------------------------------------
#include<stdio.h> //关于结构成员操作符
#include<string.h> 
struct stu
{
	char name[20];
	int age;
	double score;
 };
 void set_stu(struct stu* ps)
 {
 	(*ps).age=20;//等价于ps->age=20;
 	strcpy((*ps).name,"zhangsan");//strcpy(ps->name,"zhangsan");
 	(*ps).score=100.0;//ps->score=100.0;
 }
 void print_stu(struct stu ss)
 {
 	printf("%s %d %lf\n",ss.name,ss.age,ss.score);
 }
 int main()
 {
 	struct stu s={0};
 	set_stu(&s);
 	print_stu(s);
 	return 0;
 }

11.表达式求值

1.隐式类型转换

c语言的整形算数总是至少以缺省整形的精度来进行的,为了获得这个精度,表达式中的字符和短整型操作数在使用前被转换为普通整形,这种转换称为整形提升

以下的例题为字节大小小于整形的类型(char)(short)

#include<stdio.h> 
int main()
{      
 	char a=5;
 	char b=126;
 	char c=a+b;//char类型的大小达不到一个整形字节的大小,在进行计算时先将变量a,b转换为整形再参与运算 
 	return 0;
}

如何进行整形提升?

(整形提神时按照变量的数据类型的符号来提升的)

#include<stdio.h> 
int main()
{   char c=-1;
//-1本身是整数拥有4个字节,32个比特位
//-1的原码10000000000000000000000000000001
//-1的反码11111111111111111111111111111110 
//-1的补码11111111111111111111111111111111 
//11111111是存放在c中的二进制(从右边开始,取出8个比特位) 
//在计算时要进行整形提升,最高位为符号位,符号位为1表示为负数,为0表示正数
// 整形提升时在高位补充符号位 
//提升后的c 11111111111111111111111111111111 
 	return 0;
}

ps(对于整数类型,在内存中存储的都是它的补码,而字符类型也归类于整形,原因是:字符在存储的时候存的是它的ASCII码值,ASCII码值是整数)

关于整形提升的例题

#include<stdio.h> 
int main()
{   
    
char a=5;
    //00000000000000000000000000000101--5的补码
	//00000101--a中存储的5的二进制 
	
char b=126;
	//00000000000000000000000001111110--126的补码
	//01111110 --b中存储的123的二进制 
	
char c=a+b;
	//a+b达不到一个整形的大小,进行整形提升
	//提神后的二进制   a:00000000000000000000000000000101
	//b:00000000000000000000000001111110  
	//a+b:00000000000000000000000010000011 
	//c中也是只能存储8个比特位
	//c:10000011
    
printf("%d\n",c);
 	return 0;
}
-125

--------------------------------
Process exited after 0.1791 seconds with return value 0
请按任意键继续. . .
ps:无符号整形提升,高位补0


#include<stdio.h> 
int main()
{   
    char c=1;
    printf("%u\n",sizeof(c));
    printf("%u\n",sizeof(+c));//+c为表达式,表达式在使用时发生整形提升
    printf("%u\n",sizeof(-c));
 	return 0;
}
1
4
4

--------------------------------
Process exited after 0.156 seconds with return value 0
请按任意键继续. . .

2.算数转换(若类型的大小大于等于整形)

如果某个操作数的各个操作数属于不同的类型,那么除非其中一个操作数的转换位另一个操作数

的类型,否则操作就无法进行,下面的层次体系称为寻常算数转换

ps:转换是向上转换的(向大的转换),例如float类型与int类型,会把int类型转换为float类型,再比如,float类型与double类型,会把float类型转换为double类型

3.操作符的属性

1.操作符的优先级

2.操作符的结合性

//两个相邻的操作符先执行那个?取决于他们的优先级,如果两者的优先级相同,取决于他们的结合性

3.是否控制求值顺序

表 2 列出优先级次序下,所有 C 语言运算符的优先级和结合律。
 

 运算符优先级和结合律
优先级运算符结合律
1后缀运算符:[]    ()    ·    ->    ++    --(类型名称){列表}从左到右
2一元运算符:++    --    !    ~    +    -    *    &    sizeof_Alignof从右到左
3类型转换运算符:(类型名称)从右到左
4乘除法运算符:*    /    %从左到右
5加减法运算符:+    -从左到右
6移位运算符:<<    >>从左到右
7关系运算符:<<=    >>=从左到右
8相等运算符:==    !=从左到右
9位运算符 AND:&从左到右
10位运算符 XOR:^从左到右
11位运算符 OR:|从左到右
12逻辑运算符 AND:&&从左到右
13逻辑运算符 OR:||从左到右
14条件运算符:?:从右到左
15赋值运算符:
     =         +=        -=       *=       /=      %=       &=       ^=      |=   
   <<=      >>=
从右到左
16逗号运算符:,从左到右

     关于问题表达式(没有办法确定唯一的计算路径)

                                                                                                                                                                         

#include<stdio.h> //问题表达式的例子,以下代码在不同的编译器的运行结果是不同的
int main()
{   
    int i=10;
    i=i-- - --i * (i = -3) * i++ + ++i;
    printf("%d\n",i);
 	return 0;
}
//以下程序也是一个问题表达式
#include<stdio.h> 
int fun()
{
	int count =1;
	return ++count;
}
int main()
{   
    int i=10;
    i=fun()-fun()*fun;//无定法确定先调用那个函数
    printf("%d\n",i);
 	return 0;
}

                                                                                                                                                                                                                                                                                                                                                                                                                             

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值