[C Language Elementary] Leva você a brincar facilmente com todos os operadores comuns O capítulo final - referência de subscrito, chamada de função e membro de estrutura, avaliação de expressão

insira a descrição da imagem aqui

Página inicial pessoal de Junxi_

Seja diligente e encoraje os anos a não esperar por ninguém

Desenvolvimento de jogos C/C++


Olá, aqui é Junxi_, eu estava muito ocupado há alguns dias e não tive tempo de atualizar, e agora finalmente estou livre. Este é o segundo artigo da atualização explosiva do fígado de hoje e também é o último artigo do nosso [C Language Elementary] para levá-lo a brincar com todos os operadores comumente usados ​​facilmente. Não vamos falar bobagem, vamos direto ao ponto

  • Antes do início oficial, ainda usamos um mapa mental para ajudar a relembrar brevemente o conteúdo básico dos operadores

insira a descrição da imagem aqui

  • Vamos para a última parte

1. Referências de subscrito, chamadas de função e membros de estrutura

1. [ ] operador de referência de subscrito

O operando deste operador: um nome de array + um valor de índice

int arr[10];//Cria um array
arr[9] = 10;//Prático operador de referência de subscrito.
Os dois operandos de [ ] são arr e 9.

  • Observe aqui que arr e 9 são apenas dois operandos de "[]", então também podemos escrever o array assim:
9[arr];
  • O código da prova é o seguinte:
int main()
{
    
    
	int arr[10] = {
    
     1,2,3,4,5 };//不完全初始化,此时后面未初始化元为0
	//              
	//数组的起始是有下标的,下标是0开始的
	printf("%d\n", arr[2]);//[] 下标引用操作符,arr 和 2 是[] 的两个操作数
	printf("%d\n", 2[arr]);
	return 0;
}

insira a descrição da imagem aqui

  • Mas geralmente para a legibilidade e fluência do código, é melhor não escrever assim, aqui está apenas para dizer que é correto escrever assim!

2. ( ) operador de chamada de função

  • Aceita um ou mais operandos: o primeiro operando é o nome da função e os demais operandos 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;
}
  • É muito simples e você já viu isso muitas vezes em sua vida diária, então não vou entrar em detalhes aqui.

3. Acessando membros de uma estrutura

  • Normalmente existem duas formas
. 结构体.成员名
-> 结构体指针->成员名

"." Estrutura. Nome do membro

  • 这种通常用于直接访问结构体成员
struct Book
{
    
    
	char name[30];//成员
	char author[20];
	float price;
};


int main()
{
    
    
	struct Book b1 = {
    
     "C语言", "zz",99.6f };
	struct Book b2 = {
    
    "数据结构","yy",88.6f};//书
	printf("%s %s %.1f\n", b1.name, b1.author, b1.price);
	printf("%s %s %.1f\n", b2.name, b2.author, b2.price);

	//结构体变量.成员名
	return 0;
}

-> ponteiro de estrutura -> nome do membro

  • 主要用于在结构体传参时通过结构体指针找到对应结构体成员
  • código mostra como abaixo:
struct Book
    {
    
    
    	char name[30];//成员
    	char author[20];
    	float price;
    };
    
    void Print(struct Book * p)
    {
    
    
    	printf("%s %s %.1f\n", (*p).name, (*p).author, (*p).price);
    	printf("%s %s %.1f\n", p->name, p->author, p->price);
    	//->
    	//结构指针->成员名
    }
    
    int main()
    {
    
    
        struct Book b1 = {
    
     "C语言", "zz",99.6f };
       	struct Book b2 = {
    
    "数据结构","yy",88.6f};//书
    	Print(&b1);
    	Print(&b2);
    
    
    	//printf("%s %s %.1f\n", b1.name, b1.author, b1.price);
    	//printf("%s %s %.1f\n", b2.name, b2.author, b2.price);
    
    	//结构体变量.成员名
    	return 0;
    }



2. Avaliação da expressão

  • A ordem na qual as expressões são avaliadas é determinada em parte pela precedência e associatividade dos operadores.
    Da mesma forma, os operandos de algumas expressões podem precisar ser convertidos em outros tipos durante a avaliação

1. Conversão implícita de tipo

  • As operações aritméticas inteiras de C são sempre 以缺省整型类型的精度executadas por pelo menos .
  • Para obter essa precisão,Operandos de caractere e inteiro curto em expressões são convertidos em tipos inteiros normais antes do uso, essa conversão é chamada de promoção de inteiro.
  • Significado da promoção inteira:
  • A operação de número inteiro da expressão deve ser executada no dispositivo de operação correspondente da CPU. O comprimento do byte do operando da unidade aritmética inteira (ALU) na CPU é geralmente o comprimento do byte de int e também é o comprimento do registrador de uso geral da CPU.
  • Portanto, mesmo que os dados de dois tipos de caracteres sejam adicionados, eles devem primeiro ser convertidos para o comprimento padrão do operando inteiro na CPU quando a CPU executa .
  • É difícil para uma CPU de uso geral (CPU de uso geral) adicionar diretamente dois bytes de dados de 8 bits (embora possa haver tais instruções de adição de byte em instruções de máquina). Portanto, os vários 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 cálculo.
