C语言操作符

本文详细介绍了C语言中的移位操作符、位操作符、逗号表达式、下标引用与函数调用,以及优先级、结合性和整型提升与算术转换的概念和用法实例,帮助读者深入理解这些关键概念。
摘要由CSDN通过智能技术生成

操作符学习

1.移位操作符

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

注意:他们的操作数必须是整数,并且不要移动负数位,e.g.10>>(-1)

左移操作符,左面抛弃,右面补0

右移操作符,逻辑右移或者算术右移,逻辑右移右面抛弃,左面补0;算术右移,右面抛弃,左面补符号位
左移一位相当于乘2,右移一位相当于除以2。
可以用右移来求平均值。
e.g.(left + right) >> 1

2.位操作符

按位与、按位或、按位异或、按位取反,操作数都必须为整数

e.g.1

不创建中间变量的情况下,实现两个数的交换

int main()
{
	int a = 10, b = 20;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a = %d b = %d\n", a, b);
	return 0;
}

按位异或的神奇之处

int main()
{
    int a = 10;
    int b = 20;
    int c = a ^ a;//c=0,因为相同取0,不同取1
    int d = c ^ b;//d=b
    int e = a ^ a ^ b;//e = b
    int f = a ^ b ^ a;//f = b,可以交换律
}

这个用法是按位异或比较巧妙的一个使用方法,值得大家学习一下。

e.g.2

一个数在计算机中的二进制存储形式里有多少个1

int main()
{
	int a = 0, i = 0;
	printf("请输入:>");
	scanf("%d", &a);
	while (a)
	{
		if (a % 2 == 1)
		{
			i++;
		}
		a = a / 2;
	}
	printf("%d\n", i);
	return 0;
}

int main()
{
	int a = 0, i = 0, count = 0;
	printf("请输入:>");
	scanf("%d", &a);
	for (i = 0; i < 32; i++)
	{
		if ((a & (1 << i)) != 0 )
		{
			count++;
		}
	}
	printf("%d\n", count);
	return 0;
}

int main()
{
	
	int a = 0, i = 0;
	printf("请输入:>");
	scanf("%d", &a);
	while (a)
	{
		i++;
		a = a & (a - 1);
	}
	printf("%d\n", i);
	return 0;
	
}

三种方法,都要掌握。

e.g.3

求两个数二进制中不同位的个数

int main()
{
    int a = 0, b = 0, i = 0;
    scanf("%d%d", &a, &b);
    int c = a ^ b;
    while(c)
    {
        i++;
        c = c & (c - 1);
    }
    printf("%d\n", i);
    return 0;
}

先试用按位异或的性质,相同为0,不同为1,接着在变成找一个数二进制位的1的个数。

3.逗号表达式

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

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

4.下标引用[]和函数调用()

int arr[10];//创建数组
arr[9] = 10;//实⽤下标引⽤操作符。
//[ ]的两个操作数是arr和9。

函数调用操作符:接受⼀个或者多个操作数:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数。

5.优先级和结合性

优先级

常用: 自加自减 > ! > 运算操作符 > 关系操作符(大于和小于高于!=和==)> && || > 赋值操作符

参考:

C 运算符优先级 - cppreference.com

6.整型提升和算术转换

1.整型提升

C语言的整型算术运算总是至少以缺省整型类型(计算机整型默认的类型-int)的精度来进行的,为了获得这个精度,表达式中的字符和短整形操作数**在使用前(参与算术运算之前)**都会被转换为默认的普通整型,这种转换称为整型提升。

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度⼀般就是int的字节长度,同时也是CPU的通⽤寄存器的长度。

有符号整数提升是按照变量的数据类型的符号位来提升的,负数补1,正数补0

无符号整数提升, 高位补0
在这里插入图片描述
因为-1整型提升后是在内存中的二进制存储形式是32个1,无符号数自然会很大。
在这里插入图片描述
至于++a和–a为什么还是1,因为a=a+1和a=a-1最后的本质还是求sizeof(a)

2.算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另⼀个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。

//long double
//double
//float
//unsigned long int
//long int
//unsigned int
//int

从下到上转换

e.g.

#include <stdio.h>
int i;
int main()
{
    i--;
    if (i > sizeof(i))
    {
        printf(">\n");
    }
    else
    {
        printf("<\n");
    }
    return 0; 
}

最后输出>

C语言中,0为假,非0即为真。

全局变量,没有给初始值时,编译其会默认将其初始化为0。

i的初始值为0,i–结果-1,i为整形,sizeof(i)求i类型大小是4,按照此分析来看,结果应该是<,但是sizeof的返回值类型实际为无符号整形,因此编译器会自动将左侧i自动转换为无符号整形的数据,-1对应的无符号整形是一个非常大的数字,超过4或者8,故实际应该是>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值