[C language foundation 8 - detailed explanation of operators (1)]


foreword

The main contents of operators include: the introduction of various operators, and the evaluation of expressions.


1. Classification of operators

  • arithmetic operators
  • shift operator
  • bitwise operator
  • assignment operator
  • unary operator
  • relational operator
  • logical operator
  • Conditional operator
  • comma expression
  • Subscript references, function calls, and structure members

2. Arithmetic operators

 +  -  *  /  %  (加法 减法 乘法 取余 取模)
int main()
{
    
    
	int a = 9 / 2;//4
	float b = 9 / 2;
	int c = 9.0 / 2;
	float d = 9.0 / 2;//4.5
	float e = (float)9.0 / 2;

	printf("%d\n", a);
	printf("%f\n", b);
	printf("%d\n", c);
	printf("%f\n", d);
	printf("%f\n", e);
	return 0;
}

The running result is shown in the figure below:
insert image description here
insert image description here
insert image description here
through the example, it can be found that if the type of variable is used incorrectly, the result is also wrong

  • In addition to the % operator, several other operators can operate on integers and floating-point numbers
  • For the / operator, integer division is performed if both operands are integers. And as long as there are floating-point numbers, floating-point division is performed.
  • Both operands of the % operator must be integers. Returns the remainder after division

3. Shift operator

Shift operator operands can only be integers

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

3.1 Left shift operator

Shifting rules: discard on the left, add 0 on the right

  • Integer is of int type, occupies 4 bytes, and has 32-bit representation. The highest bit represents the sign, 0 is positive and 1 is negative
  • Integers are stored in memory in two's complement binary, and the original code, inverse code, and complement code of positive numbers are the same
  • The flow of operator operations on integers:
  • (1) First convert the original code of the integer to the inverse code
  • (2) Inverse code + 1 is converted into complement code
  • (3) Finally, operate on the complement of the integer
  • (4) After the operation is completed, convert the complement code -1 after the operation into the complement code
  • (5) Convert the inverse code into the final original code
  • The function printf prints the original code of the integer

3.1.1 Example 1 - Shift a positive number to the left by 1 bit

The code is as follows (example):

int main()
{
    
    
	int a = 5;
	int b = a << 1;//操作的补码二进制位,a本身结果不变
	printf("%d\n", a);//打印5
	printf("%d\n", b);// -10
	return 0;
}

insert image description here

The result operation is shown in the figure below, which is consistent with the analysis result. The effect of shifting left by 1 bit is equivalent to multiplying by 2. In 51 single-chip microcomputer and STM32, the operation register will be often used.
insert image description here

3.1.2 Example 2 - Shift a negative number to the left by 1 bit

int main()
{
    
    
	int a = -5;
	int b = a << 1;//<< >> 操作的二进制位
	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -10
	return 0;
}

insert image description here

The running results are shown in the figure below , which are consistent with the analysis results.
insert image description here

3.2 Right shift operator

There are two types of right shift rule operations:

  • Logical shift: pad with 0 on the left, discard on the right

  • Arithmetic shift: The left side is filled with the sign bit of the original value, and the right side is discarded

3.2.1 Example 1 - Shift a positive number to the right by 1

int main()
{
    
    
	int a = 5;
	int b = a >> 1;//右移不一定是除2

	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -3
	return 0;
}

The process of right shifting is analyzed below: the original code, inverse code, and complement code of positive numbers are the same

00000000 00000000 00000000 00000101 //5的二进制补码
//算术右移:左边用原该值的符号位1填充,右边丢弃1
00000000 00000000 00000000 00000010 //右移后的补码
//右移后的补码就是右移后的原码  2

The result is shown below:
insert image description here

3.2.2 Example 2 - Shift a negative number to the right by 1

int main()
{
    
    
	int a = -5;
	int b = a >> 1;//右移不一定是除2

	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -3
	return 0;
}

The following analysis of the process of right shift:

10000000 00000000 00000000 00000101 //-5的二进制原码
11111111 11111111 11111111 11111010 //反码
11111111 11111111 11111111 11111011 //补码:反码+1
//算术右移:左边用原该值的符号位1填充,右边丢弃1
11111111 11111111 11111111 11111101 //右移后的补码
11111111 11111111 11111111 11111100 //反码:补码-1
10000000 00000000 00000000 00000011 //原码  -3

The result is shown below:
insert image description here

3.3 Shift operator description

Precautions:

  • The right shift operator uses a logical shift or an arithmetic shift, depending on the computer compiler. Mine is an arithmetic shift, so the example is analyzed by an arithmetic shift, and the logical shift analysis process is the same.
  • For shift operators, do not shift negative bits, this is undefined by the standard, for example:
int num = 10;
num>>-1;//10右移-1位,这是错误的表达

4. Bitwise operators

Bit operators are:

& //按位与     相同为1, 相异为0
| //按位或     有1为1, 全0为0
^ //按位异或    相同为0, 相异为1
//注:他们的操作数必须是整数
int main()
{
    
    
	int a = 3;
	int b = -5;
	int c = a & b;
	int d = a | b;
	int e = a ^ b;//异或
	//对应的二进制位:相同位0,相异为1
	printf("%d\n", c);// 打印3
	printf("%d\n", d);// -5
	printfan("%d\n", e);// -8	
	return 0;
}
00000000 00000000 00000000 00000011   3的补码
11111111 11111111 11111111 11111011   -5的补码
//按位与:  相同为1, 相异为0
00000000 00000000 00000000 00000011    3的补码,原码表示3
//按位或:   有1为1, 全0为0
11111111 11111111 11111111 11111011   -5的补码,原码表示-5
//按位异或: 相同为0, 相异为1
11111111 11111111 11111111 11111000  补码
11111111 11111111 11111111 11110111  反码
10000000 00000000 00000000 00001000  原码 -8

The output results are shown in the following figure, which is consistent with the analysis:
insert image description here

4.1 Exercise 1

Cannot create a temporary variable (the third variable) to exchange two numbers

int main()
{
    
    
	int a = 3;
	int b = 5;

	printf("a=%d b=%d\n", a, b);
	//第一种,常用的方法,创建中间变量
	int tmp = a;
	a = b;
	b = tmp;	
	//第二种,不创建变量
	a = a + b;
	b = a - b;
	a = a - b;
	//第三种,不创建变量,很难想到
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

4.2 Exercise 2

Find the number of 1's in the binary of an integer stored in memory

//举例: 5   &1, 然后右移1位, 再&1
//00000000 00000000 00000000 00000101
//00000000 00000000 00000000 00000001
int main()
{
    
    
	int num = 0;
	scanf("%d", &num);
	int i = 0;
	int cnt = 0;
	//位操作
	for ( i = 0; i < 32; i++)
	{
    
    //每次右移一位就 &1
		if (1==((num>>i)&1))
		{
    
    
			cnt++;//所有位与1,相同为1,相异为0
		}
	}
	printf("%d", cnt);
	return 0;
}

Summarize

This article introduces, introduces, and analyzes the specific implementation process of the operator. It is enough to understand the principle here. The specific operation is handed over to the computer for execution. It is not necessary to draw and analyze each of them by themselves. Error, 32-bit binary is recommended to be divided into 4 bytes and 8-bit groups, which are better-looking. This is often divided in this way when STM32 MCU operates on registers, which is clear at a glance.

Continue to learn about operators in the next article.

Guess you like

Origin blog.csdn.net/taibudong1991/article/details/123855462