Вы находитесь на странице: 1из 6

Relatório sobre as soluções encontradas dos problemas

propostos pelo projeto prático da matéria de Fundamentos de


Programação
Bruno Roberto Reis Alves, Juan Carlo França Gaspar

Bacharel em Sistemas de Infomação – Universidade Tecnológica Federal do Paraná


(UTFPR) – Curitiba – PR – Brazil

Abstract. This report aims to briefly describe the problems proposed by the
practical project and the main strategies found to develop each program, as
long as they meet the functionalities specified in each problem.

Resumo. Este relatório tem como finalidade descrever sucintamente os


problemas propostos pelo projeto prático e as principais estratégias
encontradas para desenvolver cada programa, desde que atendam às
funcionalidades especificadas em cada problema.

1. Construção do calendário

O primeiro problema pede para que se construa um programa que produza uma folha de
calendário anual. Neste sentido, o programa lê o ano informado pelo usuário, e a partir
de uma série de funções retorna o calendário inteiro daquele ano. Após a leitura, o
programa chamará a função que mostram o nome do mês (de acordo com seu respectivo
número) e o formata, mostrando todos os dias do mês. Para tal, utilizou-se outras
funções como ferramentas auxiliares, como o algoritmo de Zeller (adaptado de
CHAPMAN, 1991), para se calcular o primeiro dia de cada mês e outra função para
definir o último dia de cada mês, levando em consideração anos bissextos.

2. Operadores de bits

Como a linguagem C foi idealizada de forma a se aproximar da linguagem de máquina,


se fez necessário a presença de operadores que manipulem binários em sua estrutura,
uma vez que computadores consideram todos os dados como sequências de bits,
tornando, assim, o C mais robusto para o propósito de se trabalhar em baixo nível
(DEITEL; DEITEL, 2016, SCHILDT, 2000). Manipulação de bits, de modo geral,
podem ser uteis para a criação de uma série de programas, sejam eles compiladores,
sistemas operacionais, encriptadores, programas gráficos e diversos outros usos (KING,
2008).
A manipulação de bits pode ser realizada em quase todos os tipos em C, int –
short, long, long long – e em char, porém não em tipos mais complexos como float,
double ou void (KERNIGHAN; RITCHIE, 1988 , KOCHAN, 2005, SCHILDT, 2000).
A Tabela 1 exemplifica os operadores bit a bit (bitwise) permitidos na linguagem C.
Tabela 1. Operadores bitwise

Símbolo Significado (bit a bit)


<< Deslocamento à esquerda
>> Deslocamento à direita
- Complementar
& E
^ Ou exclusivo
| Ou inclusivo
Fonte: Adaptado de KING (2008)

O operador “&” atua de forma similar ao operador de lógica “&&”. Converte-se


o numero para sua forma binária, por exemplo, 25(0011001) e 77(1001101) e faz-se o
uso do operador, conforme exemplificado na Figura 1. Ele atua fazendo a verificação bit
a bit de dois (caso do exemplo) ou mais números, e somente retornará valor
verdadeiro(1) quando o bit correspondente de cada operando for 1, do contrário, retorna
falso (0) (DEITEL; DEITEL, 2016). O resultado, em base 2, é, então, convertido para
decimal.

Figura 1. Operação binária & entre 25 e 77.

Fonte: Adaptado de KOCHAN (2005)

Percebe-se então o comportamento similar do operador de bits “&” a sua


contraparte lógica “&&” à medida que ambos são governadas pela mesma tabela
verdade, retornando verdadeiro apenas se todas as condições são atingidas – a diferença
entre eles reside no fato de que && é usado em expressões lógicas para retornar 0 ou 1,
enquanto o operador & trabalha bit por bit e poderá retornar qualquer valor arbitrário.
(KOCHAN, 2005, SCHILDT, 2000).
Os operadores “<<” e “>>” são operadores que fazem o deslocamentos de bits,
tanto à esquerda, quanto à direita (SCHILDT, 2000). Ou seja, ele pega cada bit em sua
posição inicial e desloca tantos índices quanto for informado, no sentido apontado pelo
operador, conforme representado no exemplo da Figura 2. Todos os bits que retornam
verdadeiro presentes na representação binária do decimal “5” (00000101) foram
deslocados “3” casas (00101000), uma vez que a operação realizada foi 5<<3.

Figura 2. Exemplo de uso do operador binário “<<”


Fonte: Autoria própria

Analisando-se os resultados, apresentados na Tabela 2, percebe-se um padrão


quando da utilização do operador <<. Pode se, então, observar a analogia entre “<<” e a
operação da multiplicação (*), indicada pelo fato do numero à esquerda multiplicado
por 2 elevado à potencia do numero à direita resultar no mesmo valor se comparado ao
uso do operador binário em questão.

Tabela 2. Comparação entre a operação com o operador binário << e a


multiplicação

Operação com ‘<<’ Operação de multiplicação


5<<1 = 10 5 * 21 = 10
5<<2 = 20 5 * 22 = 20
5<<3 = 40 5 * 23 = 40
5<<4 = 80 5 * 24 = 80

Fonte: Autoria própria

As respostas a seguir referem-se a questão 2 do Projeto Prático 1, com a linha de


código adaptada representada na Figura 3; a adaptação foi feita para melhor
compreensão dos laços.

Figura 3. Linha de código – questão 2

Fonte: adaptado de DORINI e DELGADO (2019)

1. Conforme demonstrado na Figura 2 e Tabela 1, o operador “<<” irá deslocar, 7


