4.1Por que é que os parâmetros existentes nas macros não têm tipos de dados?

4.2Defina a macro toupper(ch) que deverá converter o valor de ch para maiúsculas.

4.3Qual a expansão que seria produzida pelo pré-processador a partir do seguinte trecho, utilizando a macro definida no item anterior?

#define FIRST ‘A’

#define LAST ‘Z’

main()

{

int ch = 65; /* ASCII do ‘A’ */

printf(“%c %c”, toupper(FIRST+2), toupper(LAST+’a’-ch));

}

4.4Qual a saída que seria gerada pela execução desse programa?

Passo 1

Fala aí! Essa aqui é legal, envolve uma partezinha conceitual e uma prática, bora lá.

Os macros não têm tipos de dados porque eles são substituídos pelo pré-processador, antes mesmo de o código chegar no compilador. Então, o macro simplesmente faz a substituição dos parâmetros recebidos pela expressão nele definida, sem se importar com o tipo de dado que foi passado.

Passo 2

Vamos definir nosso macro utilizando a diretiva #define, da seguinte forma:

Olha só o que estamos fazendo aqui, utilizamos o operador ? para escrever:

Se o caractere ch for maior que o caractere ‘a’ E menor que o caractere ‘z’, subtraia 32 de ch, se não, mantenha ch.

Perceba que, quando comparamos se um caractere é maior que outro, bem como mandamos subtrair ou somar um valor de um caractere, estamos nos referindo aos seus valores ASCII. Dá só uma olhada na tabela a seguir:

Perceba que a diferença entre um caractere maiúsculo e o mesmo caractere minúsculo é sempre igual a 32. Portanto, se pegarmos, por exemplo, o caractere “k” e subtrairmos dele 32, chegamos no caractere de ASCII 75, que é o “K”.

Passo 3

Para resolver a próxima, basta percebemos que se trata de uma simples questão de substituição de variáveis. Olha só, invocamos o macro toupper(ch) duas vezes e passamos como parâmetros (FIRST+2) e depois (LAST + ‘a’ – ch), certo? Então, lembrando que definimos FIRST como ‘A’ e LAST como ‘Z’, vamos ver como fica:

Simplesmente substituímos ch por ‘A + 2 na primeira ocorrência e ch por ‘Z’ + ‘a’ – ch na segunda.

Passo 4

Beleza, agora vamos pensar no que seria a saída deste programa. Olha só, a primeira coisa é perceber que temos duas variáveis do tipo char sendo passadas para uma instrução printf pelos operadores %c, certo? Então, já sabemos que vamos imprimir dois caracteres na tela do usuário, falta descobrir quais são os caracteres. Para isso, vamos olhar para o nosso macro.

Na primeira instância, foi passado o parâmetro A+2 para nosso macro, como resultado vamos devolver o caractere C, de ASCII 67, tranquilo?

Para a segunda, temos que descobrir qual o caractere resultante da expressão ‘Z’ + ‘a’ – ch. Bom, tendo em mente que o programa nos passou o valor de 65 – ASCII do caractere ‘A’ – para a variável ch, basta olharmos para a tabela ASCII, substituirmos os valores dos caracteres “Z” e “a” e fazer as contas. Temos então ‘Z’ + ‘a’ – ch = 90 + 97 – 65 = 122, que corresponde ao caractere “z”.

Portanto, a saída gerada seria:

Resposta

4.1Os macros não têm tipos de dados porque eles são substituídos pelo pré-processador, antes mesmo de o código chegar no compilador.

4.2

4.3

4.4C z