Apostila - Pensamento-Computacional
Apostila - Pensamento-Computacional
Apostila - Pensamento-Computacional
COMPUTACIONAL
PARA INDÚSTRIA 4.0
Professores Reginaldo Barbosa Nunes & Victorio Albani de Carvalho
Ministério da Educação
Ministro da Educação
Milton Ribeiro
Campus Vitória
Diretor Geral
Hudson Cogo
Diretor de Extensão
Christian Mariani Lucas dos Santos
Oficinas 4.0
Coordenação Geral
Rodrigo Varejão Andreão
Marcelo Queiroz Schimidt
Gabriel Tozatto Zago
Jordando Celestrini
Professores Autores
Reginaldo Barbosa Nunes/Ifes
Victorio Albani de Carvalho
Equipe Pedagógica
Ítalo Severo/Ifes
Wagner Scopel/Ifes
Jaqueline Almeida/Ufes
Laboratório
LabTef - Ifes - Campus Vitória
A nossas famílias, por sua compreensão em tempos de Cornavírus.
3 ••••
Agradecimentos
Agradeço a todos que contribuíram para a realização deste trabalho.
4 ••••
Indicação de ícones
Os ícones são elementos gráficos utilizados para ampliar as formas de linguagem e facilitar a
organização e a leitura hipertextual
Atenção:
Indica pontos de maior relevância no texto
Saiba mais:
oferece novas informações que enriquecem o assunto ou notícias recentes
relacionadas ao tema estudado.
Glossário:
indica a definição de um termo, palavra ou expressão utilizada no texto.
Mídias integradas:
sempre que se desejar que os estudantes desenvolvam atividades empregando
diferentes mídias: vídeos, filmes, jornais, ambiente AVEA e outras.
Exemplo:
apresenta um exemplo ou um exercíco resolvido a fim de que o estudante
possa compreender melhor o conteúdo estudado.
5 ••••
“As invenções são, sobretudo, o resultado de um trabalho teimoso.”
(Santos Dumont)
6 ••••
Sumário
INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Apresentação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Palavra do Professor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Apresentação do Curso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
PENSAMENTO COMPUTACIONAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Conceito de Pensamento Computacional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Sistemas de Computadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
O Hardware dos Computadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
O Software dos Computadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Sistemas de Numeração . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Notação posicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Conversão entre bases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Representação dos Dados no Computador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Tipos Básicos de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Ambientes de Programação C/C++ e Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Declaração de Variáveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Atribuição de valor a Variáveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
INTRODUÇÃO À LÓGICA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Conceitos Básicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Construção de Algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37
Controle do Fluxo de Execução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Fluxo Sequencial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Entrada e Saída de Dados em C/C++ e Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Operadores Lógicos, Relacionais e Aritméticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Fluxo de Execução com Estruturas de Decisão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Estrutura de Seleção Simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Estrutura de Seleção Múltipla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
Fluxo de Execução com Estrutura de Repetição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Estruturas de Repetição. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Estrutura para número de Repetições conhecidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Comandos de Desvio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7 ••••
MODULARIZACÃO E FUNÇÕES. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Funções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Construindo Funções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Passagem de Parâmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Módulos em Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Importando parte de um Módulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Bibliotecas e Cabeçalhos em C/C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Criando o Arquivo Cabeçalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Criando o Arquivo .cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Criando o arquivo biblioteca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
ESTRUTURAS DE DADOS COMPLEXAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Estruturas Homogêneas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Listas e Tuplas em Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Acessando Elementos nas Estruturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Percorrendo Listas e Arrays usando Laços . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Métodos Associados a uma Lista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Estruturas de Dados Heterogêneas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
struct em C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Atribuindo e Acessando os Dados em uma Struct . . . . . . . . . . . . . . . . . . . . . . . . . 80
Dados Heterogêneos em Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Persistência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Persistência em Arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
REFERÊNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8 ••••
Introdução
Apresentação
Prezado estudante,
Bem-vindo ao projeto Transformação Digital!
Você faz parte de uma rede nacional pública de ensino, o Instituto Federal do Espírito Santo, e
agora ao LabTef - Laboratório de Tecnologias do Futuro, que tem o objetivo de democratizar o acesso
as transformações digitais pelas quais o mundo atual esta passando. Neste curso, isto se dará a partir
de ensino de programação na modalidade a distância. Este projeto é resultado de uma parceria entre
o Ministério da Educação, por meio das Secretarias de Educação a Distancia (SEED) e de Educação
Profissional e Tecnológica (SETEC), as universidades e Institutos estaduais e federais.
A educação a distância no nosso país, de dimensões continentais e grande diversidade regional
e cultural, longe de distanciar, aproxima as pessoas ao garantir acesso à educação de qualidade, e
promover o fortalecimento da formação de jovens moradores de regiões distantes, geograficamente
ou economicamente, dos grandes centros, especialmente quando o mundo passa por uma crise
de proporções consideráveis e nos obriga à contenção e ao isolamento social em virtude dessa
pandemia (Covid19).
Este projeto leva cursos atualizados voltados para o desenvolvimento das capacidades
cognitivas alinhadas à mundo digital, incentivando os jovens a se engajar no processo de
transformação digital pelo qual passam nossa sociedade, quer seja na indústria no comécio e
principalmente na a educação. O Ministério da Educação, as instituições públicas de ensino, seus
servidores técnicos e professores acreditam que uma educação profissional qualificada e integradora
é capaz de promover o cidadão com capacidades para produzir, mas também com autonomia diante
das diferentes dimensões da realidade: cultural, social, familiar, esportiva, política e ética.
Caro Aluno,
Se Você ainda se pergunta: Por que estudar programação?
Vamos à resposta: Desde o lançamento dos primeiros computadores pessoais, ferramenta
que tem se tornado cada vez mais popular, essas tecnologias vêm evoluindo, aumentando seu
grau de penetração na sociedade e sendo utilizadas na realização das mais variadas tarefas, seja no
comércio, na indústria, na academia e até mesmo no cotidiano das pessoas. Ter conhecimentos sobre
computação deixou de ser uma opção e tornou-se necessidade, não só para inclusão no mercado de
trabalho, mas até para relacionar-se com pessoas ou grupos de interesse.
Há alguns anos, na área de informática, você poderia optar por três a quatro especializações
apenas; hoje estas possibilidades se multiplicaram, pelo fato de a informática permear praticamente
todas as atividades da sociedade moderna. Entretanto, dentre estes caminhos possíveis, a
programação ainda apresenta uma das maiores demandas de técnicos. Além disto, o estudo de
programação desenvolve um tipo de raciocínio (sequencial e lógico) base para resolver problemas
de várias outras áreas.
A formação deste tipo de raciocínio, necessário para você prosseguir com sucesso na
programação, é o principal objetivo deste curso. Embora exista uma certa dificuldade dos estudantes
de estruturar um raciocínio lógico computacional, nesta oficina, vamos ajudá-lo no desenvolvimento
de sua capacidade de abstração e análise de situações problema e de elaborar estratégias para
solucioná-las.
Se você não tem experiência com computadores, ainda assim você poderá realizar este curso
e concluí-lo com bom aproveitamento. Esta afirmativa é feita baseada em nossa experiência com
vários alunos de cursos presenciais, que chegam sem nenhuma experiência, enfrentando algumas
dificuldades no começo, mas que conseguem se superar e se tornam bons programadores. Como o
aluno a distância é especial, acreditamos que também conseguirá superar as dificuldades iniciais. Se
for preciso, peça a ajuda da equipe de apoio e também o auxílio de seus colegas.
Lembre-se: a melhor forma de aprender é praticando! Esta frase é ainda mais verdadeira para
a programação. Assim, organize seu tempo, dedique-se ao curso e aproveite: você deverá divertir-se
durante o processo de aprendizado.
Um abraço!
Prof. Reginaldo Barbosa Nunes
O curso de Programação para Transformação Digital será seu primeiro passo no aprendizado da
programação de computadores. Assim, ela é de fundamental importância para o seu desenvolvimento
nesta área, pois é nele que você aprenderá os fundamentos básicos que servirão de alicerce para os
desafios que a transfomação digital exige dos profissionais e cidadãos de modo geral.
Neste curso você aprenderá os principais conceitos sobre o pensamento computacional
e sobre programação. Entenderá o funcionamento básico de um computador, como ele trata os
diversos tipos de informação e aspectos sobre o armazenamento destas informações. Irá aprender
como traduzir instruções da linguagem natural para as linguagens utilizadas pelos computadores,
como C++ e Python. Além disso, terá a oportunidade de aplicar esses conceitos na prática, criando
algoritmos e programas completos e funcionais utilizando uma dessas duas linguagens de
programação.
A formação do raciocínio, necessário para você prosseguir com sucesso na programação, é o
principal objetivo deste curso. Por isso, nas primeiras aulas, você usará sua linguagem natura, porém
com uma sintaxe formal para escrever programas, mas que não é uma linguagem de programação
(no sentido ser entendida pelo computador). Na sequência do curso você estudará também as
linguagem C e Python.
Por que escolhemos estas duas linguagens para você iniciar com a programação? Porque C é
a base da sintaxe de diversas outras linguagens de programação, inclusive para Internet (Java, PHP,
Java Script...), com as quais você lidará caso pretenda continuar nesta área.
E o Python? Bem, esta linguagem tem ganhado um enorme destaque nos últimos anos. Dentre
todas as características dessa linguagem de programação, sem sombra de dúvidas, a simplicidade
é a que mais chama a atenção. Para usá-la, basta instalá-la em seu sistema e chamá-la no console.
Python nasceu com esse objetivo: ser simples, acessível e fácil de usar. Entretanto, não podemos
atribuir o sucesso da linguagem a um único fator. A tecnologia é muito mais que simplicidade.
Lembre-se de que, apesar de se tratar de um curso a distância, você não está sozinho nesta jornada.
Qualquer dúvida que tenha poderá acionar o tutor a distância e, sempre que necessário, poderá
solicitar que o tutor entre em contato com o professor. Além disso, temos à nossa disposição um
ambiente virtual cheio de recursos para nos auxiliar neste processo.
Decomposição
Corresponde à habilidade de dividir um problema complexo em partes menores. Trabalhar um
fragmento do problema por vez facilita a solução desse problema, permitindo ainda maior atenção a
cada etapa. A decomposição ajuda a diminuir a ansiedade e o medo frente aos desafios. E possibilita
encontrar as respostas de cada parte do problema com mais confiança e rapidez, enquanto seguem
um passo a passo para a solução da grande questão.
Reconhecimento de Padrões
Para identificar tendências de comportamento é necessário observar atentamente a questão,
reconhecendo padrões e similaridades. Essa competência permite a construção de soluções para
problemas comuns de forma inovadora e empreendedora.
Construção de Algoritmos
Ainda que a palavra algoritmo seja mais utilizada no contexto computacional, esse pensamento
corresponde à criação de passos e soluções para alcançar um objetivo específico para qualquer
problema, de ordem matemática ou não. Desenvolver essa competência nos alunos estimula a
criatividade, a fim de construir soluções cada vez mais eficazes.
Sistemas de Computadores
Muitos são os conceitos e exemplos associados aos sistemas computacionais. Todo processo
que envolve tecnologia computacional e seres humano, ou seja, Máquinas, programas e pessoas
compondo processos complexos e dinâmicos, pode ser considerado um sistema computacional.
Nesta seção voce conhecerá as principais partes que compõem o hardware de um computador
. A figura 2 apresenta estas partes e vias pelas quais as partes se comunicam.
Memórias:
O computador deve ser dotado de alguma forma de armazenamento temporário (RAM
do inglês Random Access Memory ou memoria de acesso aleatório) ou permanente (ROM do
Inglês textitRead Only Memory ou memória somente de leitura), para que os dados coletados ou
processados possam ser armazenados. A essa estrutura damos o nome genérico de memória (não
está contextualizado aqui o tipo da memória).
Unidades de entrada são, portanto, dispositivos físicos que capturam os dados a serem
processados. Os dados podem ser do tipo texto, vídeo ou áudio. Para cada tipo de dado temos um
dispositivo de entrada especifico para sua leitura: teclado, mouse, scanner, etc.
Unidades de saída apresentam os resultados finais do processamento. Para o usuário, os
dispositivos de saída são tão normais que quase não são percebidos: monitores de vídeo, Capítulo
2. Pensamento Computacional 18 impressoras, plotter, telas de terminais bancários, impressoras de
extratos, painéis de senha, quiosques de consultas de preços, etc.
Existem também alguns dispositivos que podem ser classificados com ambas as denominações,
entrada e saída, por exemplo: telas touch screen, etc.
Saiba Mais: você pode encontrar no link abaixo mais informações sobre
os dispositivos de armazenamento, entrada e saída de dados:
https://blog.maxieduca.com.br/tipos-dispositivos-perifericos/
Mídias: se você prefere ver um vídeo, copie e cole o link abaixo no seu
navegador: https://www.youtube.com/watch?v=1BUaQSpGfxct=8s
Um programa de computador pode ser definido como uma série de instruções ou declarações,
em forma inteligível pelo computador, preparada para obter certos resultados. Um programa pode
ser chamado de software, porém esse termo pode ser utilizado também para um grupo de programas
ou para todo o conjunto de programas de um computador.
Software Básico
São software destinados à operação do computador. Têm como função principal controlar os
diversos dispositivos do computador e servir de comunicação intermediária entre o computador e
os outros programas normalmente utilizados, o que permite que esses possam ser executados. Sua
classificação básica pode ser:
Software de Aplicação
São os programas destinados a nos oferecer certos tipos de serviços. Podemos incluir nessa
categoria todos os demais programas utilizados diretamente pelo usuário final do computador. Eles
podem ser classificados ainda como:
• Uso Geral - São programas ou conjunto de programas desenvolvidos para atender diversos
tipos de usuários nas mais diversas atividades: os processadores de texto, as planilhas
eletrônicas, os programas gráficos, os sistemas gerenciadores de banco de dados e outros.
• Uso Específico - São software desenvolvidos sob encomenda para empresas que utilizam
aplicações específicas, como, por exemplo, aplicações de controle financeiro, controle de
produção, controle de clientes, faturamento, etc.
Os software são construídos a partir de outros softwares, por exemplo, utilizamos um editor
de texto para escrever um programa em linguagem de alto nível, depois utilizamos um compilador
para traduzir o programa para a linguagem de máquina (zeros e uns), Capítulo 2. Pensamento
Computacional 20 transformando-o em programa executável. Este último, então, pode ser executado
a partir do sistema operacional do computador.
Tendo em mente que estas máquinas operam com digitos, e especialmente digitos binários,
na próxima seção iremos conhecer as representações por dígitos numéricos mais utilizadas quando
tratamos de sistemas computacionais.
O Homem, através dos tempos, sentiu a necessidade de utilização de sistemas numéricos. Entre
eles, temos os Sistema Decimal, o binário, o octal e o hexadecimal. O sistema decimal é utilizado por
nós no dia-a-dia e é, sem dúvida, o mais importante dos sistemas numéricos. Os outros sistemas, em
especial o binário e o hexadecimal, são muito utilizados nas áreas técnicas digitais e na informática.
Mídias: se você prefere ver um vídeo, copie e cole o link abaixo no seu
navegador: https://www.youtube.com/watch?v=ntylzQWvzCA
Notação posicional
O Homem, através dos tempos, sentiu a necessidade de utilização de sistemas numéricos. Entre
eles, temos os Sistema Decimal, o binário, o octal e o hexadecimal. O sistema decimal é utilizado por
nós no dia-a-dia e é, sem dúvida, o mais importante dos sistemas numéricos. Os outros sistemas, em
especial o binário e o hexadecimal, são muito utilizados nas áreas técnicas digitais e na informática.
Observe então, que o número 1264 escrito na base 8 (octal) tem o valor de 692 em
decimal (base 10). No sistema decimal, um número é expresso através da soma
de potências de base 10 multiplicadas pelo respectivo coeficiente (dígito). Como
características do sistema de numeração decimal temos: Base: 10 Dígitos possíveis:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Já para o sistema de numeração octal (base 8) as potências são
de base 8 e suas características são as que seguem: Base: 8 Dígitos possíveis: 0, 1, 2,
3, 4, 5, 6, 7.
Assim, na base 2 (binária) teremos apenas dois símbolos e as características
são as que seguem: Base: 2 Dígitos possíveis: 0, 1. Para o sistema de numeração
hexadecimal (base 16) será necessário acrecentar mais 06 (seis) digitos diferentes (as
letras maiúsculas de A a F). Assim, temos como características deste sistema: Base:
16 Dígitos possíveis: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. Onde: A vale 10, B vale 11 e
assim por diante, até F com valor 15.
Comece com o primeiro dígito possível como primeiro número, o próximo dígito possível
representa o segundo número e assim por diante até terminar os dígitos possíveis. Como não há mais
dígitos diferentes para usar, o próximo número será o segundo dígito possível seguido do primeiro
dígito possível. veja a tabela a seguir com os 17 (dezessete) primeiros números de cada sistema:
A passagem de uma base X para outra base Y, consiste em decompor o número de acordo com
a estrutura posicional, usando as operações de produto, divisão e soma. Para facilitar o cálculo das
operações de conversão de base, vale pena relebrar as potências das base numéricas utilizadas em
computação:
Como visto, multiplica-se cada digito pelo peso correspondente a sua posição
Há variações nos termos para linguagens diferentes, porém, em geral, podemos ter os seguintes
tipos de dados em linguagens de programação:
Lógico: Um dado lógico armazena 1 bit para representar verdadeiro ou true (1) ou para
representar falso ou false (0). Para Java, usa-se a palavra reservada boolean. Já na Linguagem C
padrão não existe esse tipo primitivo de dado, podendo ser usado o tipo inteiro para isto onde zero
(0) é falso, e qualquer valor diferente de zero (x<>0) é verdadeiro.
Literal: Dados deste tipo incluem um caractere ou um conjunto deles, incluindo letras, símbolos
e números. Vale destacar que não se pode usar dados literais para realização de operações matemáticas. Em
geral os dados literais ocupam 8 bits, independente do hardware, uma vez que são, em sua maioria,
baseados na tabela ASCII (Fig.3). Para declarar uma variável ou uma constante literal em Linguagem C,
pode-se usar a palavra reservada char, que armazenará apenas 1 caractere. Já em Java pode-se utilizar
char para 1 caractere ou String para um conjunto deles;
Inteiro: Um número inteiro é aquele que não possui parte fracionária, podendo representar
quantidades positivas, negativas ou zero. Para declarar uma variável ou constante inteira em Java ou
Linguagem C, é utilizada a palavra reservada int;
A representação de inteiros pode variar quanto ao número de bits que ocupa. E quanto maior
o número de bits utilizado maior o range de valores que a variável pode armazenar:
Variável inteira com 8 bits (1 byte) - pode armazenar um entre 256 (28) números diferentes, no
range de 0 a 256 se for sem sinal (uint8) ou de -128 a 127 se for com sinal (int8).
Podemos ter ainda inteiros com 16, 32 ou 64 bits, e nesse caso a o range de valores que poderá
ser armazenado aumenta conforme a potência de 2 (216, 232 e 264).
Real: Um número real em computação não possui a mesma definição rigorosa da matemática,
já que para ela existem infinitos números entre 0 e 1 (0.1, 0.01, 0.001,
. . . ). Há uma certa limitação de acordo com a capacidade de armazenamento do hardware
do computador, que definirá quais são os limites possíveis para se representar números ditos reais.
Dessa forma, pode representar números com parte fracionária positivos e negativos, além do zero.
Para declarar uma variável ou contante real em linguagem C ou Java, podem ser utilizadas as palavras
reservadas double ou float, cada qual com sua capacidade específica;
Um real float é representado com 32 bits, dos quais um (1) é utilizado para o sinal (+ zero e -
um), 8 bits para o expoente e 23 para a mantissa. Por exemplo:w
Um real de dupla precisão, o tipo double é representado por 64 bits, sendo um para o sinal, 11
bits para o expoente e 52 bits para a mantissa
Quando queremos construir algoritmos que computadores possam entender e exe- cutar, é
necessário que utilizemos uma linguagem de programação que disponha de um compilador que
transforme o algoritmo em um programa a ser executado. O arquivo contendo o algoritmo que
desenvolvemos é chamado de “fonte”, pois é a partir dele que o compilador vai criar o programa a
ser executado.
A partir daqui, iremos trabalhar com duas linguagens de programação, C/C++ e Python.
Os exemplos quando necessários serão apresentados nas duas linguagens.
Portanto, precisamos conhecer os ambientes para editar compilar e executar programas
nestas linguagens.
Os ambientes de desenvolvimento integrados (do inglês Integrated Development
Environment - IDE) são softwares que facilitam o desenvolvimento de programas pois possuem
em um único ambiente editores de textos com recursos específicos para editarmos um programa fonte,
um compilador para determinada linguagem de programação e além disso, outras ferramentas para
possibilitar encontrar determinados erros na criação do programa.
Saiba Mais: Existem vários sites que disponibilizam compiladores online para
diversas linguagens. Entre eles está o OnlineGDB, que pode ser acessado
pelo link: https://www.onlinegdb.com
Este termo já foi utilizado na seção 2.5.1, mas vale uma definição.
Em termos de hardware, as variáveis podem ser armazenadas em memórias que podem ser
regravadas, como por exemplo na memória RAM. Uma variável pode assumir apenas um valor a cada
instante.
Para facilitar o entendimento da programação em médio e alto níveis, não se utiliza o endereço
físico da memória na qual está o valor de uma possível variável em uso. O que se faz é utilizar
nomes associados a tais endereços. A alocação de variáveis não é necessariamente uma tarefa do
programador, sendo executada automaticamente pelo compilador.
Em algumas linguagens, para que as variáveis existam, elas devem ser previamente declaradas. É
neste momento, da declaração de variáveis, que informamos o tipo da variável. É importante observar
que se uma variável foi declarada como sendo do tipo inteiro, ela não poderá armazenar valores reais.
Neste caso, há um erro de semântica, uma vez que uma variável de um tipo só pode armazenar valores
deste mesmo tipo.
A sintaxe em liguagem C a seguir exemplifica a declaração de diferentes tipos de variáveis:
Modelo:
tipo variável;
Exemplos:
int numero_1; /* a variável numero_1 é declarada como tipo inteiro de 32 bits*/;
float salario; // a variável salario é declarada como tipo ponto flutuante de 32 bits;
char letra; // a variável letra é declarada como tipo caracter de 8 bits.
char palavra[n] // palavra será um conjunto de n (natural) caracteres de 8 bits
Para deixar o código mais organizado e economizar tempo de digitação, pode-se declarar
várias variáveis do mesmo tipo da seguinte forma:
Modelo:
tipo nome1, nome2, nome3;
Exemplos:
float salario, caixa, desconto; // as 3 variáveis foram declaradas como float 32 bits.
É importante destacar que algumas regras e recomendações devem ser seguidas para
declaração de variáveis:
• Pode conter 1 ou mais caracteres alfanuméricos, sendo que o primeiro sempre deve ser uma
letra;
• Não utilizar espaços ou caracteres especiais (salvo o famoso “underline” _);
• Não é permitido criar variáveis usando palavras reservadas (ex.: int, float, etc);
• Usar preferencialmente nomes que possuam relação com o objetivo da variável, sendo sucinto,
mas sem exagerar nas abreviações para não dificultar a compreensão;
• Atenção especial para linguagens ditas “case sensitive”, uma vez que diferenciam
letras maiúsculas das minúsculas (ex.: int Valor; é diferente de int valor;);
Agora vejamos como fica a sintaxe, tanto em C quanto em Python, para associar um valor a
uma variável:
Modelo:
variável = Valor;
A função strcpy foi necessária, pois não se pode em C atribuir completamete os valores a este
tipo de variável diretamente. Mas isto veremos nos próximos capítulos.
Conceitos Básicos
Nesta seção iniciaremos os estudos sobre Lógica de Programação. Mas antes, seria útil uma
reflexão sobre o significado da palavra “Lógica”. Assim, o que é Lógica?
Construção de Algoritmos
A lógica de programação é essencial para pessoas que desejam trabalhar com desenvolvimento
de programas para computadores. Lógica de programação pode ser definida como um conjunto de
técnicas para encadear pensamentos a fim de atingir determinado objetivo.
O objetivo fundamental de toda programação é construir algoritmos. Mas, afinal, o que é um
algoritmo?
Em outras palavras, quando criamos um algoritmo, apenas apontamos uma sequên- cia de
atividades que levam à solução de um problema. Até mesmo as soluções para os problemas cotidianos
mais simples podem ser descritas por sequências lógicas de atividades, ou seja, por algoritmos:
Problema: Trocar uma lâmpada.
Sequência de Passos para Solução:
1. Pegue uma escada;
2. Posicione a escada embaixo da lâmpada;
Atenção: Esta solução é apenas uma das muitas soluções possíveis para o
problema apresentado. Assim, ao criarmos um algoritmo, indicamos uma
dentre várias possíveis sequências de passos para solucionar o problema.
Por exemplo, o problema acima poderia ser resolvido mesmo se alterássemos a sequência de
passos para:
1. Pegue uma lâmpada nova;
2. Pegue uma escada;
3. Posicione a escada embaixo da lâmpada;
4. Suba na escada;
5. Retire a lâmpada velha;
6. Coloque a lâmpada nova.
Entretanto, como vimos no capitulo anterior, quando se trata de algoritmos para computadores
precisamos transformar a sequência de passos que escrevemos em linguagem natural para uma
linguagem que possa ser “entendida” pelo computador.
De acordo com o modo como este controle é feito, as estruturas básicas de controle do fluxo
de instruções de um algoritmo, são classificadas em: Estruturas Seqüenciais, Estruturas de Decisão e
Estruturas de Repetição.
Fluxo Sequencial
Exemplo: Exemplo:
int numero; numero = int(input(“Digite um número: “))
scanf(“%d”,&numero);
o typecast no modelo em python é utilizado para transformar o string lido pela função input
para o tipo que se deseja por na variável. No exemplo, o input lê caracteres que são transformados em
um número inteiro (int) para ser armazenado na variável numero.
Exemplo: Exemplo:
float numero = 4/3; numero = 4.3
printf(“o número é: %6.2f”,numero); print(“o número é :{:6.2f }”.format(numero))
Saída Saída
o número é: 1.33 o número é : 1.33
Atividade 6: Faça um programa que leia dois valores reais e calcule a soma
dos numeros e também a sua diferença. O programa deve imprimir as
operações uma ao lado da outra, como no exemplo
17.84 17.84
+ 6.56 − 6.56
______ _______
24.40 11.28
Operadores Aritméticos
As linguagens de programação podem lidar diretamente com algumas operações matemática,
enquanto para outras será necessário o uso de bibliotecas próprias onde foram construídas funções
matemáticas mais complexas. Entre uma linguagem e outra pode haver alguma diferença sobre
quais operações são nativas e quais não são. a figura 8 mostra a Tabela com os operadores
aritméticos que podem ser utilizados diretamene em C/C++ e Python.
Operadores Relacionais
Operadores relacionais são utilizados para comparar valores, o resultado de uma expressão
relacional é um valor booleano (VERDADEIRO ou FALSO). Não é necessário explicar cada um, pois
eles são auto-explicativos. Mas para quem é iniciante em desenvol- vimento de softwares algumas
informações podem ser importantes, principalmente pelo fato de haver diferença nos operadores entre
as linguagens de programação. No caso de C++ e Python não há diferenças, observe na figura 9 a
tabela de operadores relacionais usados nestas linguagens:
A figura 10 apresenta uma tabela com os operadores lógicos utilizados em C/C++ e Python:
Os algoritmos que construímos até agora apresentam uma sequência de passos que devem ser
seguidos para atingir um objetivo bem definido. Note que todos os passos dos algoritmos devem ser
executados a fim de que o objetivo seja alcançado.
Porém, há algoritmos nos quais a execução de alguns passos pode depender de decisões
a serem tomadas. Dessa forma, algum fato indicará se um ou mais passos do algoritmo serão
executados ou não.
Por exemplo, o nosso primeiro algoritmo define uma sequência de passos para
trocar uma lâmpada. Em momento algum perguntamos se a lâmpada está queimada.
Simplesmente trocamos a lâmpada sem fazer qualquer teste. Para resolver esse problema,
podemos acrescentar ao nosso algoritmo um teste que verifique se a lâmpada deve ser
trocada:
1. Ligue o interruptor
2. Se a lâmpada não acender:
2.1. Pegue uma escada;
2.2. Posicione a escada embaixo da lâmpada;
2.3. Pegue uma lâmpada nova;
2.4. Suba na escada;
2.5. Retire a lâmpada velha;
2.6. Coloque a lâmpada nova.
Como vimos anteriormente, muitas vezes precisamos tomar decisões que podem interferir
diretamente no andamento do algoritmo. A representação dessas decisões em nossos programas
é feita através do uso de estruturas de seleção, ou estruturas de decisão. Uma estrutura de seleção
simples pode ser descrita em português da seguinte forma:
SE... ENTÃO... SENÃO ... FIM do SE.
A palavra reservada SE indica o início da estrutura de seleção. Após essa palavra, vem a condição
que definirá o bloco a ser executado. Qualquer expressão lógica poderá ser utilizada como condição,
pois deverá retornar verdadeiro ou falso. Caso a expressão da condição seja verdadeira, o bloco de
instruções ENTÃO será executado. Caso contrário, o bloco SENÃO o será. A palavra reservada FIM do
SE indica o final da estrutura de seleção.
Vale ressaltar que o bloco SENÃO não é obrigatório: caso só queiramos executar algumas
instruções se a expressão lógica for verdadeira, podemos omitir o bloco SENÃO.
A figura 11 mostra um fluxo de execução utilizando uma estrutura de seleção simples:
Exemplo: Exemplo:
if (A > B) { if A > B :
//instruçoes se verdadeiro #instruções se verdadeiro
printf(“A é maior que B”);} print(“A é maior que B”)
else{ else :
//instruções se falso #instruções se falso
printf(“B é maior ou igual a A”); } printf(“B é maior ou igual a A”)
Atividade 11: Faça um programa que leia três valores distintos a serem
digitados pelo usuário, determine e exiba o menor deles. Dica: aqui voce
precisará utilizar estruturas de decisão dentro de estruturas de decisão.
No fluxograma utilizamos uma serie de estrutura de decisão simples aninhadas, uma após a
outra. Podemos fazer o mesmo para as linguagens formais C++ e Python. Em C++ basta usarmos
outro if dentro da cláusula else do if anterior. Porém em python, para encadear vários if’s utilizamos
a cláusula elif , enquanto a cláusula else é usada apenas na última decisão ou na estrutura de seleção
simples. Vejamos como fica a sintaxe para o exemplo do fluxograma:
Sintaxe em C/C++
switch (OP) {
case ’+’:
printf(“%f”, A + B); break;
case ’-’:
printf(“%f”, A - B); break;
case ’x’:
printf(“%f”, A * B); break;
case ’/’:
printf(“%f”, A / B); break;
default:
printf(“OP inválida”); }
Observe que utilizamos a cláusula case é utilizada para identificar o caso em que a expressão
ou a variável se encaixa. A cláusula break evita que, uma vez escolhido um caso, outros casos sejam
testados. A cláusula default é executada caso nenhum dos casos anteriores seja selecionado.
Atividade 13: Faça um programa que leia dois números reais e apresente
um menu para que o usuário escolha uma das seguintes operações aritméticas
(soma, subtração, divisão e multiplicação) . O programa deve apresentar o
resultado da operação.
Note que, apesar de nosso algoritmo sobre a lâmpada estar verificando a necessidade de trocar
a lâmpada antes de fazê-lo, em momento algum verificamos se a lâmpada nova que foi instalada
funciona. Assim, vamos tentar alterar o nosso algoritmo a fim de garantir que ao fim de sua execução
tenhamos uma lâmpada funcionando. Para isso, vamos incluir um novo teste em seu final:
1. Ligue o interruptor
2. Se a lâmpada não acender:
2.1. Pegue uma escada;
2.2. Posicione a escada embaixo da lâmpada;
2.3. Pegue uma lâmpada nova;
2.4. Suba na escada;
2.5. Retire a lâmpada velha;
2.6. Coloque a lâmpada nova;
2.7. Se a lâmpada não acender:
2.7.1. Retire a lâmpada;
2.7.2. Coloque uma outra lâmpada;
2.7.3. Se a lâmpada ainda não acender:
2.7.3.1. Retire a lâmpada;
2.7.3.2. Coloque uma outra lâmpada;
Pelo nosso novo algoritmo, caso a nova lâmpada não acenda, devemos trocá-la novamente e
repetir esse procedimento indefinidamente até que uma lâmpada funcione. Note que não sabemos
quantas vezes teremos de repetir o teste até acharmos uma lâmpada que funcione.
Em casos como esse, devemos utilizar estruturas de repetição. Essas estruturas definem
um fluxo de ações que se repete enquanto uma determinada situação acontece. Dessa forma,
substituímos nossa sequência indefinida de estruturas de decisão por uma estrutura de repetição:
1. Ligue o interruptor;
2. Se a lâmpada não acender:
2.1. Pegue uma escada;
2.2. Posicione a escada embaixo da lâmpada;
2.3. Pegue uma lâmpada nova;
2.4. Suba na escada;
2.5. Retire a lâmpada velha;
Estruturas de Repetição
O segundo tipo de laço utiliza as palavras chaves do e while. Este tipo de laço não existe em
Python, entretanto, observe que no exemplo em Python do laço anterio é possivel utilizar a cláusula
else para especificar comandos para serem executados quando a condição não for satisfeita. Isto pode
ser usado para simular o tipo de laço da direita na figura 13. A sintaxe em C++ para o laço da direita
é apresentado a seguir:
Sintaxe em C/C++
do
{
bloco de comandos a repetir;
}
while (condição);
Exemplo
int cont = 0;
do {
printf(“%d”, cont);
valor++; }
} while (cont <=10);
Figura 14 – Exemplo de fluxo de execução com estrutura de repetição com contagem conhecida.
Por exemplo, se o número de alunos da turma for conhecido, a estrutura de repetição recomendada,
tanto em C++ quanto em Python, é o laço for. Vejamos como fica a sintaxe desta estrutura:
Sintaxe em C/C++
for (cont = valor inicial; cont <= valor final; cont = cont + passo) {
bloco de comandos que irão se repetir;}
Exemplo
for (cont = 1; cont <= 10; cont = cont +1) {
printf(“%d”, contador; }
/* serão impressos os valores de 1 a 10 */
Exemplo
for contador in range(1,11,1) :
print(contador) # serão impressos os valores de 1 a 10.
else :
print(’comandos após o laço’)
Existem outras maneiras de construir um laço for em python. Além disso, sempre que
necessário, voce poderá construir um laço dentro de outro laço. Quando o conteúdo sobre listas for
apresentado, você aprenderá a construir algumas destas estruturas.
Os laços vistos nas linguagens C++ e Python possuem dois comandos de desvios: break e
continue. Estes comandos funcionam com todos os comandos de repetição. O comando break
encerra o laço no ponto em que for executado. Já o comando continue desvia o fluxo para o início
do laço.
Nestes exemplos de utilização do comando break, caso o usuário digite um número negativo o
laço termina antes do contador chegar a 10.
Atividade 16: Faça um programa que leia a matrícula e a nota final dos 20
alunos de uma turma. O programa deve imprimir a matricula e a condição de
cada aluno (Aprovado ou Reprovado). Alunos com nota abaixo de 60 será
reprovado.
Funções
Construindo Funções
Para utilizarmos uma função, ela precisa ser previamente construída, além disso, uma função
pode ou não retornar valores para o ponto do programa onde foi chamada. Por exemplo, as funções
scanf e input retornam valores, enquanto as funções printf e print, apesar de imprimirem na tela ou
Exemplo 1: Exemplo 1:
float media(float n1, float n2, float n3) { def media(n1, n2, n3):
return (n1 + n2 + n3)/3; } return (n1 + n2 + n3)/3
Exemplo 2: Exemplo 2:
void media(float n1, float n2, float n3) { def media(n1, n2, n3):
printf(“%5.2f”, (n1 + n2 + n3)/3); } print((n1 + n2 + n3)/3)
Passagem de Parâmetros
Normalmente os parâmetros ou argumentos passados para uma função são valores que poderão
ou não ser atribuidos a variáveis internas da função (variáveis locais). Entre- tanto, há situações em que
é necessário passar os argumentos por referência. Por exemplo, na função scanf em C++, os argumentos
que se seguem ao primeiro, são sempre passados por referência, isto é, na verdade o que a função
recebe não é o valor, e sim o endereço da variável. Além disso, há certos tipos de dados que só
conseguimos passar por referência, como por exemplo, uma cadeia de caracteres (string).
Em C++, qualquer tipo de dado pode ser passado por referência. Porém, para o Python,
Sintaxe em C+
chamando a função:
int cont, soma = 0;
for (cont=1; cont<=3; cont++ {
acumula(cont, &soma); }
Observe que a variável cont é passada para a função como valor, ou seja, o valor dela é que
será enviado para a função acumula. Já a variável soma é passada por referência, ou seja, o endereço
dela é que será enviado para a função acumula (devido ao uso do “*” na construção da função e
do “&” na passagem do parâmetro). Assim, quando o laço for terminar, a variável soma terá o valor
6 (seis), pois quando a passagem ocorre por referência, qualquer alteração da variável dentro da
função implica em alteração fora da função, pois o endereço de memória correspondente aos dois
nomes de variável, soma e *acumulador, é o mesmo.
Módulos em Python
Um módulo é simplesmente um arquivo contendo códigos Python que podem ser explorados
por outros programas. Um módulo completo pode ser chamado por outros programas através da
declaração import (importar).
Como exemplo, o código do programa salvo como o nome area.py contém as funções
retangulo, triangulo e circulo construídas para calcular as áreas destas figuras geométricas. Este
código é mostrado a seguir:
Uma vez salvo, o programa estará pronto para servir como um módulo. Se quisermos usar suas
funções dentro de outro programa ou mesmo no interpretador Python devemos usar a declaração
import para importar area.py como um módulo. Agora para usar o módulo primeiro é preciso digitar
o nome do módulo, colocar um ponto e digitar o nome da função que queremos usar e por fim
passar os argumentos necessários à função. Veja o exemplo abaixo:
Módulos podem ser muito grandes e sua importação completa pode gerar desperdício de memoria
se só vamos fazer uso de uma pequena parte do módulo. Assim é possível importar somente partes de
um módulo. No caso do módulo area.py podemos importar, por exemplo, somente a função circulo.
Veja a seguir:
Sintaxe em Python:
from nome_do_módulo import nome_da_função as apelido
Exemplo:
”””Programa para calcular o volume de um cilindro””’
from area import circulo as area_circulo
r = float(input(’Entre com o raio do cilindro: ’))
h = float(input(’Entre com a altura do cilindro: ’))
volume = area_circulo(r) * h
print(’O volume do cilindro é:’, volume)
Para criarmos o arquivo .cpp. Crie um novo arquivo, troca.cpp, com as definições das funções
que declaramos em troca.h (perceba que os dois arquivos devem ter o mesmo nome, só muda a
extensão).
As primeiras regras para a criação do arquivo C++ são:
Regra 1. deve conter apenas as definições, que não serão visíveis ao programa.
Regra 2. deve conter apenas as diretivas #include necessárias para suas definições.
Neste exemplo, basta copiar a parte das definições, exatamente como está no original.
Dessa vez não é preciso se preocupar com guarda de cabeçalho. As definições em C++ funcionam
de maneira diferente dos arquivos de cabeçalho.
Regra 3. Nunca declare um inline dentro de um arquivo .cpp, toda função inline deve ter
sua definição conhecida antes de ser usada e apenas o arquivo de cabeçalho é conhecido até este
momento.
Uma vez criados os arquivos (troca.h e troca.cpp), para podermos utilizar as funções troca em
qualquer outro program C++, teremos que criar uma biblioteca. Existem dois tipos de bibliotecas:
bibliotecas estáticas (static library) e dinâmicas (dynamic library) . Bibliotecas estáticas são vinculadas
ao programa resultante, de modo que cada programa que usa essa biblioteca obterá sua própria
cópia do código da biblioteca.
Uma maneira mais eficiente economizar memória é usar bibliotecas compartilhadas (em janelas
chamadas DLL), que são carregadas sob demanda de um local específico para cada plataforma, mas
a vantagem é que apenas uma instância do código da biblioteca precisa ser carregada para memória
quando diferentes programas que usam a biblioteca estão sendo executados simultaneamente e o
código binário resultante desses programas não contém o código da biblioteca. ele reside em um
arquivo separado que precisa ser enviado junto com o aplicativo e instalado em um local apropriado.
Estruturas Homogêneas
Na atividade anterior, você construiu um programa que calculava a média das notas dos alunos
de uma turma. Nesse programa sempre líamos a nota de cada aluno utilizando a mesma variável para
armazenar o valor. Ou seja, a cada rodada do laço, a variável assumia uma das notas do aluno e essa
nota era acumulada numa variável soma, para ao final calcular a média.
Assim, se no final do programa quiséssemos exibir as notas de todos os alunos, não seria
possível, pois sempre substituíamos uma nota de um aluno pela próxima nota. Para que fosse possível
armazenar as notas de todos os alunos, teríamos duas alternativas: a primeira, menos inteligente,
seria declarar uma variável para armazenar cada nota de cada aluno; e a segunda seria declarar uma
estrutura de dados com um único nome que fosse capaz de armazenar todas as notas dos alunos.
Diferentes linguagens de programação possuem diferentes tipos de dados capazes de realizar esta
função. Neste capítulo veremos como o C++ e o Python trabalham com estes tipos de estruturas.
Array
Um array (vetor) é uma estrutura de dados utilizada para representar certa quan- tidade de
variáveis de valores homogêneos, ou seja: um conjunto de variáveis, todas do mesmo tipo. Podemos
dizer que um array é uma sequência de dados de mesmo tipo ocupando posições consecutivas de
memória, e por isso, existe uma ordem natural entre os elementos de um array (o primeiro elemento,
o segundo, e assim por diante). A grande vantagem de usar array é poder trabalhar com um grande
número de variáveis utilizando um único nome (para a variável). Para isso existe uma sintaxe especial
para pegar elemen- tos do vetor em posições específicas (como o primeiro elemento ou o décimo
elemento). O valor de uma posição específica é definido como índice do array.
A linguagem Python encapsula bastante o conceito de array, agregando funcionali- dades e por
isso geralmente o material didático sobre arrays em Python utiliza o nome lista. Por isso veremos
separadamente as estruturas da linguagem C++ e da linguagem Python.
A sintaxe em C++ para declarar e armazenar valores em um array e feita da seguinte forma:
Sintaxe em C++:
tipo variável[tamanho];
variável[índice] = valor;
Exemplos:
int numeros[10]; // a variável numeros possui 10 elementos do tipo inteiro
char letras[20]; // a variável letra possui 20 caracteres;
numeros[4] = 339; // a posição de índice 4 de numeros recebeu o valor 339
letras[7] = ’A’; // a posição de índice 7 de letras recebeu o caracter A
Sintaxe em C++:
int lin, col;
float notas[3][9];
for (col=0; col<9; col++)
{
for (lin=0; lin<3; lin++)
{
scanf(“%f”, ¬as[lin][col]);
}
}
Listas e Tuplas em Python também são tipos de sequências de dados e possuem muitas
propriedades comum entre elas e com o tipo array, mas a diferença básica é que a lista é mutável, assim
como o array, enquanto a tupla é imutável.
Na prática, isso implica em que não é possível fazer atribuições à um objeto imutável. Nos exemplos
a seguir veremos como podemos criar listas e tuplas e também como é possível alterar os valores de
uma lista:
Embora a tupla seja um tipo imutável, se possuir um valor de um tipo mutável, o mesmo
permanece mutável enquanto dentro da tupla. Por exemplo, se considerarmos uma tupla de listas:
# criando tupla com 2 listas
tupla = ([1, 3], [4, 8]) # note que tuplas usam parênteses e listas usam colchetes tupla[0]
[1] = 5 # resulta em tuplas = ([1, 5], [4, 8])
Existem algumas diferenças entre um array em C++ e uma lista em Python. Um array em C++
é apenas uma sequência de variáveis alocadas de forma contígua em memória, enquanto a lista em
Atenção: se uma lista for criada com elementos do mesmo tipo, está não
acei- tará atribuições de valores de tipos diferentes aos seus elementos já
existentes. Entretanto, é possível acrescentar novos elementos de outros
tipos, e neste caso a lista deixa de ser de elementos do mesmo tipo e passa
a permitir alteração de tipos em todos os outros elementos. Assim, este
tipo de lista deixará de ser um estrutura de dados homogênea.
os elementos de uma estrutura de dados homogênea, arrays, listas e tuplas são atribuídos
a um único nome de variável, para acessar os elementos individualmente, simplesmente utilize o
nome da variável seguido de um índice entre colchetes [ ].
É possível percorrer um array ou uma lista elemento por elemento utilizando as estruturas de
repetição. A linguagem Python possui varias maneiras de percorrer listas com for. Duas das principais
maneiras consistem em:
- trazer os elementos da lista através de seus índices usando a função range(). - buscar
diretamente os elementos através do operador in.
A seguir serão apresentadas diversas formas de percorre uma lista em Python. Este exemplos
também podem usados para percorrer tuplas.
Figura 24 – Exemplo usando laço for e função range em Python para percorrer uma lista.
Figura 25 – Exemplo em Python para percorrer uma lista com referencia direta.
No caso do laço for em C++, basta utilzar o contador como índice do array, assim, a cada iteração
será possível acessar posições do array com base no valor do contador. Como o valor do contador será
incrementado ou decrementado, alterando o índice em que será manipulando, logo, todos os elementos
da estrutura de poderão ser manipulados.
Ainda é possível percorrer e acessar listas e tuplas utilizando a função zip(). Esta função retorna
uma lista de tuplas, onde a i-ésima tupla contém o i-ésimo elemento de cada um dos argumentos.
Nesta seção estão descritos alguns dos principais métodos (funções específicas que agem sobre
determinado tipo de dado) que podem ser utilizados com as listas.
A tabela 1 mostra um resumo dos métodos de listas mais comuns. Faça testes com esses
métodos para ganhar uma melhor compreensão do que eles fazem.
Todos os tipos de dados compostos que estudamos em detalhes até agora — strings, arrays,
listas e tuplas — são coleções sequenciais. Isto significa que os itens na coleção estão ordenados e
identificados por números inteiros usados como índices para acessar os valores que eles contêm.
As estruturas de dados heterogêneas são aquelas que permitem o agrupamento dados de
tipos diferentes com atribuição a um único nome de variável. Embora uma lista em Python também
possa ser uma estrutura heterogênea, as estruturas que usaremos agora não são identificadas por
índices, mas por nomes de campos ou elementos de dados. Cada linguagem de programação têm
sintaxes diferentes para estes tipos de estruturas. Primeiro veremos como estes tipos de dados
podem ser criados em C++, e posteriormente em Python.
struct em C++
Uma struct caracteriza uma variável especial que contém diversas outras variáveis, normalmente de
tipos diferentes. As variáveis internas contidas na struct são denominadas membros da struct. Podemos
dizer que as structs da linguagem C são o equivalente a um ficha ou um registro, onde podemos
armazenar diversa informações de tipos diferentes sobre algo ou alguém. O nome registro é muito
comum em outras linguagens de programação como Pascal, Fortran e Natural.
A ideia de usar uma struct é permitir que, ao armazenar os dados de uma mesma entidade, isto
possa ser feito com uma única variável. Por exemplo, se for preciso armazenar a altura, o peso e a idade
de uma pessoa, pode-se criar uma struct chamada tp_pessoa e agrupar os dados em um único
tipo de dado. Em seguida poderemos criar uma variável pessoa do tipo struct tp_pessoa, onde
poderemos armazenar os dados de uma pessoa específica. Note que agora tp_pessoa tornou-se
uma palavra reservada que representa um tipo de variável, deste modo poderemos também criar structs
contendo structs criadas anteriormente.
Sintaxe: Exemplo:
struct <identificador> struct tp_pessoa
{ {
<listagem dos tipos e membros>; char nome[50];
}; int idade;
//após declarar o tipo da estrutura, é preciso float altura, peso;
//criar a variável deste tipo. };
struct <identificador> <variavel>; struct tp_pessoa pessoa;
Para atribuir valor a um dado da struct “tp_pessoa”, basta por um ponto após o nome que você
escolheu para a variável. Após isso, podemos acessar normalmente qualquer dado da variável.
Em python a palavra chave struct possui um função diferente da usada em C++, portanto
para dados heterogêneos em Python usaremos outros conceitos. Tanto em C++ quanto em Python,
podemos utilizar orientação a objetos para construir classes de objetos e armazenar coleções de
dados heterogêneos, mas deixaremos orientação a objetos para outra ocasião.
Python também inclui um tipo de dados para conjuntos de dados heterogêneos, chamado
set. Um conjunto é uma coleção desordenada de elementos, sem elementos repetidos. Usos comuns
para conjuntos incluem a verificação eficiente da existência de objetos e a eliminação de itens
duplicados. Conjuntos também suportam operações matemáticas como união, interseção, diferença
e diferença simétrica.
Chaves ou a função set() podem ser usados para criar conjuntos. Note: para criar um conjunto
vazio você precisa usar set(), nunca {}; este último cria um dicionário vazio, uma estrutura de dados
que discutiremos na próxima seção.
Exemplos:
> > heterogeneos = {’nomes’, 2, 3.5, ’outros’, ’2’, 3.5, “nomes”}
> > print(heterogeneos) # mostrando que duplicatas são removidas
{’outros’, 2, 3.5, ’nomes’, ’2’}
> > ’nomes’ in heterogeneos # teste rápido de existência no conjunto
True
Dicionário de Dados
Outra estrutura de dados muito útil embutida em Python é o dicionário. Dicionários são também
chamados de “memória associativa” ou “vetor associativo” em outras lingua- gens. Diferente de sequências
que são indexadas por inteiros, dicionários são indexados por chaves (keys), que podem ser de qualquer
tipo imutável (como strings e inteiros). Tuplas também podem ser chaves se contiverem apenas
strings, inteiros ou outras tuplas. Se a tupla contiver, direta ou indiretamente, qualquer valor mutável,
não poderá ser chave. Listas não podem ser usadas como chaves porque podem ser modificadas
internamente pela atribuição em índices ou fatias, e por métodos como append() e extend().
Um bom modelo mental é imaginar um dicionário como um conjunto não-ordenado de pares
chave:valor, onde as chaves são únicas em uma dada instância do dicionário. Dicionários são delimitados
Exemplos:
> > > pessoa = {’nome’: ’Jô’, ’idade’: 18, ’altura’: 1.68, ’peso’: 67}
> > > pessoa[’nome’] > > > pessoa[’altura’]
’Jô’ 1.68
> > > pessoa[’idade’] > > > pessoa[’peso’]
18 67
Agora vamos utilizar o construtor dict() para produzir dicionários diretamente de sequências
de pares chave-valor.
A maioria dos programas que construimos até agora são transitórios, porque são executados
por algum tempo e produzem alguma saída, mas, quando terminam, seus dados desaparecem.
Se executar o programa novamente, ele começa novamente do zero. Outros programas são
persistentes: rodam por muito tempo (ou todo o tempo); mantêm pelo menos alguns dos seus dados
em armazenamento permanente (uma unidade de disco rígido, por exemplo); e quando são finalizados
e reiniciados, continuam de onde pararam.
Uma das formas mais simples para programas manterem seus dados é lendo e escrevendo
arquivos de texto ou arquivos binários. Uma alternativa muito usual é ar- mazenar o estado do
programa em um banco de dados, pois permite uma organização e interrelacionamento dos dados
mais eficiente. Entretanto, neste curso iremos abordar apenas a persistência em arquivos.
Persistência em Arquivos
Arquivos são recursos que o sistema operacional promove e que as linguagens de programação
tem acesso. É uma abstração que simplifica a criação e manipulação de dispositivos de entrada e saída
de dados, não apenas restringindo a arquivos físicos gravados no disco rígido, mas também dispositivos
como o teclado e o monitor.
Quando criamos um arquivo, seja através de uma linguagem de programação ou através da
interface de usuário, na verdade não estamos propriamente criando o arquivo, mas sim delegando
esta tarefa ao Sistema Operacional (Linux, Windows, Mac), que se encarrega de fazer toda a verificação
de permissões do usuário que está executando esta tarefa e atribuindo às descrições do arquivo
informações como: usuário dono, data de criação, tipo, tamanho, data de acesso, modificação,
dentre outras.
Os arquivos são divididos em duas subcategorias:
Texto - São arquivos que contém informações no formato de caracteres, ou seja, se for aberto
em um editor de texto será completamente legível. Eles podem conter caracteres de controle com “fim
de linha”e outros;
Binário - Arquivo cujas informações são consideradas sequências específicas de 0’s e 1’s, que são
interpretadas apenas por programas que conhecem sua estrutura. Programas compilados, bibliotecas
e arquivos de dados binários são exemplos deste tipo de arquivo. Estes arquivos se abertos em um
editor de texto não terão informações legíveis. Portanto mantêm as informações mais seguras.
Para trabalharmos com arquivos são necessários alguns passos:
1) Abrir ou criar o arquivo, associando o nome físico do arquivo ao seu nome lógico.
2) Manipular os dados do arquivo: consulta, inclusão, exclusão, alteração.
3) Fechar o arquivo.
Sintaxe em C++
FILE* nome_do_arquivo;
As funções open() para Python e fopen() para C++ devolvem um objeto arquivo, e são
frequentemente usadas com dois argumentos: o nome do arquivo e modo de operação a qual será
submetido. Em C++, além de fopen() ainda podemos usar a função fopen_s() e wopen_s(), a principal
diferença é que estas duas últimas, em lugar de retornar uma referência para o arquivo, retornam
um número de erro, identificando se ouve falha na abertura do arquivo ou nos parâmetros passados
na função.
A seguir serão apresentadas algumas funções para manipulação de arquivos tanto em C++
quanto em Python. Para C++, o fprintf() e o fscanf(), funcionam basicamento como printf() e o
scanf(). Para Python temos write() e read(). Vejamos as sintaxes:
Sintaxe em C++
exemplo 1: exemplo 2:
FILE* arquivo; FILE* arquivo;
char* frase; errno_t erro;
// abrindo arquivo para escrita erro = fopen_s(arquivo, “teste.txt”, “w”);
arquivo = fopen(“teste.txt”, “w”); fprintf(arquivo, “Hello World !!!”);
fprintf(arquivo, “Hello World !!!”); fclose(arquivo);
fclose(arquivo);
// abrindo arquivo para leitura
arquivo = fopen(“teste.txt”, “r”);
fscanf(arquivo, “
fclose(arquivo);
exemplo 1: exemplo 2:
# abrindo arquivo para escrita # adicionando a arquivo existente
arquivo = open(’teste.txt’, ’w’) with open(’teste.txt’, ’a’) as arquivo:
arquivo.write(’Hello World !!!’) arquivo.write(’Hello World !!!’)
arquivo.close() # usando o comando textitwith
# abrindo arquivo para leitura #o arquivo é fechado automáticamente
arquivo = open(’teste.txt’, ’r’) with open(’teste.txt’) as arquivo:
frase = arquivo.read() frase = arquivo.read()
arquivo.close()
Observe que um dos argumentos foi ’w’ ou ’r’, eles indicam o modo para o qual o arquivo será
aberto ou criado. A tabela 28 apresenta os modos de abertura dos arquivos, tanto para Python quanto
para C++:
Até aqui vimos como ler e escrever texto em arquivos, ou seja, as funções utilizadas até agora
entendem o conteúdo de um arquivo como uma sequência de caracteres (bytes). Para ler e escrever
tipos de dados maiores que um byte, utilizaremos as funções fread() e fwrite() em C/C++ e dump() e
load() em Python (para estas últimas é necessário instalar o módulo pickle). Essas funções permitem
a leitura e escrita em arquivos de blocos de qualquer tipo de dado. Além disso, escrevendo em arquivos
com estas funções o programador consegue manter os dados ilegíveis quando vistos por um editor
de texto.
Atividade 11: Repita a atividade 10, porém considerando que arquivo foi
salvo como texto.
89 ••••