C语言的操作符

本文详细介绍了C语言中的各种操作符,包括算数、移位、赋值、单目、关系、逻辑、条件和位操作符。重点讨论了算数操作符中的取模和移位操作,以及位操作符的按位与、按位或和按位异或的使用。此外,还提到了赋值操作符、单目操作符和强制类型转换等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.算数操作符

2.移位操作符

3.赋值操作符

4.单目操作符

5.关系操作符

6.逻辑操作符

7.条件操作符(三目操作符)

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

算数操作符     

 除号(/)在运算的时候,如果说是5.0/6.0 那么编译器会给他自定义为双精度的类型,即使定义了单精度的浮点型,会被认为是丢失了精度 ,在5.0或6.0后面加一个f,变为5.0f  6.0f  就会解决这个问题

取模(%) 取余    取余的两个数必须是 整数 相除

移位操作符   (后面有较为全面的总结)                 

左移操作符(<<)   是在n进制中移位    左边丢弃,右边补齐

#include<stdio.h>
int main()
{                   //一个字节8比特 
	int a=3;        00000000 00000000 00000000 00000011 =1*2^1+1*2^0 = 3 
	int b=a<<2;     00000000 00000000 00000000 00001100 =1*2^3+1*2^2+0*2^1 = 12
	printf("%d",b);
	return 0;
 } 

 这个是把a的二进制向左移动2位

00000000 00000000 00000000 00000011 =1*2^1+1*2^0 = 3 
00000000 00000000 00000000 00001100 =1*2^3+1*2^2+0*2^1 = 12

右移操作符 (>>) 

算数右移     右边丢弃,左边补原符号位   (原符号位是1,就补1。是0  就补0)                              逻辑右移      右移丢弃,左边补0  (不管原符号位是多少,都要补0)                                              可能以算数右移为主      

原码,反码,补码(正数的原码 反码 补码相同)

原码:直接根据数值写出二进制                        10000000 00000000

反码:原码的符号位不变,其他的都按位取反   111111111 111111111   符号不变,其他的取反

补码:就是在最低位置上 加1,0000000000010==0000000000011

 位(二进制位)操作符(按位与 &  按位或 |  按位异或^)

按位与:&   a b 两个数的二进制,上下对应,有1 和0 对应的时候,只有上下两个不相等就变为0  都是1 的时候才为 1

#include<stdio.h>
int main()
{
	int a=3;
	int b=5;
	int c=a & b;
	printf("%d",c);
	return 0;
}

得出结果c=1.                                                                                                                                      int a = 3     00000000 00000000 00000000 00000011 

int b = 5    00000000 00000000 00000000 00000101

int c = 1     00000000 00000000 00000000 00000001                                                                     

按位或 : |        两个数的二进制一一对应的时候      如果有1,则为1 如果两个同时为0 的时候则为0

#include<stdio.h>
int main()
{
	int a=2;
	int b=5;
	int c=a|b;
	printf("%d",c);
	return 0; 
}

为c = 7

int a=2     00000000 00000000 00000000 00000010                                                                         int b=5    00000000 00000000 00000000 00000101                                                                         int c=7    00000000 00000000 00000000 000000111

按位异或:^              相同则为0     相异则为1

#include<stdio.h>
int main()
{
	int a=3;
	int b=5;
	int c=a^b;
	printf("%d",c);
	return 0; 
}

int a = 3     00000000 00000000 00000000 00000011                                                                       int b = 5    00000000 00000000 00000000 00000101                                                                       int c= 6      00000000 00000000 00000000 00000110

位操作符的使用方法

在不引用任何变量的情况下,把a=3, b=5交换一下,就是要让a=5  b=3    这种情况下采用按位异或的操作符     

#include<stdio.h>
int main()
{
	int a = 3;
	int b = 5;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("%d,%d",a,b);
	return 0;
}

具体讲,我就不记了,就是转化为二进制然后在去用按位异或的方法(相同为0,不相同为1)的方法去进行计算。害,背过这个交换就行了                                                                    当然,a=a+b ,b=a-b ,a=a-b 这种方法也不是不可以,但是容易溢出,超出他的数据类型,会丢失二进制。

两个相同的数字亦或是0,a ^ a=0     a ^ a ^ a=a

题目    求整数存储在内存中的二进制中的1 有多少个

#include<stdio.h>
int main()
{
	int a=13;//00000000 00000000 00000000 00001101
	int i; //00000000 00000000 00000000 00000001
	int b=0;
	for(i=1;i<=4;i++)
	{
		if(a&1==1)
		{
			a>>1;
			b++;
		}
		else if(!a&1==1)
		{
			a>>1;
		}
	}
	printf("%d",b);
	return 0;
}

