Detalles del operador (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:
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;
}
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.
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;
}
Los resultados de ejecución se muestran en la figura a continuación , que son consistentes con los resultados del análisis.
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:
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:
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:
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.