[Fundamentos del lenguaje C 8 - explicación detallada de los operadores (1)]


prefacio

Los principales contenidos de los operadores incluyen: la introducción de varios operadores y la evaluación de expresiones.


1. Clasificación de los operadores

  • operadores aritméticos
  • operador de turno
  • operador bit a bit
  • operador de asignación
  • operador unario
  • operador relacional
  • operador lógico
  • operador condicional
  • expresión de coma
  • Referencias a subíndices, llamadas a funciones y miembros de estructura

2. Operadores aritméticos

 +  -  *  /  %  (加法 减法 乘法 取余 取模)
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;
}

El resultado de la ejecución se muestra en la figura a continuación:
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
a través del ejemplo, se puede encontrar que si el tipo de variable se usa incorrectamente, el resultado también es incorrecto

  • Además del operador %, varios otros operadores pueden operar con números enteros y de coma flotante.
  • Para el operador /, la división de enteros se realiza si ambos operandos son enteros. Y siempre que haya números de punto flotante, se realiza la división de punto flotante.
  • Ambos operandos del operador % deben ser números enteros. Devuelve el resto después de la división.

3. Operador de turno

Los operandos del operador de desplazamiento solo pueden ser números enteros

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

3.1 Operador de desplazamiento a la izquierda

Reglas de cambio: descartar a la izquierda, agregar 0 a la derecha

  • El entero es de tipo int, ocupa 4 bytes y tiene una representación de 32 bits. El bit más alto representa el signo, 0 es positivo y 1 es negativo
  • Los números enteros se almacenan en la memoria en complemento a dos, y el código original, el código inverso y el código complementario de números positivos son los mismos.
  • El flujo de operaciones del operador en enteros:
  • (1) Primero convierta el código original del número entero al código inverso
  • (2) El código inverso + 1 se convierte en código complementario
  • (3) Finalmente, operar en el complemento del entero
  • (4) Una vez completada la operación, convierta el código de complemento -1 después de la operación en el código de complemento
  • (5) Convierta el código inverso en el código original final
  • La función printf imprime el código original del entero

3.1.1 Ejemplo 1 - Desplazar un número positivo a la izquierda 1 bit

El código es el siguiente (ejemplo):

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

inserte la descripción de la imagen aquí

El resultado de la operación se muestra en la siguiente figura, que es consistente con el resultado del análisis. El efecto de desplazar 1 bit a la izquierda es equivalente a multiplicar por 2. En 51 microcomputadoras de un solo chip y STM32, el registro de operación se usará a menudo.
inserte la descripción de la imagen aquí

3.1.2 Ejemplo 2 - Desplazar un número negativo a la izquierda en 1 bit

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

inserte la descripción de la imagen aquí

Los resultados de ejecución se muestran en la figura a continuación , que son consistentes con los resultados del análisis.
inserte la descripción de la imagen aquí

3.2 Operador de turno a la derecha

Hay dos tipos de operaciones de regla de desplazamiento a la derecha:

  • Desplazamiento lógico: pad con 0 a la izquierda, descartar a la derecha

  • Desplazamiento aritmético: el lado izquierdo se rellena con el bit de signo del valor original y el lado derecho se descarta

3.2.1 Ejemplo 1 - Desplazar un número positivo a la derecha en 1

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

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

El proceso de desplazamiento a la derecha se analiza a continuación: el código original, el código inverso y el código complementario de números positivos son los mismos

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

El resultado se muestra a continuación:
inserte la descripción de la imagen aquí

3.2.2 Ejemplo 2 - Desplazar un número negativo a la derecha en 1

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

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

El siguiente análisis del proceso de desplazamiento a la derecha:

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

El resultado se muestra a continuación:
inserte la descripción de la imagen aquí

3.3 Descripción del operador de turno

Precauciones:

  • El operador de cambio a la derecha usa un cambio lógico o un cambio aritmético, según el compilador de la computadora. El mío es un cambio aritmético, por lo que el ejemplo se analiza mediante un cambio aritmético, y el proceso de análisis de cambio lógico es el mismo.
  • Para los operadores de desplazamiento, no desplace los bits negativos, esto no está definido por el estándar, por ejemplo:
int num = 10;
num>>-1;//10右移-1位,这是错误的表达

4. Operadores bit a bit

Los operadores de bits son:

& //按位与     相同为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

Los resultados de salida se muestran en la siguiente figura, que es consistente con el análisis:
inserte la descripción de la imagen aquí

4.1 Ejercicio 1

No se puede crear una variable temporal (la tercera variable) para intercambiar dos números

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 Ejercicio 2

Encuentre el número de 1 en el binario de un número entero almacenado en la memoria

//举例: 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;
}

Resumir

Este artículo introduce, introduce y analiza el proceso de implementación específico del operador. Es suficiente entender el principio aquí. La operación específica se entrega a la computadora para su ejecución. No es necesario dibujar y analizar cada uno de ellos por sí mismo. Error, se recomienda dividir el binario de 32 bits en grupos de 4 bytes y 8 bits, que son más atractivos. Esto a menudo se divide de esta manera cuando la MCU STM32 opera en registros, lo cual es claro de un vistazo.

Continúe aprendiendo sobre los operadores en el próximo artículo.

Supongo que te gusta

Origin blog.csdn.net/taibudong1991/article/details/123855462
Recomendado
Clasificación