总结:1.按位与   &(有0 就是0)  2. 按位或  |  (有1 就是1)    3. 按位异与(相同为0  不同为1)

            1 & 1 = 1                              1 | 1 = 1                                   0 ^ 0 = 0  

             1 & 0 = 0                             1 | 0 = 1                                   1 ^ 1 = 0

             0 & 0 = 0                              0 | 0 = 0                                   1 ^ 0 = 1

题目  把13 的二进制中的倒数第二个0变为1,00000000 00000000 00000000 00001101

a = a | (1 << 4 )   就可以把倒数第二个 0 变为1                                                                                1的二进制为00000000 00000000 00000000 00000001

赋值操作符

  =(赋值操作符)

覆合操作符      +=   /=   %=   &=   |=   ^=   <<=     >>=

单目操作符    只有一个操作符

!   逻辑反操作

-    负值

+    正值

&     取地址

sizeof    操作数的类型长度

~      对一个数的二进制取反   全部按位取反


++     --

(类型)     强制类型转换

!:     int flag=5      printf("%d ",!flag)     结果为 0    因为!flag是假的

sizeof  :   在计算变量名的大小的时候,可以省略掉括号,其他的都不可以了

#include<stdio.h>
int main()
{
	int a = 10;
	printf("%d",sizeof a);
	return 0;
	
}

结果是  4

sizeof(  )的括号里面的表达式是不参与运算的   因为sizeof  仅仅只是去算字节而已

#include<stdio.h>
int main()
{
	int a = -1;
	int b;
	b = ~a;
	printf("%d",b);
	pritnf("%d",a);
	return 0;
}

~     每一个都按位取反的操作符

&  和   *   这两个操作符基本放在一起运算

int *pa = &a  (pa 是指针变量,用来存放a的地址)  int a      * pa的指向类型也应该是int,这个 * 的符号叫做间接访问操作符,通过a里面存的地址,去访问a

#include<stdio.h>
int main()
{
	int a;
	a = 10;
	int *pa = &a; //这里的*pa是 去访问a的空间 ,这里的* 是指针变量
	*pa = 20;     //把a的空间里的东西去做出改变 ,这里的*是操作符
	printf("%d",a);
	return 0; 
}

int *pa 中的* 是指针变量,,而*pa是操作符    一个指针占4个或8个字节

#include<stdio.h>
test1(int arr[])
	{
	   printf("%d",sizeof(arr));	
	}
test2(char ch[])
	{
	   printf("%d",sizeof(ch));
	}
int main()
{
	
	int arr[10] = {0};
	char ch[10] = {0};
	test1(arr);
	test2(ch);
	printf("%d\n",sizeof(arr));
	printf("%d\n",sizeof(ch));  //这里的数组传过去,其实只是传了首元素的地址,只有一个而已
	return 0;                   //一个元素的地址就是一个指针 一个指针的字节是4或者是8
}

类型) 强制类型转换

#include<stdio.h>
int main()
{
	int a=(int)3.14;
	printf("%d",a);
	return 0;
}

输出结果是3  在3,14前加(int) 去重新定义 会输出3 这个整形

关系操作符

>  >=  <  <=  !=  ==

逻辑操作符

&&  ||   !

&&    左边为假 右边不要算

如果这里面有一个是假的话,那么结果就为0  如x&&y x=0的话,结果是0 后面的就不运算了

#include<stdio.h>
int main()
{
	int i=0,a=0,b=2,c=3,d=4;
	i = a++ && ++b && d++;
	printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
	return 0;
}

这里运行出来的结果是 1 2 3 4

因为a++是先运行再加1 所以 a刚开始是0  那&&  ++b,或者是&& d++ 那就没有什么必要再继续下去了,b 和 d就不用再去费时间运算了    但 a是参与了运算的,所以a++还是要去算的

如果把a改成1

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

运行出的结果是 2 3 3 5,a b c d 都参与了运算的

||    左边为真 右边不要算

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

结果是2 2 3 4   这里

如果a=0,,a++ || ++b || d++   先使用a a是0; 0 || ++b  0为假   继续看++b ++b 等于3  3为真,所以后面的就不计算了      结果为1 3 3 4

条件操作符(三目操作符)  if   else  ==(a>5 ? 1 : 2);

