从0开始学c语言-07-认识一下操作符、原码和反码和补码

发布于:2023-01-04 ⋅ 阅读:(853) ⋅ 点赞:(0)

本人0基础开始学编程,我能学会的,你也一定可以,学会多少写多少。

下载安装请从官网入手,社区版本即可,这里主要使用的软件是VS2019,图标如下。

上一篇

从0开始学c语言-06-选择语句、循环语句、函数、数组_阿秋的阿秋不是阿秋的博客-CSDN博客

总结篇

从0开始学c语言-总结01-c语言的粗略认识和快捷键_阿秋的阿秋不是阿秋的博客-CSDN博客

我一向不喜欢把一个东西复杂化,咱们就直接进入实战环节。

操作符在我看来就是表示操作的符号。

目录

1.算数操作符 

取余的有趣之处

这里我总结一下结论:

2.移位操作符

左移啥样子。

左移原则:左边不要,右边补0

右移啦

1.逻辑移位:左边补0、右边丢弃

2. 算术移位:左边用原该值的符号位填充,右边丢弃 

特别注意

补充:原码、反码、补码

正数

负数

图中有两个需要解释的

总结:

3.位操作符                                  

4.赋值操作符

“=”

复合赋值符

5.单目操作符

! 逻辑反操作

 - 负值 + 正值

 &取地址

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

 sizeof 操作数的类型长度(以字节为单位)

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

 过程是这样的

 前置、后置的--、++

( 类型)  强制类型转换

我们有两种转换的书写方式,如图。

6.关系操作符

7.逻辑操作符

区别

8.条件操作符(三母操作符)

9.逗号表达式

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


1.算数操作符 

说到算数操作,很容易能想到加减乘除吧?

那么在c语言里还有个东西叫取模也就是取余数的意思。

具体来体现一下的话,就像这样子

               

 %就是取余数的意思,看g=b%a=9%6,也就是9除6之后的余数为3~ 

取余的有趣之处

直接放代码,好好观察这几个变量的区别!!!

建议在纸上写好结果再继续阅读!

int main()
{
	int a = 9 / 2;
	float b = 9 / 2;
	float c = 9.0 / 2;
	int d = 9.0 / 2;
	float e = 9 / 2.0;
	float f = 9 % 2;

	printf("%d\n", a);
	printf("%f\n", b);  //和类型没关系,因为后面就是进行的整数除法,这样只是输出结果变为了小数,并没有得到4.5
	printf("%f\n", c);  //给等号后面改成小数模式就可以得到4.5了
	printf("%d\n", d);  //可以看到整型就算改成小数模式也没办法得到4.5,%f输出会显示错误呢
	printf("%f\n", e);  //后面只要有一个小数就可以得到4.5了呢,不论是谁
	printf("%f\n", f);  //介绍一下,%是取模(也就是取余的意思)

	return 0;
}

         

 还需要注意%的这一点,要是整数呢!

这里我总结一下结论:

1.能否得到小数点后的结果取决于两个因素,一个是变量的类型,另一个是等于号后面的操作数。

2.对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除

        若变量类型是int,那么等号后面怎么改也只会截取整数部分进行运算并输出整数。

        若变量为float或者double类型,输出结果取决于等号后面的数据类型。例如图中的b与c、e。

3.除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数

4.% 操作符的两个操作数必须为整数。返回的是整除之后的余数。

2.移位操作符

移位操作符主要有<<、>>,需要明确的是我们这里所指的移动是移动二进制位!!!

int main()
{  
	int a = 2;       
//我们写一下2的二进制位,int整型单位是4字节,也就是32bit,那么它的二进制应该这样表示00000000000000000000000000000010
	int b = a << 1;  
//注意左移操作符移动的是二进制位,也就是把a的二进制表示向左移动一位,右边再补一位,依旧是32bit,那么移动完之后就是00000000000000000000000000000100,也就是4
	printf("%d\n", b);  //输出结果
	
//同样道理,我们试试右移操作符
	int c = 2;
	int d = c >> 1;    //我们试着手动右移一下的结果是00000000000000000000000000000001
	printf("%d\n", d);

    int e = -1;
	int f = e >> 1;
	printf("%d\n", e); //这里会涉及到原码、补码、反码之类的
	return 0;
}

 代码中的解释不够详尽,这里我配上图来说明。

左移啥样子。

首先创建一个数据类型为int 的变量a等于2,它的单位大小是4字节,也就是32bit,而一个bit位盛放一个二进制数,也就是说用二进制来表示变量a的话,应该有32位二进制数字,并且它的十进制结果为2。

