全面解析C语言操作符,一切操作都在掌握之中

发布时间:2024年01月18日

算术操作符

 + - * / %

1.对于 / 操作符,如果两个操作数都是整数,执行整数除法;只要有一边是浮点数就是浮点数的除法
2.操作符 % 为取余,两边的数必须都是整数,不能为浮点数。剩下的几个操作符都可以作用于整数和浮点数。

移位操作符

<< 左移操作符
>> 右移操作符

1.操作数只能是整数
2.移动的是二进制

计算机中都是由二进制表示信息的,整数二进制有三种表示形式:原码、反码、补码
1.正整数的原码、反码、补码都是相同的
2.负整数的原码、反码、补码需要计算

1.无论该整数是正的还是负的都可以写出原码:根据正负直接写出的二进制序列就是原码。
2.十进制到二进制的转化方法:除2取余,逆序排列。

假如我们这里给个 int a = 15,15的二进制是1111,一个整型占4个字节,也就是32位,所以前28位都是0。二进制第一位是符号位,0为正,1为负。

int a = 15;
// 0000 0000 0000 0000 0000 0000 0000 1111   原码
// 0000 0000 0000 0000 0000 0000 0000 1111   反码
// 0000 0000 0000 0000 0000 0000 0000 1111   补码
int a = -15;
// 1000 0000 0000 0000 0000 0000 0000 1111   原码
// 1111 1111 1111 1111 1111 1111 1111 0000   反码(符号位不变,按位取反)
// 1111 1111 1111 1111 1111 1111 1111 0001   补码(按位取反,末位加1(反码加1)/从右往左遇见的第一个1不变,前面按位取反)

整数在计算机内存中存储的是补码,计算的时候使用补码计算。
所以移位移动的是二进制序列的补码

#include<stdio.h>

int main()
{
	int a = 15;
	int b = a >> 1; //右移
	printf("%d\n", b);
	return 0;
}

右移操作符

右移运算分为两种:逻辑右移(右边丢弃,左边补0);算术右移(右边丢弃,左边补符号位)

左移操作符

左边丢弃,右边补0

不要移动负数位,标准未定义

位操作符

与移位操作符一样都是操作二进制
位操作符的操作数必须是整数

& 按位与

对应二进制位有0则0,全1为1

#include<stdio.h>

int main()
{
	int a = 3;
	// 0000 0000 0000 0000 0000 0000 0000 0011  原码
	// 0000 0000 0000 0000 0000 0000 0000 0011  补码
	int b = -5;
	// 1000 0000 0000 0000 0000 0000 0000 0101  原码
	// 1111 1111 1111 1111 1111 1111 1111 1011  补码
	printf("%d\n", a & b); // 有0则0,全1为1
	// 0000 0000 0000 0000 0000 0000 0000 0011
	// 1111 1111 1111 1111 1111 1111 1111 1011
	// 0000 0000 0000 0000 0000 0000 0000 0011 结果 3
	return 0;
}

| 按位或

对应二进制位有1则1,全0为0

#include<stdio.h>

int main()
{
	int a = 3;
	// 0000 0000 0000 0000 0000 0000 0000 0011  原码
	// 0000 0000 0000 0000 0000 0000 0000 0011  补码
	int b = -5;
	// 1000 0000 0000 0000 0000 0000 0000 0101  原码
	// 1111 1111 1111 1111 1111 1111 1111 1011  补码
	printf("%d\n", a | b); // 有1则1,全0为0
	// 0000 0000 0000 0000 0000 0000 0000 0011 
	// 1111 1111 1111 1111 1111 1111 1111 1011 
	// 1111 1111 1111 1111 1111 1111 1111 1011 补码
	// 1000 0000 0000 0000 0000 0000 0000 0101 -5
	return 0;
}

^ 按位异或

对应的二进制位不同为1,相同为0

#include<stdio.h>

int main()
{
	int a = 3;
	// 0000 0000 0000 0000 0000 0000 0000 0011  原码
	// 0000 0000 0000 0000 0000 0000 0000 0011  补码
	int b = -5;
	// 1000 0000 0000 0000 0000 0000 0000 0101  原码
	// 1111 1111 1111 1111 1111 1111 1111 1011  补码
	printf("%d\n", a ^ b); //不同为1,相同为0
	// 0000 0000 0000 0000 0000 0000 0000 0011 
	// 1111 1111 1111 1111 1111 1111 1111 1011 
	// 1111 1111 1111 1111 1111 1111 1111 1000 补码
	// 1000 0000 0000 0000 0000 0000 0000 1000 -8
	return 0;
}

不使用中间变量,实现两个数的交换(按位异或)

#include <stdio.h>

int main()
{
	int a = 3;
	int b = 5;
	/*
	常规做法
	int tmp = a;
	a = b; 
	b = tmp;
	*/

	//不允许使用中间变量
	/*
	a = a + b; //把和放到a中
	b = a - b; //b为和减去b
	a = a - b; //a为和减去b
	缺陷:a和b很大,二者的和会超过int的范围
	*/

	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	// a^a  0
	// a^0  a
	// a = 3;
	// b = 5;
	// a^b^a ?
	// a 0011
	// b 0101
	// a^b 0110  
	// a^b^a 0110 0011  —— 0101  —— b
	// a^a^b a^a=0 0^b=b
	// a^b^a = a^a^b ,交换律
	printf("%d %d\n", a, b);
	return 0;
}