#include<stdio.h>
int main()
{
	int a=3;
	int b=0;
	if(a>5)
	{
		b=1;
	}
	else
	b=2;
	printf("%d %d",a,b);
	return 0;
#include<stdio.h>
int main()
{
	int a=3;
	int b=0;
	b = (a>5 ? 1: 2); 
	printf("%d %d",a,b);
	return 0;
}

 这两个代码的结果是一样的,但是下面的那一个 b = (a>5? 1: 2)

解释:a大于5 吗?要是(if)a>5 b 的赋值就是1: 如果不的话(else)b的赋值就是2

逗号表达式:括号里的从左到右运算,但是最后的结果就是最后一个逗号后面的

#include<stdio.h>
int main()
{
	int a = 3;
	int b = 5;
	int c = 0;
	int d = (c = 5,a = c + 5,b = a - 4,c+=5);
	printf("%d",d);
}

最后的结果应该等于5  因为从c = 5 开始,到c+=5结束,最后的 C 就是10了

如果是if语句的逗号表达式         if(a = b + 1,c = a / 2,d > 0) 判断是否进语句的是最后那个d > 0是否满足的条件 但是 这个 d 可能受到括号内前面的代码的影响

#include<stdio.h>
int main()
{
	a = get_val;//有两块重复代码,会出现冗余现象 
	count_val(a);
	while(a > 0)
	{
		a = get_val();
		count_val(a);
	}                   
}


#include<stdio.h>
int main()
{
	int a;
	while(a = get_val(),count_val(a),a > 0)
	{
		
	}
 } 

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

1.下标引用操作符 [  ]  就是数组的[  ]

arr[ 有具体的某一个元素 ]     下标引用操作符   

3 + 5    3和5是操作数,而这个的操作数是  arr ,4(就是arr和4)

操作数 :一个数组名 + 一个索引值

2、函数调用操作符

#include<stdio.h>                  //Add函数 
int Add(int x, int y)              //Add是函数名 x,y是函数参数(x,y也叫做传参) int是返回类型 
{                                  //{}是函数体 
    
    int z=0;
    z=x+y;
    return z;
}//--------------------------------------- 
int main()
{
    int a=10;
    int b=20;
    int sum = Add(a,b);      //这里的(   ),就是函数调用操作符
    printf("%d",sum);
    return 0;
}

操作数 : 函数名,+ 函数的参数     Add  +  a  +b 

3 . 结构成员的访问操作符

结构体:一组数据当中,有不同的数据类型,如 记录一个班级的学生的成绩,学生的名字是字符                  ( char)类型,学生的成绩是浮点型(float)数据不同,不能用同一个数组来定义这一组                数据,所以引用了结构体  struct(也是一种数据类型)   来存放不同类型的一组数据,

          一般结构为  struct  结构体{

                                                       成员列表     }

           还是拿上面的班级举例子      结构体是 全班同学的成绩(class)成员列表是学生的名字              (name) 和学生的成绩(grade)

              struct  class

                                  {     char name[ 40]                                                                                      

                                        float grade[40]     }                                                                                 
 

  .     结构体 . 成员名

#include<stdio.h>
struct book
	{
		char name[20]; //书名 
		char id[20];   //编号
		int  price;    //价格 
	};
int main()
{
	struct book b = {"c语言","20221103",55};
	printf("书名:%s",b.name);
	printf("编号:%s",b.id);
	printf("价格:%d",b.price);
	return 0;
	
} //这里结果是初始值为无效定义,不知道为啥,等一会再解决

这里结果是初始值为无效定义,不知道为啥,等一会再解决 !!!!!!!!!!!!

晓得了,那个{   },打成(   )

#include<stdio.h>
struct book
	{
		char name[20]; //书名 
		char id[20];   //编号
		int  price;    //价格 
	};
int main()
{
	struct book b = {"c语言","20221103",55};
	*pb = &b;                         //结构体指针,指向的是b的内容 
	printf("书名:%s",(*pb).name);
	printf("编号:%s",(*pb).id);
	printf("价格:%d",(*pb).price);
	return 0;
	
}

->     结构体指针 ->成员名

#include<stdio.h>
struct book
	{
		char name[20]; //书名 
		char id[20];   //编号
		int  price;    //价格 
	};
int main()
{
	struct book b = {"c语言","20221103",55};
	struct book *pb = &b;                        //结构体指针,指向的是b的内容 
	printf("书名:%s",pb->name);
	printf("编号:%s",pb->id);
	printf("价格:%d",pb->price);
	return 0;
	
}

如果拿到的不是结构体变量而是结构体的指针,那么依然可以通过结构体的指针来找到结构体的成员

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值