(不清楚进制转换的看这个文章从0开始学c语言-05-转义字符、进制转换、ASCII码表、注释_阿秋的阿秋不是阿秋的博客-CSDN博客不清楚单位大小为什么是4字节的看这个文章

从0开始学c语言-02-关于数据类型_阿秋的阿秋不是阿秋的博客-CSDN博客)   

这就是变量a的二进制表示结果,且它的十进制结果是2。

    int a = 2;       
	int b = a << 1;  
	printf("%d\n", b);  

 也就是说a左移后的结果b会是4。

左移原则:左边不要,右边补0

右移啦

右移分为两种:

1.逻辑移位:左边补0、右边丢弃

因为变量c与a的二进制表示结果一样,这里不再放图展示c的表达结果。

    int c = 2;
	int d = c >> 1;   
	printf("%d\n", d);

 算算c右移出来的结果d是?

2. 算术移位:左边用原该值的符号位填充,右边丢弃 

计算机系统中的右移以算术移位为主。

    int e = -1;
	int f = e >> 1;
	printf("%d\n", e); 

 这就是右移后的结果。

特别注意

对于移位运算符,不要移动负数位,这个是标准未定义的。

例如:  

int aqiu = 10;  

num>>-1;  //这是不可以的哦!

现在展示一下代码输出结果

 我知道你看到这里可能会问,补码是什么?

别着急我们接下来简单讲一下,具体一些的我会出专门章节补充。

补充:原码、反码、补码

以上面的代码例子为例,

正数

a、c均为正数2,他们的原码、反码、补码都一样,左移、右移后仍未正数,所以在输出的时候并没有进行负数那样的思考进行转码输出。而e、f在右移后均为负数,所以在输出的时候进行了转码。

负数

具体来说他们的作用是这样。

原码:进行结果输出

反码:中间的过渡码

补码:内存中储存的是补码

图中有两个需要解释的

1.按位取反、符号位不变

按位取反意思就是说0变成1 ,1变成0 ,符号位也就是第一位不变,0表示正数,1表示负数。

2.反码加一变补码

怎么加一呢?就是最后一位加1就可以了!

现在你返回去看上面输出的例子,是不是会更加理解你在干些什么?

总结:

1.正数的原码、反码、补码都一样

2.输出原码,储存补码

3.左移、右移所移动的是补码

3.位操作符                                  

&:按位与(有0为0)

| :按位或(有1为1)

^:按位异或(相同为0,不同为1)

注意:

1.他们的操作数必须是整数

2.和移位运算符一样,位操作符也是对补码进行操作。

int main()
{
	int num1 = 1;
	int num2 = 2;
	int a, b, c;
	a = num1&num2;
	b = num1|num2;
	c = num1^num2;
	
	printf("%d\n", a);
	printf("%d\n", b);
	printf("%d\n", c);

	return 0;
}

 

 

  

现在进行结果验证,和我们上图所示二进制转化的结果一样。

4.赋值操作符

“=”

这是赋值操作符,并不是等于。c语言中的等于是"=="。

简单来说,我们常用的int a=3;这就是把3赋值给a了。

复合赋值符

 +=    -=   *=   /=   %=           

>>=   <<=   &=   |=   ^= 

int main()
{
	int a = 0;
	a = a + 3;
	a += 3;
    //同样意思
	a = a - 3;
	a -= 3;
	return 0;
}

其他书写方式也是一样的,大家自己试试。

5.单目操作符

! 逻辑反操作

int main()
{
	//规定0为假,非0为真
	//!逻辑取反就是真假互换,一般0会变为1
	
	int a = 0;
	printf("%d\n", !a);
	return 0;
}

对比一下两个结果,就知道什么意思了!

 - 负值 + 正值

 &取地址

 这里后续会在指针章节补充上。

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

先放个代码吧,如果你是初学者,这里可能看不懂。

 sizeof 操作数的类型长度(以字节为单位)

int main()
{
	int a = 1;
	printf("%d\n", sizeof(int)); //这是类型,不能省略括号,规定就这样
	printf("%d\n", sizeof(a));  //这是变量,且可以省略括号
	
    int sz[10] = { 2 };
	printf("%d\n", sizeof(sz));  //计算了整个数组,数组有10个元素,每个元素的类型都是整型,而整型的单位大小为4字节,所以总的有40字节
	
    printf("%d\n", sizeof(sz[1])); //计算了数组的第一个元素,这个元素的类型是整型
	
    int szgs = sizeof(sz) / sizeof(sz[1]);  //计算了数组元素个数
	printf("%d\n", szgs);
	return 0;
}

 强调一下:

