Explicação detalhada dos operadores (muito detalhada)

Acesso subscrito [], chamada de função ()

[] operador de referência de subscrito

Operandos: um nome de array + um valor de índice

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

operador de chamada de função

Aceita um ou mais operandos: o primeiro operando é o nome da função e os operandos restantes são os parâmetros passados ​​para a função

#include <stdio.h>
void test1()
{
    
    
printf("hehe\n");
}
void test2(const char *str)
{
    
    
printf("%s\n", str);
}
int main()
{
    
    
test1(); //这⾥的()就是作为函数调⽤操作符。
test2("hello bit.");//这⾥的()就是函数调⽤操作符。
return 0;
}

Nota: O operando mínimo de uma função é apenas um, ou seja, apenas um nome de função. Nenhum parâmetro (void) é passado.
Aqui, gostaria de mencionar que sizeof não é uma função, mas sim um operador.

#include<stdio.h>
int main()
{
    
    
int a=10;
int n=sizeof(a)int n=sizeof a其实都一样
printf("%d\n",n);
return 0;
}

Podemos ver que a diferença entre int n=sizeof(a) e int n=sizeof a é um (), e a função requer (), então sizeof não é uma função, mas um operador

Propriedades do operador: precedência, associatividade

Os operadores na linguagem C têm dois atributos importantes, prioridade e associatividade. Esses dois atributos determinam a ordem de cálculo da avaliação da expressão (pode ser aproximado como uma operação matemática, mas ainda existem algumas diferenças)

prioridade

Se uma expressão contém vários operadores durante a operação, qual operador deve ser executado primeiro?
Para resolver este problema, a prioridade de cada operador é especificada

 3 + 4 * 5;

No exemplo acima, a expressão 3 + 4 * 5 contém o operador de adição ( + ) e o operador de multiplicação ( * ). Como a multiplicação tem prioridade mais alta que a adição, 4 * 5 será calculado primeiro, em vez de 3 + 4 primeiro. (Estas são na verdade as regras de operação matemática)

Combinação

Quando as prioridades de dois operadores são iguais, ou seja, quando os operadores são iguais, não podemos julgar qual cálculo iniciar com base na prioridade, então neste caso a associatividade precisa ser usada, mas a associatividade depende da situação. , alguns combinarão à esquerda (calculado da esquerda para a direita), alguns combinarão à direita (calculado da direita para a esquerda), mas a maioria deles será calculada da esquerda para a direita.

5 * 6 / 2;

No exemplo acima, * e / têm a mesma precedência. Ambos são operadores associativos à esquerda, portanto são executados da esquerda para a direita. 5 * 6 é calculado primeiro e depois 6/2. Existem muitas ordens de prioridade de operadores. A seguir está a ordem de prioridade de alguns operadores (organizados de alta para baixa prioridade). É recomendável que você apenas se lembre das prioridades desses operadores. • Parênteses ( () ) • Operação de incremento
automático
operador ( ++ ), operador de decremento ( – )
• Operadores unários ( + e - )
• Multiplicação ( * ), divisão ( / )
• Adição ( + ), subtração ( - )
• Operadores relacionais ( < , > etc.)
• Operador de atribuição (=)

Como os parênteses têm a precedência mais alta, você pode usá-los para alterar a precedência de outros operadores.
insira a descrição da imagem aqui
Link de referência de precedência do operador

avaliação de expressão

promoção inteira

As operações aritméticas inteiras na linguagem C são sempre executadas com pelo menos a precisão do tipo inteiro padrão ( ou seja, quando o tipo de dados armazenado é menor que os 32 bits armazenados no inteiro, o tipo de dados menor que 32 bits é promovido como inteiro) .
para obter essa precisão, os caracteres e os operandos curtos nas expressões são convertidos em números inteiros comuns antes de serem usados. Essa conversão é chamada de promoção de número inteiro.

A importância da promoção inteira

A operação inteira da expressão deve ser realizada no dispositivo de computação correspondente da CPU . O comprimento de bytes do operando da unidade aritmética inteira (ALU) na CPU é geralmente o comprimento de bytes de int e também é o comprimento de o registro de uso geral da CPU .
Portanto, mesmo que a adição de dois tipos de caracteres seja realizada pela CPU, ela deve primeiro ser convertida para o comprimento padrão do operando inteiro na CPU . ( De qualquer forma, eles são o comprimento padrão dos operandos inteiros a serem convertidos, de modo que o comprimento de bytes aumentado pode ser usado para tornar a precisão mais precisa. )
É difícil para uma CPU de uso geral implementar diretamente a adição direta operação de dois bytes de 8 bits (embora a máquina possa ter essa instrução de adição de bytes na instrução
). Portanto, todos os valores inteiros na expressão cujo comprimento pode ser menor que o comprimento de int devem ser convertidos em int ou unsigned int antes de serem enviados à CPU para realizar operações.