//实例1
char a,b,c;
...
a = b + c;
  • Os valores de b e c são promovidos a inteiros normais antes que a operação de adição seja realizada.
    Após a conclusão da operação de adição, o resultado é truncado antes de ser armazenado em a.

Como realizar a melhoria geral?

  • A promoção de inteiro é promovida de acordo com o bit de sinal do tipo de dados da variável
  • O código de exemplo é o seguinte:
//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0
  • Exemplos de reforços de plástico:
//实例1
int main()
{
    
    
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if(a==0xb6)
printf("a");
if(b==0xb600)
printf("b");
if(c==0xb6000000)
printf("c");
return 0;
}
  • No exemplo 1, a e b precisam ser melhorados, mas c não precisa ser melhorado
  • Depois que a e b são promovidos plasticamente, eles se tornam números negativos, então o resultado da expressão a== 0xb6, b == 0xb600 é falso, mas se c não sofre promoção plástica, o resultado da expressão c==0xb6000000 é verdadeiro.
    insira a descrição da imagem aqui
//实例2
int main()
{
    
    
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(-c));//%u - 10进制的形式打印无符号的整数
return 0;
}
  • No exemplo 2, desde que c participe da operação de expressão, a promoção de número inteiro ocorrerá e a expressão +c será promovida, então sizeof(+c) é 4 bytes.
  • A expressão -c também sofre promoção plástica, então sizeof(-c) é 4 bytes, mas sizeof(c) é 1 byte.
    insira a descrição da imagem aqui

2. 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 .
  • A seguinte hierarquia é chamada de conversão aritmética ordinária

long double
double
float
unsigned long int
long int
unsigned int
int
acima digite de alto -> baixo

  • Se o tipo de um operando for inferior na lista acima, ele deve primeiro ser convertido para o tipo do outro operando antes de realizar a operação
  • Perceber:
    A conversão aritmética deve ser razoável, caso contrário, haverá alguns problemas potenciais
float f = 3.14;
int num = f;//隐式转换,会有精度丢失

3 Propriedades dos operadores

  • Existem três fatores que afetam a avaliação de expressões complexas.
    1. 操作符的优先级
    2. 操作符的结合性
    3. 是否控制求值顺序。
  • Qual dos dois operadores adjacentes é executado primeiro? Depende de suas prioridades. Se ambos tiverem a mesma prioridade, depende de sua associatividade.
  • operador precedente
    insira a descrição da imagem aqui
    insira a descrição da imagem aqui
    insira a descrição da imagem aqui
    insira a descrição da imagem aqui
    insira a descrição da imagem aqui

Algumas expressões com problemas

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

Notas:代码1在计算的时候,由于*比+的优先级高,只能保证,*的计算是比+早,但是优先级并不能决定第三个*比第一个+早执行。

  • Portanto, a ordem das expressões do computador pode ser:
a*b
c*d
a*b + c*d
e*f
a*b + c*d + e*f
或者:
a*b
c*d
e*f
a*b + c*d
a*b + c*d + e*f
  • Exemplo 2
//表达式2
c + --c;

Notas:同上,操作符的优先级只能决定自减--的运算在+的运算的前面,但是我们并没有办法得知,+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。

  • Exemplo três
int fun()
{
    
    
  static int count = 1;
  return ++count;
}
int main()
{
    
    
  int answer;
  answer = fun() - fun() * fun();
  printf( "%d\n", answer);//输出多少?
  return 0;
  }
  • Embora os resultados sejam os mesmos na maioria dos compiladores.
  • Mas no código acima responda = fun() - fun() * fun(); só podemos saber pela prioridade do operador: primeiro calcule a multiplicação, depois calcule a subtração.
  • A ordem na qual as funções são chamadas não pode ser determinada pela precedência dos operadores.
  • Exemplo quatro
#include <stdio.h>
int main()
{
    
    
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}
//尝试在linux 环境gcc编译器,VS2013环境下都执行,看结果。
  • O resultado do ambiente Linux:
    insira a descrição da imagem aqui

  • O resultado do ambiente VS2013:
    insira a descrição da imagem aqui

  • Veja o mesmo código produz resultados diferentes, por quê?

  • Quando o primeiro + neste código é executado, se o terceiro ++ é executado é incerto, porque a ordem do primeiro + e do terceiro ++ anterior não pode ser determinada dependendo da prioridade e associatividade dos operadores.

Resumo:
Se a expressão que escrevemos não pode determinar o único caminho de cálculo através dos atributos do operador, então há um problema com esta expressão!


Resumir

Não é fácil para um novo blogueiro criar. Se você acha que o conteúdo do artigo é útil para você, clique neste novo blogueiro antes de sair. Seu apoio é minha motivação para atualizar! ! !

**(Ke Li pede para você apoiar o blogueiro três vezes seguidas!!! Clique no comentário abaixo para curtir e coletar para ajudar Ke Li)**

insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/syf666250/article/details/131435676
Recomendado
Clasificación