详解c语言操作符(下篇)

2023-12-22 12:00:18


前言

又来到了崭新的一天,欢迎各位读者来到我的课堂详解c语言操作符,书接上回,我们学习了c语言操作符的算数操作符和移位操作符今天小编就把剩下的操作符讲解给大家。

操作符Value
算数操作符+, -, * , / ,%
移位操作符左移操作符(<<)右移操作符 (>>)
位操作符按位与(&)按位或(
赋值操作符= += -=
单目操作符
关系操作符
逻辑操作符&&
条件操作符表达式1 ? 表达式2:表达式3
逗号表达式
下标引用,函数调用和结构成员

提示:以下是本篇文章正文内容,下面案例可供参考

一、位操作符

位操作符操作数必须整数

1,& 按位与

1,这里位代表二进制位,在上篇内容讲解了有关于二进制的知识,在这里小编就不再重复了。
2,按位与的运算就是两个都为1则为1,否则为0。

int main()
{
	int a = 3;
	int b = -3;
	int c = a & b;
	printf("%d",c);
}

在这里插入图片描述
在这里插入图片描述

分析

在这里整数在内存中存储的是补码,正整数的原码,反码,补码都相同,所以3在内存中存储的是它的原码,负整数在内存中存储的也是补码,得到如上图中一样,3的补码和-3的补码按位与,两个数两个都为1则为1,否则则为0,%d意味着打印一个有符号的整数,所以最终结果等于1.

2,| 按位或

这里位代表二进制位,在上篇内容讲解了有关于二进制的知识,在这里小编就不再重复了。
按位或的运算就是只要两个之中有一个为1则为1,两个0才为0

int main()
{
	int a = 3;
	int b = -3;
	int c = a | b;
	printf("%d",c);
}

在这里插入图片描述

在这里插入图片描述

分析

在这里讲3与-3的补码写出来 按位或的运算就是只要两个之中有一个为1则为1,两个0才为0;所以求得反码的值,最高位为符号位,所以求到他的值为负数的反码,在这里%d来打印就得求得他的原码二进制,转换成十进制,所以最终得到值为-1。

3,^按位异或

这里位代表二进制位,在上篇内容讲解了有关于二进制的知识,在这里小编就不再重复了。
按位异或相同为0;不相同(相异)为1

//按位异或
int main()
{
	int a = 3;
	int b = -3;
	int c = a ^ b;
	printf("%d", c);
}

在这里插入图片描述
在这里插入图片描述

分析

在这里先求出3和-3的补码,然后按位异或的运算就是相同为0,相异为1,所以求得3和-3的按位异或的值,但是他的最高位为1,是负数,要用%d打印出来所以我们得求出他的原码所以得到最终的值为-2.

在这里给大家讲解一个关于按位异或的小知识看到如下图:按位异或满足交换律

在这里插入图片描述

来做个习题:让13的第五位变成1,在让13的第五位变回来

int main()
{
	int a = 13;
	a |= (1 << 4);  //1向右移动四位在和a或上得到13的二进制位第五位变成1
	printf("%d \n", a);
	a ^= (1 << 4);  //异或得到原来的值 a &= (~(1<<4));
	printf("%d ",a);  
	return 0;
}

在这里插入图片描述


二、赋值操作符

1,赋值操作符可以重新赋值

一个等号叫赋值,两个等号叫相等,注意区分 !!!

int main()           
{
	int x = 0;  //这个叫初始化           
	x = 100;    //这个叫赋值           
}

2,赋值操作符可以连续使用

int main()   
{
	//int x = 0;  //这个叫初始化   
	//x = 100;    //这个叫赋值   
	int x = 10;   
	int a = 20;   
	int y = 0;   
	a = x = y + 1;//连续赋值  
	printf("%d %d %d",a,x,y);
}

在这里插入图片描述

分析

在这里y等于0;然后把y+1的值赋值给x,x=1,最后将x赋值给a,得到a等于1。也就是等于x=y+1;a=x;

三,单目操作符

0,什么叫单目操作符

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

例如:像a+b;+号两端有两个操作数a和b这个叫双目操作符
而!a,逻辑反操作符旁边就a一个操作数叫做单目操作符。

1,单目操作符介绍

单目操作符名称
逻辑反操作
-负值
+正值
&取地址
sizeof操作数的类型长度(以字节为单位)
~对一个数的二进制位进行按位取反
前置和后置–
++前置和后置++
*间接访问操作符(解引用操作符)
(类型)强制类型转换

2,逻辑反操作

在c语言中0表示假,非零表示真
逻辑反操作就是把假的变成真的,把真的变成假的。

int main()
{
	int flag = 3;
	if (flag)
		printf("hehe\n");
	return 0;
}

在这里插入图片描述

int main() 
{
	int flag = 3; 
	if (!flag) 
		printf("hehe\n"); 
	return 0; 
}

在这里插入图片描述

分析

在第一个代码中flag的值为3,3为非零代表真进入if里面判断,判断为真则执行if里面的语句printf (“hehe”);在第二个代码中,flag表示真,则!flag表示为假,if后面跟着判断,判断为假则不执行if语句中的内容,所以不打印hehe。

3,取地址操作符

作用:取出一个变量在内存中的地址

int main()
{
	int a = 10;
	printf("%p",&a);
	return 0;
}

在这里插入图片描述

分析

在这里对a进行取地址,取出a的地址我们用%p进行打印,%p是专门用来打印地址的。当然我们把程序关掉重新运行,我们发现这时地址是变化的,这时正常现象,程序重新运行,原先的存放的a就消除了,所以每次运行a都会重新开辟一个空间再去存放a,所以地址不一样。在这里注意,a在内存中占四个字节,每个字节都有地址,&a取的是a的第一个字节的地址也就是起始地址。

3,sizeof操作符

sizeof的操作数就是sizeof后面括号的内容,计算的是类型所创建的变量或者变量所占内存空间的大小

如要详细深刻理解请看小编写的: 详解sizeof和strlen

int main()
{
	int a = 10;
	int n = sizeof(a); //计算的是a所占内存的大小,单位是字节
	printf("n=%d\n",n);
	return 0;
}

在这里插入图片描述

验证sizeof不是函数的原因
在这里插入图片描述

如果sizeof是函数那么后面的括号不能省略,因为函数在调用的时候,后面的括号是不能省略的,所以sizeof是操作符,

4,~操作符

作用:对一个数的二进制位进行按位取反

int main()
{
	int x = 0;
	printf("%d",~x);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

分析

在这里0在内存中存储的是0的补码,然后~0表示所有的二进制位按位取反得到反码,因为最高位为1,所以它是负数,负数要以%d的形式打印需求出它的原码所以得到-1。

5,++操作符

++操作符分为两种,前置++和后置++
接下来代码演示

1,前置++

1,前置++作用:先加1后赋值

//前置++
int main()
{
	int a = 10;
	int b = ++a;
	printf("%d\n",a);
	printf("%d\n",b);
}

在这里插入图片描述

分析
在这里前置++,先将a的值加上1,然后在赋值给b,等同于a=a+1;b=a;最终得到两个值都是11.

2,后置++

2,后置++作用:先赋值后加1

//后置++
int main()
{
	int a = 10;
	int b = a++;
	printf("%d\n", a);
	printf("%d\n", b);
}

在这里插入图片描述

分析

而后置++,则是先将a的值赋值给b,然后再a+1,等同于b=a;a=a+1;最终得到a的值为11,b的值为10.

思考一下:a=10;printf(“%d\n”,a++);这个运算表达式结果是什么?
回答:先使用后++,先打印a的值,a再去加1

在这里插入图片描述

6,- - 操作符

–操作符等同于++操作符一样的作用,在这里不再演示
1,前置- -:先减一,后赋值。
2,后置- -:先赋值,后减一。

7, *间接访问操作符(解引用操作符)

这个操作符搭配地址使用

//*解引用操作符
int main()
{
	int a = 10;
	int* p = &a;  //取出a的地址,放在p中,于是p就成了指针变量,而不是整型变量,指针变量类型就是 int *
	printf("%p\n",p);   //打印地址用%p
	*p = 20;
	printf("%d\n",a);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

分析

第一个*代表的是int 这个是指针变量的类型不是操作符;而p的意思是对p解引用,通过p里面存的地址找到它所指向的对象,也就是a,也就是说解引用p等价于a。我这里后面赋值20,也就是把20给到了a。

8,强制类型转换

类型不同强制转换成需要的类型

在这里插入图片描述
在这里3.14是double类型转换成int类型下面就会报警告,可能会丢失数据。而我们需要一个整形的变量我么只需要强制类型转换成int类型的。

在这里插入图片描述


三,关系操作符

在这里小编主要讲一下等于操作符(==),注意的是并不是所有的对象都可以用等于号来比较的
例如:字符串的比较

在这里插入图片描述

在这里插入图片描述


四,逻辑操作符

1,逻辑与&&

区分逻辑与和按位与
逻辑与不关注二进制位,它只关注真假,两个真才为真,只要一个为假整体结果就是假,按位与是二进制位进行与

int main()
{
	int x = 1 & 2;
	int y = 1 && 2; 
	printf("%d\n", x); 
	printf("%d\n", y); 
	return 0; 
}

在这里插入图片描述

分析

在这里按位与就不跟各位读者详细说了前面已经讲述,我们这里讲解一下逻辑与。在这里y=1&&2为啥等于1呢,这是因为逻辑与只关注真假,在计算机中0代表假,非零表示真,在这里1是真,2也是真,真逻辑与真,整体就是真所以y就是1.

在这里拓展一下,&&只要左边为假,右边就不在计算了,也就是短路现象。

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\ni=%d\n", a, b, c, d, i);
	return 0;
}

在这里插入图片描述

分析
在这里,等于赋值号优先级是最低的,所以我们优先计算后面的逻辑操作,因为i是后置++,先使用后加 1,所以这里逻辑与操作之前就直接为0,因为0是假所以后面的表达式不在计算,所以可得上面的结果

2,逻辑或 ||

区分逻辑或和按位或.
逻辑与也是只关注二进制位,但是他是只要有一个为真,整体结果就为真。
按位或关注的是二进制位,它是只要两个中有一个为1就为1 ,两个全部为0才为0.

int main()
{
	int x = 1 && 0;
	int z = 1 || 0;
	int y = 1 | 0;
	printf("%d\n", x);
	printf("%d\n", z);
	printf("%d\n", y);
	return 0;
}

在这里插入图片描述

分析

在这里逻辑x= 1&&0;因为1是真0是假,逻辑与运算只要一个为假整体就为假。而z=1| | 0;在这里1为真0为假,逻辑或运算只要一个为真整体就为真,所以z的结果为1。


五,条件操作符(三目操作符)

一般形式:表达式1?表达式2:表达式3;这个计算方法就是如果表达式1为真则表达式2计算,表达式3不计算,表达式2计算的结果就是整个表达式的结果;相反表达式1为假则表达式2不计算,表达式3计算,表达式3为整个表达式的结果。

int main()
{
	int x = 3;
	int y = x > 4 ? x + 1 : x - 1;
	printf("%d",y);
	return 0;
}

在这里插入图片描述

分析
在这里x的值是3,3小于4,表达式结果为假,则执行x-1,所以x等于2,x=2就是整个表达式的结果赋值给y,所以得到y=2;

六,逗号表达式

逗号表达式就是用逗号隔开的多个表达式
语法形式为:表达式1,表达式2,表达式3,…表达式n
逗号表达式,从左向右依次进行。整个表达式的结果是最后一个表达式的结果

int main()
{
	int a = 1;
	int b = 2;
	int c = (a > b, a = b + 10, a, b = a + 1);
	printf("%d\n", a);
	printf("%d\n", b);
	printf("%d\n", c);
	return 0;
}

在这里插入图片描述

分析
在这里括号里就是逗号表达式,逗号表达式从左向右依次执行,整个表达式的结果为最后一个表达式的结果,首先a>b,这是假所以为0,然后a=b+10;因为b=2,所以a=12;第三个则是a的值;第四个也就是最后一个表达式,a此时等于12再去+1得到b的值为13,最后一个表达式结果为13赋值给c,所以c也是13.
int main()
{
	int a = 1;
	int b = 2;
	int c = (a > b, a + 10, a, b = a + 1);
	printf("%d\n", a);
	printf("%d\n", b);
	printf("%d\n", c);
	return 0;
}

在这里插入图片描述

分析

在这里讲述一下小编最开始学这个表达式容易搞混的东西,在这里可以清晰看到小编把第二个表达式改为a+10,而不是a=b+10;所以这里只是算出了a+10的结果但是并没有赋值给a,所以a的值还是1,最后算出的b也就是1+1得到2然后赋值给c。


七,下标引用操作符[ ]

在这里小编就不在多唠嗑下标引用操作符了,大家都在数组中学过了我就简单给各位读者概括一下

int main()   
{
	int arr[10]; //创建数组   
	arr[9] = 10; //使用下标引用操作符,令数组下标为9的数为10,在这里[]操作数为arr和9  
	return 0;   
}


八,函数调用操作符

//函数定义
int add(int x, int y)
{
	return x + y;
}
int  main()
{
	int a = 10;
	int b = 20;
	//函数调用
	int c = add(a, b);
	return 0;
}

分析

在这里函数调用那里add后面的圆括号就是函数调用操作符,函数调用不能省略括号,他是一个函数调用操作符,在这里之前也讲述了sizeof为什么不是函数的原因,如果sizeof是函数那么函数调用的时候那个括号不能省略, 在这里函数调用操作符的操作数是add,a,b


九,结构体操作符

在这里结构体操作符有两个
. 结构体.成员
->结构体指针->成员名

#include<string.h>
struct Stu
{
	char name[20];
	int age;
	double score;
};
void set_stu(struct Stu* ps)
{
	//strcpy((*ps).name, "zhangsan");
	//(*ps).age = 20;
	//(*ps).score = 100.0;
	strcpy(ps->name, "zhangsan"); //通过ps结构体指针找到他所指向的对象成员
	ps->age = 20;
	ps->score = 100.0;
}
void print_stu(struct Stu ss)
{
	printf("%s %d %lf",ss.name,ss.age,ss.score);
}
int main()
{
	struct Stu s = { 0 };
	set_stu(&s);
	print_stu(s);
    return 0;
}

在这里插入图片描述

完结撒花

一份耕耘一分收获,在此次学习中你已经学会了c语言操作符,如果大家还有什么不懂的可以在下方留言小编看到后会详细给大家解读一番,感谢观看!!完结撒花。

文章来源:https://blog.csdn.net/weixin_62168696/article/details/135078271
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。