//实例1
char a,b,c;
char a=5;
//00000000 00000000 00000000 00000101
//00000101(截断后存储到a中)
char b=127;
//00000000 00000000 00000000 01111111
01111111(截断后存储到b中)
char a = b + c;
//00000000 00000000 00000000 00000101  a
//00000000 00000000 00000000 01111111  b
//00000000 00000000 00000000 10000100
//10000100(截断后存储到c中)
printf(“%d”,c)
//这里还是要整型提升
//11111111 11111111 11111111 10000100 补码
//10000000 00000000 00000000 01111011 反码
//10000000 00000000 00000000 01111010 原码
//%d是按照10进制的形式打印有符合的整数
/*可能会有人对这有疑惑11111111 11111111 11111111 10000100 补码
为什么左边全是1,其实是因为在整形提升时最高位补符号位*/
b和c的值被提升为普通整型,然后再执⾏加法运算。
加法运算完成之后,结果将被截断,然后再存储于a中

Como melhorar no geral

  1. A promoção de inteiro assinado é promovida de acordo com o bit de sinal do tipo de dados da variável.
  2. Promoção de número inteiro não assinado, bits altos preenchidos com 0
//负数的整形提升
char c1 = -1;
变量c1的⼆进制位(补码)中只有8个⽐特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111

//正数的整形提升
char c2 = 1;
变量c2的⼆进制位(补码)中只有8个⽐特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//⽆符号整形提升,⾼位补0

Conversão aritmética

Se os operandos de um operador forem de tipos diferentes, a operação não poderá prosseguir a menos que um dos operandos seja convertido para o tipo do outro operando . A seguinte hierarquia é chamada de transformações aritméticas ordinárias

1.long double
2.double
3.float
4.unsigned long int
5.long int
6.unsigned int
7.int
//如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏
运算。
//比如int和double,因为int排在double后面,所以要将int转换为double类型再执行运算

Análise de expressão de problema

As expressões a seguir entram em conflito com métodos de cálculo matemático, portanto preste atenção especial a elas.

Expressão 1

//表达式的求值部分由操作符的优先级决定。
//表达式1
a*b + c*d + e*f

Muitas pessoas calcularão a b, c d, e f ao mesmo tempo porque a prioridade de é maior que +,
mas a prioridade não determina que o terceiro * será executado antes do primeiro +, porque só pode ser determinado para ser adjacente a ele. operadores aritméticos
, então a ordem computacional da expressão pode ser:

1:a*b
2:c*d
3:a*b + c*d
4:e*f
5:a*b + c*d + e*f

Mas também é possível

a*b
c*d
e*f
a*b + c*d
a*b + c*d + e*f

Expressão 2

//表达式2
c + --c;

Assim como acima, a prioridade do operador só pode determinar se a operação de decremento – precede a operação de +, mas não temos como saber se o operando esquerdo do operador + é obtido antes ou depois do operando direito, portanto, os resultados são imprevisíveis e ambíguos
. Por exemplo:

intc=1;
c+--c

Se o primeiro c for 1, então c+ --c=1+0=1,
e se o primeiro c for atribuído depois de –c, então c+ --c=0+0=0,

então não escreva o código como isso, senão vai acabar, não consigo nem entender como surgiu o resultado.

Expressão 3

//表达式3
int main()
{
    
    
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}

Resultados do teste de expressão 3 em diferentes compiladores: resultados do programa de expressão ilegal
insira a descrição da imagem aqui

Expressão 4

#include <sdtio.h>
int fun()
{
    
    
static int count = 1;
return ++count;
}
int main()
{
    
    
int answer;
answer = fun() - fun() * fun();
printf( "%d\n", answer);
return 0;
}

No código acima resposta = fun() - fun() * fun(); só podemos saber através da prioridade do operador: a
multiplicação é calculada primeiro, depois a subtração, mas a ordem de chamada das funções não pode ser determinada pela prioridade da operadora. Claro

Expressão 5

//表达式5
#include <stdio.h>
int main()
{
    
    
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}

Quando o primeiro + neste código é executado, é incerto se o terceiro + + será executado, porque a prioridade e a associatividade do operador não podem determinar se o primeiro + e o terceiro + + serão executados. A sequência de configuração ++

Resumir

Mesmo com a prioridade e associatividade dos operadores, a expressão que escrevemos pode ainda não ser capaz de determinar o caminho de cálculo único através dos atributos do operador. Então esta expressão é potencialmente arriscada. É recomendado não escrever expressões sofisticadas. estilo, caso contrário você ficará confuso

Acho que você gosta

Origin blog.csdn.net/2301_79178723/article/details/132363185
Recomendado
Clasificación