1.siizeof是一个操作符,而不是函数(函数不能省略括号)
2.sizeof可以计算类型或者变量的大小
3.这里说下单目和双目操作符的区别,单目就是只能对一个操作数(变量或者常量)进行操作,比如+需要两个操作数才能进行相加,而++只能对一个操作数操作。

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

int main()
{
	int a = 0;
	printf("%d\n", ~a);
	
	//一个整数二进制的表示有三种,原码、反码、补码
	//我们需要知道的是整数在内存中存储的是补码,我们输出的是原码
	//~是在内存中进行的按位取反(是按二进制位取反),内存中取反后还是补码
	//在输出的时候需要输出原码
	//负数的计算是从原码到反码是符号位不变,其他全部取反
	//从反码到补码是反码加一
	//正数的原码、反码、补码都一样

	int b = -1;
	printf("%d\n", b);
	//我多虑了,-1本来存储的就是补码,然后直接输出的话就是原码,但是这玩意都表示的是-1,所以不用担心输出不了负数
	//这是我逻辑上的漏洞,需要实践才能相信自己
	return 0;
}

 过程是这样的

1.~是在内存中进行的按位取反(是按二进制位取反),内存中取反后还是补码

这是从第一行到第二行的~过程。

2.在输出的时候需要输出原码

第二行到第四行是在进行输出的转码。

输出结果如图。

 前置、后置的--、++

int main()
{
	int a = 2;
	int b = a++;  //后置++,先使用,后+
	printf("%d\n", a);
	printf("%d\n", b);
	int c = 3;
	int d = ++c;  //前置++,先+,后使用
	printf("%d\n", c);
	printf("%d\n", d);  //也就是说输出d时候,是先对c进行+,再进行了d的初始值赋值

	return 0;
}

 也就是说,无论是前置还是后置,对于它本身输出的结果都会是操作之后的结果

而对于运用它的变量,则会受到前置后置的影响。

( 类型)  强制类型转换

    int a = 3.23;
	printf("%d\n", a);

如果我们这样输出,那结果会是3,但会有警告如图。

我们有两种转换的书写方式,如图。

第一种,直接定义赋值的时候加上强制类型转换然后进行输出就不会有警告。

第二种,在输出的时候再进行强制类型转换。

6.关系操作符

>  大于

>=  大于等于

<  小于

<=  小于等于

!=       用于测试“不相等”

==      用于测试“相等”

注意: 在编程的过程中 == 和 = 所代表的意思不一样!!!

7.逻辑操作符

int main()
{
	int a = 1;
	int b = 0;
	int c = a || b;  //这是逻辑字符或,判断真与假,真输出1,假输出0,
	printf("%d\n", c);
	return 0;
}
int main()
{
	int a = 3;
	int b = 0;
	int c = a && b;  //这是逻辑字符与,判断真与假,真输出1,假输出0,
	printf("%d\n", c);
	return 0;
}

 

 

 在我的理解中,

&&就是一假则假,||就是一真则真。

(真就是非0,假就是0)

区别

这里需要和&按位与、|按位或来区分,这俩东西是对二进制的补码进行操作的。

而逻辑字符与&&、逻辑字符或||是对十进制进行操作。

8.条件操作符(三母操作符)

接下来这两段代码的意思是一样的,你看不懂的那个就是条件操作符。

exp1 ? exp2 : exp3   exp1是判断条件,为真执行exp2,为假执行exp3

exp就是表达式的意思。

int main()
{
	int a = 3;
	int b = 0;
	int c = 0; 

	if (a > b)
	{
    	c = a;
	}

	else
	{
		c = b;

	}
	printf("%d\n", c);
	return 0;
}
int main()
{
	int a = 3;
	int b = 0;
	int c = 5; 

	c = a < b ? a : b;  //这就是条件操作符,也叫三目操作符,和上面表达的意思一样
	printf("%d\n", c);
	return 0;
}

9.逗号表达式

exp1, exp2, exp3, …expN   用逗号隔开的多个表达式。

int main()
{
	int a = 3;
	int b = 0;
	int c = 6; 
	int d = (a = 9 + c, b = a, c = a + b+ c);
	//逗号表达式从左向右计算,计算结果是最后一个表达式的结果
	printf("%d\n", d);
	return 0;
}

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

[ ]  下表引用操作符

()函数后面的这个括号就是函数调用操作符

· 和->涉及到结构体,这里先不讲。

重点是认识,应用的时候就会更加理解。

下一篇

从0开始学c语言-08-认识一下关键字、#define定义常量和宏_阿秋的阿秋不是阿秋的博客-CSDN博客

总结篇

从0开始学c语言-总结01-c语言的粗略认识和快捷键_阿秋的阿秋不是阿秋的博客-CSDN博客


网站公告

今日签到

点亮在社区的每一天
去签到