operador
operador aritmético
% Operador de módulo, os operandos esquerdo e direito devem ser inteiros
/sinais de divisão, etc., os operandos esquerdo e direito de + - * podem ser números de ponto flutuante ou inteiros
operador de turno
Operador de deslocamento à direita:
1. O deslocamento à direita aritmético
descarta à direita e complementa o bit de sinal original à esquerda
int main()//算术右移,右边丢弃,左边补原符号位
{
int a = -1;//负数按照补码的方式存储,正数存储的也是补码(正数的补码和原码相同)
//1000000000000001-原码
//1111111111111110-补码
//1111111111111111-补码
int b = a >> 1;//移位移的是内存中的二进制
printf("%d\n", b);
return 0;//结果为-1,证明负数右移之后还是负数
}
2. Desloque logicamente
para a direita e descarte à direita, adicione 0 à esquerda
Deslocar um bit para a direita tem o efeito de dividir por dois
int main()
{
int a = 16;
int b = a >> 1;
int c = a >> 2;
printf("%d %d\n", b,c);//结果分别为8 4
return 0;
}
Operador de deslocamento à esquerda:
o lado esquerdo é descartado e o lado direito é preenchido com 0,
que tem o efeito de multiplicar por dois
int main()
{
int a = 5;
int b = a << 1;
printf("%d\n", b);
return 0;//10
}
Deslocamento à esquerda negativo ou negativo
int main()
{
int a = -5;
int b = a << 1;
printf("%d\n", b);
return 0;//-10
}
Aviso ⚠
1. Não mova dígitos negativos, é um comportamento indefinido
int num = 10;
num >> -1;///错误
2. Só funciona com números inteiros
&、|、^
& bit a bit AND
int main()
{
//&按2进制位与
int a = 3;
int b = 5;
int c = a&b;
//011
//101
//001
printf("%d\n", c);
return 0;
}
| bit a bit ou
int main()
{
//|按2进制位或
int a = 3;
int b = 5;
int c = a | b;
//011
//101
//111
printf("%d\n", c);//7
return 0;
}
^ XOR bit a bit
int main()
{
//^按2进制位异或 相同为0,相异为1
int a = 3;
int b = 5;
int c = a^b;
//011
//101
//110
printf("%d\n", c);
return 0;
}
Exercício: Edite o código para encontrar o número de 1s no binário de um inteiro armazenado na memória
int main()
{
int num = 0;
int count = 0;
scanf("%d", &num);
//统计num的补码中有几个1
while (num)
{
if (num % 2 == 1)//判断末位是否为1
count++;
num = num / 2;//去掉判断过的末位
}
printf("%d\n", count);
return 0;//但负数会出现问题
}
Mas há um problema com números negativos
int main()
{
int num = 0;
int count = 0;
scanf("%d", &num);//当num&1,比如num=3即0011,num&1即为0011&0001,末位为1时&1必定为1,末位是0&1必定是0
int i = 0;
for (i = 0; i < 32; i++)
{
if (1 == ((num >> i) & 1))
count++;
}
printf("%d\n", count);
return 0;
}
operador lógico
&&Lógico e ||Lógico ou
Há uma diferença entre lógico e ou e bit a bit e ou,
bit a bit e ou: os bits binários correspondentes são ANDed
Lógico e ou: julgando se o próprio número é verdadeiro ou falso
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;//a=0&&后面都为假,不运行//用后自加一
printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d);
return 0;//1 2 3 4
}
&&
O lado esquerdo é falso && não conta
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;//a=0为假&&后面不计算,不运行//用后自加一
printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d);
return 0;//1 2 3 4
}
Calculado após && quando a esquerda é verdadeira
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d);
return 0;//2 3 3 5
}
||
left é verdadeiro quando || não é avaliado após
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ || ++b || d++;//a=1为真||后面的不计算,然后自加一
printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d);
return 0;//2 2 3 4
}
operador condicional
O formato é: expressão1? Expressão 2: expressão 3;
quando a expressão 1 é verdadeira, o resultado é a expressão 2, e quando a expressão é falsa, o resultado é a expressão 3
int main()
{
int a = 0;
int b = 0;
if (a > 5)
b = 3;
else
b = -3;
//用条件操作符来表示
b = (a > 5 ? 3 : -3);
return 0;
}
expressão de vírgula
Executado sequencialmente da esquerda para a direita, o resultado de toda a expressão é o resultado da última expressão
int a=1;
int b=2;
int c=(a>b,a=b+10,a,b=a+1);
o valor de c é 13
Você também pode simplificar a expressão
a = get_val();
count_val(a);
while (a > 0)
{ // processamento de negócios a = get_val(); count_val(a); } //---otimização de expressão de vírgula --- while (a = get_val (), count_val(a), a > 0) { //processamento de negócios }
Referências de subscrito, chamadas de função e membros de estrutura
[] operador de referência de subscrito
Operando: um nome de array + um valor de índice
int arr[10];//Cria um array arr[9] = 10;// Os dois operadores do
operador de referência de subscrito prático [] são arr e 9
operador de chamada de função
O () ao chamar uma função é o operador de chamada de função. O () que define a função não é
() operandos: nome da função, parâmetro
membro da estrutura
struct Stu
{
char name[20];//成员变量
int age;
char id[20];
};
int main()
{
int a = 10;
//使用struct Stu这个类型创建了一个学生对象s1,并初始化
struct Stu s1 = {"张三",20,"2019010305"};
printf("%d\n", s1.age); //结构体变量.成员名//.操作符可以访问成员
printf("%s\n", s1.id);
struct Stu* ps = &s1;
printf("%d\n", (*ps).age);
printf("%d\n", ps->age);//结构体指针->成员名
return 0;
}
struct Stu{} é equivalente ao desenho, e uma casa chamada s1 é construída de acordo com o desenho, então struct Stu s1 ocupa espaço de memória e pode armazenar vários parâmetros
avaliação de expressão
conversão implícita de tipo
As operações aritméticas inteiras de C são sempre executadas com pelo menos a precisão do tipo inteiro padrão.
Para obter essa precisão, caracteres e operandos inteiros curtos em expressões são convertidos em tipos inteiros normais antes do uso. Essa conversão é chamada de promoção inteiro
A promoção de inteiro é promovida de acordo com o bit de sinal do tipo de dado da variável (o bit alto complementa o bit de sinal)
int main()
{
char a = 3;
//00000000000000000000000000000011 正常一个整数所占32位
//00000011这就是char a //但char只能存放一个字节,要发生截断,取低位一个字节
char b = 127;
//00000000000000000000000001111111 同理
//01111111这就是char b
char c = a + b;//计算时进行整型提升
//00000000000000000000000000000011 //整型提升:高位补符号位
//00000000000000000000000001111111 //整型提升:高位补符号位
//00000000000000000000000010000010 a+b得到c,因为c是char类型要截断
//10000010就是char c
printf("%d\n", c);//要打印整型//整型提升:高位补符号位
//11111111111111111111111110000010 - 补码//因为是负数,所以要求原码
//11111111111111111111111110000001 - 反码
//10000000000000000000000001111110 - 原码//-126
return 0;
}
conversão aritmética
Execute operações em operandos de tipos diferentes, converta tipos de baixa precisão em tipos de alta precisão e execute operações no mesmo tipo
Auto-incremento e auto-decremento em detalhes
Resumo: Pré-aumento automático (++/--): altera as variáveis antes da operação
Pós-aumento automático (++/--) : altera as variáveis após a operação
1.
int main()
{
int i = 0;
int j = i++ + ++i;//++i优先级高于i++,所以相当于int j=++i + i++;
//此时i=0,1(此时i=1)+1(此时i=2)=2
int k = --i + i--;//此时i=2,(此时i=1)1+1(此时i=0)=2
printf("%d %d %d\n", i, j, k);
return 0;
}
Ao executar int j = i++ + ++i;
prioridade de análise: auto-incremento é maior que +, e dois níveis de auto-incremento são calculados da esquerda para a direita; onde ++i tem prioridade maior que i++, ou seja, torna-se int j= Antes da operação
++i + i++ : Por causa de ++i, a variável i é incrementada em um (0+1=1) antes da operação; neste momento, durante a operação i=1 : adicione i++, porque é post ++, portanto, neste momento, i ainda é 1, então 1+1=2 é atribuído a j após a operação : por causa de i++, a variável i é incrementada em um após a operação (1+1=2 ); neste momento, quando i=2, ao executar int k = - -i + i--; Antes da operação : por causa de --i, a variável i é subtraída por um (2-1=1) antes do operação; neste momento, durante a operação de i=1 : adicione i--, porque é pós-posição --, então i ainda é 1 neste momento, então 1+1=2 é atribuído a j após a operação : porque i--, após a operação, a variável i é reduzida em um (1-1=0); neste momento, i=0
2.
int main()
{
int i = 0;
int j = i + i++;//0+0(i=1)=0
printf("%d %d\n", i, j);
return 0;
}
Execute int j = i + i++;
antes da operação : nenhuma
operação : adicione i++, porque é post ++, então i ainda é 0 neste momento, então 0+0=0 é atribuído a j
após a operação : porque i++ , adicione um à variável i após a operação (0+1=1); neste momento i=1
3.
int main()
{
int i = 0;
int j = i + ++i;//1+1=2
printf("%d %d\n", i, j);
return 0;
}
Execute int j = i + ++i;
prioridade de análise: auto-incremento é maior que +, que se torna int j=++i + i;
antes da operação : por causa de ++i, a variável i é incrementada em um (0 +1=1); Neste momento, i=1
operação : adicione i, e i ainda é 1 neste momento, portanto, após atribuir 1+1=2 à
operação j : nenhum