Ir ao conteúdo
  • Cadastre-se

C Comando de uma função em C


PenseC
Ir à solução Resolvido por Lucca Rodrigues,

Posts recomendados

Gente, estou lendo um livro de programação em C.

No capítulo sobre funções, o autor me forneceu um exemplo com os seguintes comandos com o intuito de fazer uma função que fizesse qualquer letra ficar maiúscula.

Mas eu não entendi a parte em NEGRITO. Algum ninja aí poderia me explicar?

Desde já, Obrigado!

 

#include <stdio.h>
#include <stdlib.h>

int x_toupper(char ch)
{
    if (ch>='a'&& ch<='z')
        return ch + 'A'- 'a';    <----- ESSA LINHA
    else
        return ch;
}
int main()
{
    char c;

    while (1)
    {
        c=getchar();
        putchar(x_toupper(c));
    }
    return 0;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Solução

@PenseC Veja a tabela ASCII:

image.png.6f79442f72664537e3f41b3caff48593.png

Percebe que o caractere A maiúsculo equivale a 65 em decimal e o A minúsculo, 97?

 

Agora, vamos ao código:

34 minutos atrás, PenseC disse:

if (ch>='a'&& ch<='z')
    return ch + 'A'- 'a';    <----- ESSA LINHA

Isso se traduz como: caso a variável ch esteja entre as letras A e Z minúsculas, o que será retornado (considerando que sua função é do tipo inteiro) é a variável ch + o valor em decimal de A maiúsculo - o valor em decimal de A minúsculo, isto é, ch + (65 - 97).

65 - 97 = -32, e observando a tabela ASCII, é notável que a diferença entre as letras maiúsculas e minúsculas é exatamente 32, então, se o caractere em questão for uma letra minúscula, será subtraído 32 de seu valor em decimal para convertê-lo para uma letra maiúscula.

Acho que seria mais simples apenas retornar ch - 32, não sei pra que essa complicação...

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Interessante que se pegar os valores binários dessa tabela dá para perceber como converter com uma máscara e o operador de bits. Para converter para maiúscula, p.ex,

 

A = 65 decimal e 1000001

a = 97 decimal e 1100001

 

Com a máscara 1011111 (95 decimal) é só fazer um AND para zerar o segundo dígito e sempre converter para maiúscula,

 

a AND 95  = 1100001 AND 1011111 = 1000001.

 

#include <stdio.h>

char maiuscula(char c){
    return c & 95;
}

int main(void) {
    char c;

    while(1){
        c = getchar();
        putchar(maiuscula(c));
    }
    return 0;
}

 

Para converter para minúscula, OU com máscara 0100000 (32).

 

  • Curtir 2
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, PenseC disse:

if (ch>='a'&& ch<='z')         return ch + 'A'- 'a';    <----- ESSA LINHA     else         return ch;

 

1 hora atrás, Lucca Rodrigues disse:

Acho que seria mais simples apenas retornar ch - 32, não sei pra que essa complicação

 

Em geral se escreve assim justamente por isso: complicação é escrever 32, que parece um número mágico.

 

Por outro lado, se você imaginar que os códigos das letras de 'a' em diante possam estar em ordem alfabética e os códigos de 'A' em diante também, pode imaginar que 'c' - 'a' == 2 por exemplo, já que 'c' é a terceira letra e 'a' é a primeira.
Pela mesma razão se imagina que a diferença entre 'a' e 'A' seja a mesma que entre qualquer letra minúscula  e sua equivalente maiúscula, seja essa diferença 32 ou 5,67. E assim é mais legível escrever 'a' - 'A' ou 'z' - 'Z' para converter minúscula para maiúscula, porque se imagina que a diferença entre as letras permaneça em qualquer código, já que a ordem alfabética é um conceito bem estabelecido.

 

Mais referências :)  históricas:

  • apesar de maiúsculas serem até ditas como "caixa alta", o código das maiúsculas é menor. Inicialmente sequer haviam letras minúsculas nos programas e impressoras, e era até um avanço do código ASCII quando criado.  COM aquelas letrinhas
     
  • 32 é o bit 5 então pode fazer a conversão com um and, tipo
     
        maiuscula = minuscula & (~32);

     

  • De todo modo o compilador vai gerar esse código mesmo
     
  • 32 também é o efeito de apertar a tecla Control ao digitar: Control-A vale 1, porque apertar control faz um AND com 32 antes de gerar o código. Como A = 65 e 'a' - 97 os dois vão virar 1. e o Z vai gerar 26, já que a conta é a mesma

 

 

 

35 minutos atrás, Midori disse:

Com a máscara 1011111 (95 decimal) é só fazer um AND para zerar o segundo dígito e sempre converter para maiúscula

 

Sim! Seria um AND com ~32, não por acaso 95 que é 127 --- que seriam os sete bits 1 --- menos 32 que é o bit 5. No compacto ~32 já que '~' é o notebook em C e inverte os bits todos

  • Curtir 2
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!