赋值操作符

赋值操作符中除了**=**外,还有很多个复合赋值操作符, +=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=

单目操作符

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

!逻辑取反

可以理解为把真的变成假的,把假的变成真的

#include<stdio.h>

int main()
{
	int x = 0;
	if (x == 0)
		printf("hello\n");
	if (!x)
		printf("world\n");
	if (x)
		printf("!\n");
	return 0;
}

在上述代码中,有三个条件语句,第一个当x0,输出hello;第二个0为假,非0为真,所以 !x为真,输出world;第三个0为假,非0为真,所以x为假,不输出 !

在这里插入图片描述

+ -

这里的 +-,是正值和负值的意思,并不是加和减的意思,-1的负号就是单目操作符,它的操作数只有一个;2-1的减号是双目操作符,它的操作数有两个,分别是21

& *

& 为取地址, * 不是乘的意思,它是间接访问操作符,也称作解引用操作符,两者通常应用于指针。

#include<stdio.h>

int main() 
{
	int a = 1;
	int* pa = &a; 
	//&a将a的地址取出来,放到pa变量中,类型是int *
	*pa = 2; //间接访问操作符,通过pa中存放的地址找到指向的内容或者空间
	int b = *pa;
	return 0;
}

在这里插入图片描述

sizeof

sizeof是操作符,不是函数。它可以求变量或者类型所占空间的大小,单位是字节。

#include<stdio.h>

int main()
{
	int a = 1;
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof a);
	//printf("%d\n", sizeof int);错误写法

	return 0;
}

除此之外,sizeof还可以计算数组的大小,单位同样是字节。

#include<stdio.h>

int main()
{
	int arr[10] = {0};
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(int [10])); //[]中的数字不能去掉
	//printf("%d\n", sizeof(int [])); 错误写法

	return 0;
}

~ 按位取反

按位取反是对二进制进行取反。

#include<stdio.h>

int main()
{
	int a = 0;
	printf("%d\n", ~a);
	//0的补码是       0000 0000 0000 0000 0000 0000 0000 0000
	//对0的补码取反为  1111 1111 1111 1111 1111 1111 1111 1111
	//取反后的原码为   1000 0000 0000 0000 0000 0000 0000 0001
	//所以结果是-1
	return 0;
}

下面这段代码,问题分析都在注释中写出来了

#include<stdio.h>
int main()
{
	int a = 13;
	//方便起见,只写八位
	//13是         0000 1101
	//要得到       0001 1101  真值为29
	//按位或是有1则1
	//可以将13与   0001 0000按位或
	//0001 0000是0000 0001左移4位得到,也就是将1左移4位,将a按位或0001 0000即可
	a |= (1 << 4);
	printf("%d\n", a);

	//通过0001 1101  真值为29 
	//得到0000 1101  真值为13
	//按位与是全1才1
	//将0001 1101 按位与 1110 1111,即对0001 0000按位取反,也就是将1左移4位,取反。按位与。
	a &= (~(1 << 4)); //不知道优先级的话可以都带上括号
	printf("%d\n", a);

	return 0;
}

感兴趣可以琢磨琢磨下面的代码

#include<stdio.h>

int main()
{
	int a = 0;
	//第一种写法
	//while (scanf("%d", &a) == 1)
	//{
	//	printf("%d\n", a);
	//}

	//第二种写法
	//while (scanf("%d", &a) != EOF)
	//{
	//	printf("%d\n", a);
	//}

	//第三种写法
	while (~scanf("%d", &a))
	{
		printf("%d\n", a);
	}
	return 0;
}

++ 和 - -

++- - 分别都有前置和后置两种,前置为先运算后使用,后置为先使用后运算

关系操作符

> >= < <= != ==
注意:===的区别

逻辑操作符

&& 逻辑与(并且)
|| 逻辑或(或者)

条件操作符

语句1 ? 语句2 : 语句3
类似于
if (语句1)
	语句2;
else 语句3;

C语言中唯一的三目操作符

逗号表达式

语句1,语句2,语句3,语句n
从左向右计算,整个表达式的结果是最后一个表达式的值

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

1.下标引用操作符 []        
操作数:数组名 + 索引值
2.函数调用操作符 ()  
第一个操作数是函数名,剩余操作数是传递给函数的参数。
最少有一个操作数
3.访问结构成员 .  结构体.成员名
            -> 结构体指针->成员名
#include <stdio.h>
struct Stu
{
	char name[10];
	int age;
	char sex[5];
	double score;
};
void set_age1(struct Stu stu)
{
	stu.age = 18;
};
void set_age2(struct Stu* pStu)
{
	pStu->age = 18;//结构成员访问
}
int main()
{
	struct Stu stu;
	struct Stu* pStu = &stu;//结构成员访问
	stu.age = 20;//结构成员访问
	set_age1(stu);
	pStu->age = 20;//结构成员访问
	set_age2(pStu);
	return 0;
}
文章来源:https://blog.csdn.net/m0_74012934/article/details/135674933
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。