posições à esquerda, o único bit que representa o número 1(00000001), o qual se
encontra no índice “0”; logo a constante SIZE terá o valor de 2 7 = 128(10000000) . Com
isso, modifica-se o tamanho do qual o laço irá percorrer, por consequência o tamanho da
figura geométrica.
2. É possível, também, responder de outra forma ao problema proposto. Ao invés de
usar operadores binários, usar uma série de funções as quais: converta numeros
decimais para binários, depois compare os binários entre si, bit a bit, em busca de 1 no
mesmo indice, outra função, para transformar esse novo numero em binario, mantendo
os 0s e 1s nas posições corretas e mais uma para converter este novo binario novamente
para decimal. Após essa série de cálculos, poderia-se, finalmente, iniciar os laços
predeterminados no exercicio.

2.1 Resolução do teste:

Ao definir a constante SIZE como (1 << 4), ela passará a ter o valor de 16 (decimal).
Neste sentido, o primeiro laço irá percorrer de 15 (SIZE-1) até 0, o que representa cada
linha da figura geométrica. Ou seja, este laço estará definindo o numero de linhas, uma
vez que além de percorrer “SIZE” vezes e chamar os laços internos, também pula
linhas. Em um segundo momento, para cada passagem deste primeiro laço, dois outros
laços serão percorridos: o primeiro percorre de 0 até o tamanho da linha atual menos
uma unidade, o outro percorre do último número do laço anterior até a quantidade
faltante para chegar a 16.

Tendo isso em vista, pode-se notar como consequência que, na medida em que o limite
do primeiro laço interno diminui, o segundo aumenta. Este comportamento está
representado na Figura 4, onde o caractere “.” representa a ação feita pelo laço (a) da
Figura 3, “-” pelo laço (b) e “*” pelo laço (c).

Figura 4. Representação da lógica dos laços

Fonte: autoria própria

Como foi possível observar na Figura 4, a cada nova linha (de 16 a 1), haverá uma
menor contribuição do primeiro laço interno em comparação ao segundo laço; é
importante salientar que esta Figura não leva em consideração o que cada laço
teoricamente deveria imprimir, mas sim como os mesmos estão atuando linha a linha.

Ao entrar no segundo laço, nota-se o uso de um operador ternário (?), dependente de


uma condição representada por uma operação binária (&). Com isso, pode-se perceber
que, na Linha 1, por exemplo, ocorrerão testes bit a bit entre x e y: caso retorne
verdadeiro haverá a impressão de um espaço, ou se falso, a impressão do caractere “*”
mais um novo espaço; como i apresenta-se nesta linha com valor 0, não haverá valores
verdadeiros, então somente “*” seriam impressos. Diferente da linha 2, onde o laço (b)
seria ativado uma única (i=0), e pela última (já que após o incremento, ele passa a ser
igual a y), vez, imprimindo um espaço e o laço (c) faria testes entre os índices do
números binários em busca de valores 1 e retornando verdadeiro ou falso até a
quantidade faltante de 16 (16-1=15). A ocorrência deste comportamento é observado em
todas as linhas controladas pelo laço externo (a).

3. Codificar e/ou decodificar uma mensagem.

O terceiro problema envolve duas partes: criar um menu para que o usuário decida o que
deseja fazer e, com isso, codificar ou decodificar uma mensagem. Para aquela primeira
decisão, o programa lê cada letra da mensagem até o ponto final e as converte para
binário. Caso o número de bits deste binário for ímpar, então é adicionado um bit ao
número mais significativo (digito mais à esquerda). Após feito, está mensagem é
convertida novamente, desda vez para decimal, e mostrado ao usuário.

Em um segundo momento de decisão, o programa lê uma séria de números decimal.


Logo em seguida, todos estes números são convertidos para binário e, a partir disso, são
contatos quantos números de bits esses binários possuem. Caso alguns desse binários
forem ímpares, isto significa que a mensagem sofreu interferência e, portanto, é
mostrado o caractere “*” no lugar dessa respectiva letra. Em outro caso, esses números
são convertidos para inteiros em decimal e, posteriormente, são mostrados ao usuário, já
convertidos em caractere, obtidos na tabela ASCII.

4. Validar um cartão bancário

O último problema envolver construir um programa que, dado um número, identifica a


operadora e verifica a validade desse cartão. Para resolver este problema, primeiramente
é lida uma sequência de números e é contado quantos dígitos esse cartão possuí. Após
feito, é verificado se todos os dígitos são números. Caso for verdadeiro, então o é
passado para a terceira e quarta verificação as quais conferem se a quantidade de dígitos
está no intervalo de 13 a 16 dígitos. Se novamente for verdadeiro, então é chamado uma
outra função que mostra o nome da operadora, se existir; e, se os números são válidos
através do algoritmo de Luin. No caso de não passar em nenhuma verificação, o usuário
é informado o motivo pelo qual não foi possível dar prosseguimento.
REFERÊNCIAS

DEITEL, P.; DEITEL, H. (2016.). C How to program: with and introduction to C++.
Londres: Pearson, 8th ed..

DORINI, L.; DELGADO, M. Projeto Pratico1. Disponivel em:


<http://moodle.dainf.ct.utfpr.edu.br/pluginfile.php/46962/mod_assign/intro/pp01.pdf?
time=1555339673692>. Acesso em 4 mai 2019.

KERNIGHAN, B.; RITCHIE, D. (1988). C Programming Language. New Jersey:


Prentice Hall, 2nd ed..

KING, K. (2008). C Programming: a modern approach. New York: W. W. Norton, 2 nd


ed..

KOCHAN, S. (2005). Programming in C. Indianapolis: Sams Publishing, 3th ed..

SCHILDT, H. (2010). C: the complete reference. Berkeley: McGraw-Hill, 4th ed..

CHAMPAM, W.A.(1991). Cmastering C Programming. New York: Palgravre


Macmillan.