Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas

Apostila C++, Notas de estudo de Informática

Apostila C++

Tipologia: Notas de estudo

Antes de 2010
Em oferta
30 Pontos
Discount

Oferta por tempo limitado


Compartilhado em 13/11/2009

aron-gustavo-lima-e-santos-3
aron-gustavo-lima-e-santos-3 🇧🇷

3 documentos

1 / 102

Documentos relacionados


Pré-visualização parcial do texto

Baixe Apostila C++ e outras Notas de estudo em PDF para Informática, somente na Docsity! Bacharelado em Sistemas de Informação Algoritmos Prof. Ms. Antonio Marcos SELMINI Apostila de Algoritmos / Linguagem C 2008 Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 2 Prefácio Este material é o resultado das notas de aulas das disciplinas Algoritmos e Estruturas de Dados. O principal objetivo deste material é auxiliar os alunos na disciplina de Algoritmos ministrada na Faculdade de Informática e Administração Paulista (FIAP). Vale destacar também que este material não substitui em hipótese alguma os livros indicados como bibliografia básica, pois deverão ser consultados para uma melhor formação profissional. Prof. Ms. Antonio Marcos Selmini Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 5 Capítulo 9 - Introdução aos Ponteiros..................................................................... 73 9.1 Definição............................................................................................................ 73 9.2 Declaração de ponteiros..................................................................................... 73 9.3 Operadores de ponteiros (& e *)........................................................................ 74 9.4 Cuidados com ponteiros..................................................................................... 75 9.5 Exercícios em Classe ......................................................................................... 76 Capítulo 10 - Funções................................................................................................ 77 10.1 Introdução ........................................................................................................ 77 10.2 Protótipos de funções....................................................................................... 78 10.3 Passagem de Parâmetros.................................................................................. 80 10.4 Passagem de arrays para funções..................................................................... 81 10.5 Escopo de variáveis ......................................................................................... 82 10.6 Exercícios em Classe ....................................................................................... 82 Capítulo 11 - Estruturas ........................................................................................... 87 11.1 Definição e declaração de estruturas em C...................................................... 87 11.2 Matrizes de estruturas ...................................................................................... 89 11.3 Passando elementos de estruturas como parâmetros para funções.................. 89 11.4 Passando estruturas inteiras para funções........................................................ 90 11.5 Ponteiros para estruturas.................................................................................. 91 11.6 Comando typedef ............................................................................................. 91 11.7 Exercícios em Classe ....................................................................................... 92 11.8 Exercícios Complementares ............................................................................ 93 Capítulo 12 - Manipulação de arquivos em C ........................................................ 95 12.1 Introdução ........................................................................................................ 95 12.2 Streams............................................................................................................. 95 12.3 Abrindo um arquivo......................................................................................... 96 12.4 Fechando um arquivo....................................................................................... 97 12.5 Escrevendo e lendo caracteres em um arquivo................................................ 97 12.6 Escrevendo e lendo strings em um arquivo ..................................................... 98 12.7 Funções fread() e fwrite() ................................................................................ 99 12.8 Exercícios....................................................................................................... 100 Bibliografia............................................................................................................... 101 Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 6 Capítulo 1 Introdução à Microinformática 1.1 Introdução A cada dia presenciamos em jornais, revistas, na televisão o surgimento de novas invenções. Mas de todos esses inventos, talvez o maior e mais sensacional tenha sido o computador. O ano inicial da construção do primeiro computador é 1946, mas sabe-se que suas bases foram estabelecidas ao longo de dois séculos. O computador que conhecemos hoje, com suas funcionalidades é muito recente tendo quase 60 anos. Desses quase 60 anos sua divulgação e aquisição por parte da população tem pouco mais de 20 anos. O ENIAC (primeiro computador) foi construído nos Estados Unidos e tinha o tamanho aproximado de um caminhão. Funcionava por poucas horas. Era construído com muitas válvulas e consumia energia suficiente para abastecer centenas de casas. Era um computador muito complicado de operá-lo e só os seus projetistas o conseguiam fazer. Os principais fatores responsáveis pela divulgação e aquisição dos computadores são:  Redução da dimensão física;  Aumento da confiabilidade;  Aumento da capacidade de processamento;  Redução de custo para aquisição e manutenção;  Ampliação da gama de utilidades e aplicações; Uma pergunta que surge com freqüência em programas de televisão (programas educativos de perguntas e respostas) ou até mesmo entre os alunos é quem inventou o computador. Essa é uma pergunta difícil de responder porque não existe apenas um criador. O computador foi resultado de uma série de equipamentos e ou máquinas que foram sendo desenvolvidos por diversos personagens marcantes da história. 1.2 Precursores do Computador Como mencionado na seção anterior dizer o inventor do computador é algo praticamente impossível. Diferente de outras invenções, o computador não “nasceu da noite para o dia”, mas foi o resultado do aperfeiçoamento de várias máquinas que foram surgindo em diferentes épocas. O surgimento dessa poderosa máquina é apenas um reflexo da evolução do homem e também uma conquista pela busca por processos de automatização e substituição do trabalho humano. Um dos primeiros dispositivos de calcular que se tem conhecimento é o ábaco. O ábaco do grego significa “tábua de calcular”. É considerado um dos primeiros precursores das máquinas de somar sendo um dispositivo auxiliar para o usuário que faz cálculos mentais. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 7 Um personagem muito importante para o desenvolvimento dos computadores atuais é Blaise Pascal. Esse matemático francês foi responsável pela criação de uma máquina de somar, a partir da qual foram criados diversos modelos. A máquina criada por Pascal foi chamada de Pascalina e na época foi considerada a perfeição em máquinas de calcular. Vale destacar que antes da Pascalina outros cientistas criaram outras máquinas mas que não tiveram desempenho tão bom quanto a Pascalina. Outro matemático de grande importância foi Charles Babbage. Dentre as várias invenções de Babbage destaca-se a Máquina Analítica. A Máquina Analítica tinha alguns princípios básicos muito interessantes tais como:  Dispositivos de entrada;  Facilidade de armazenar números para processamento;  Processador, que na época era chamado de calculador numérico;  Unidade organizacional que tinha como função organizar as tarefas a serem executadas;  Dispositivo de saída com cartões perfurados; É uma pena que a tecnologia disponível no tempo de Babbage não permitiu, pois teria sido um computador programável como conhecemos nos dias atuais. Dentre esses dois grandes personagens citados há também uma figura feminina de destaque. Seu nome era Ada Augusta King, filha do poeta inglês Lord Byron. Ada foi amiga de Babbage. Sugeriu que a Máquina Analítica utilizasse o sistema binário e também escreveu pequenos programas para ela. Ada é considerada a primeira programadora de computadores do mundo. Os desenvolvimentos não paravam e em toda parte do mundo cientistas desenvolviam suas engenhosas criações. Em 1930, a IBM lança uma máquina eletromecânica batizada de Harvard Mark I. O Mark I processava número com precisão de 23 dígitos e executava todas as quatro operações aritméticas, além de cálculos de logaritmos e funções trigonométricas. O Mark I também tinha programas embutidos. Era uma máquina lenta, mas era completamente automático. Após o desenvolvimento do Mark I, o outro grande desenvolvimento americano foi o ENIAC (Electrical Numerical Integrator and Calculator). Era construído a base de válvulas e ocupava um espaço de 167 metros quadrados. Era um computador de alta velocidade e programável que usava a base de numeração decimal (base 10). Foi utilizado de 1946 a 1955. 1.3 Gerações dos Computadores A evolução do computador segundo as tecnologias empregadas são divididas em gerações. Cada geração é caracterizada por um marco tecnológico. Basicamente os marcos tecnológicos utilizados para classificar a evolução dos computadores são três:  Válvulas eletrônicas;  Transistores;  Circuitos Integrados; 1ª Geração (1946 – 1958)  Caracterizada pelo uso de válvulas na composição dos computadores;  Entradas e saídas baseadas em fitas perfuradas; Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 10 Dessa forma, a lógica de programação é a técnica de encadear pensamentos para atingir um determinado objetivo. Esse encadeamento representa uma seqüência lógica de passos a serem “seguidos” pelo computador. É através da lógica de programação que definimos a seqüência lógica de passos. Uma seqüência lógica são passos executados até atingir um objetivo ou solução de um problema. Em programação de computadores, o termo “instruções” normalmente é utilizado no lugar de “passos”. Em ciência da computação, a instrução representa a “ordem” para que o computador execute uma determinada ação. A solução de um problema é obtida a partir de um conjunto de instruções e não apenas de uma instrução isolada. 2.3 Algoritmos O termo algoritmos é o termo central na ciência da computação e em programação de computadores. Formalmente um algoritmo é uma seqüência lógica e finita de instruções escritas em uma linguagem de programação para se atingir a solução de um problema. No dia-a-dia fazemos centenas de algoritmos. Por exemplo: tomar banho, tomar o café da manhã, trocar uma lâmpada, fazer uma ligação telefônica, uma receita de bolo, etc. Um algoritmo apenas especifica os passos lógicos que devem ser seguidos pelo computador para se atingir a solução de um problema. O algoritmo não é a solução do problema porque se assim fosse, para cada problema existiria apenas um algoritmo. Exemplo 1: Algoritmo para calcular a média de três valores inteiros: Inicio Fornecer o primeiro valor inteiro; Fornecer o segundo valor inteiro; Fornecer o terceiro valor inteiro; Somar os três valores; Pegar o resultado da soma e dividir por 3; Mostrar o resultado obtido; Fim Como pode ser observado no exemplo acima um algoritmo deve ser simples e mostrar de forma coerente como deve ser obtida a solução do problema. Algumas instruções não pode ser alteradas como, por exemplo, não podemos dividir o valor antes de somar e também não podemos somar os valores se os mesmos não forem fornecidos para o programa. Caso essa inversão ocorra é o que chamamos de erro de lógica. É como se fossemos beber um refrigerante em lata sem abrir a lata! Como mostrado na figura 2.1, um programa é dividido em três partes básicas: entrada, processamento e saída. Se tivermos essa idéia em mente ao construir um algoritmo, a sua construção poderá ficar mais simples. Para o exemplo 1 temos:  Quais são os dados de entrada? o Três números inteiros.  Quais são os dados de saída? Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 11 o A média dos três valores inteiros.  Qual é o processamento a ser realizado nos dados de entrada? o Somar os três valores inteiros e dividir o resultado por três. Ao analisarmos o exemplo 1 novamente podemos identificar as três partes: Inicio Fornecer o primeiro valor inteiro; Fornecer o segundo valor inteiro; Fornecer o terceiro valor inteiro; Somar os três valores; Pegar o resultado da soma e dividir por 3; Mostrar o resultado obtido; Fim 2.4 Representação de Algoritmos Como vimos na seção anterior, um algoritmo nada mais é que um conjunto de instruções escritos em uma determinada linguagem. Essa linguagem é uma forma de representação do algoritmo. A representação pode ser através de:  Linguagem de programação: representa uma forma de escrever os algoritmos para que um computador possa entender e executar as instruções. Posteriormente estudaremos com mais detalhe os conceitos de linguagem de programação. Exemplo: #include <stdio.h> void main() { int p1, p2, p3; float m; clrscr(); printf(“Informe o primeiro valor: “); scanf(“%d”, &p1); printf(“Informe o segundo valor: “); scanf(“%d”, &p2); printf(“Informe o terceiro valor: “); scanf(“%d”, &p3); m = (p1+p2+p3)/3; printf(“O resultado é %f”, m); getch(); } entrada processamento saída Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 12 O programa acima foi codificado em linguagem C e representa o código para o algoritmo do exemplo 1. Usando uma linguagem de programação, devemos estar atentos as suas regras, limitações e convenções utilizadas, o que para um iniciante pode ser algo extremamente difícil e trabalhoso.  Graficamente: A representação de algoritmos através de gráficos é extremamente simples e fácil de compreender, mas existe um inconveniente. A medida que os problemas a serem resolvidos tornam-se grandes, os gráficos também tornam-se grandes e trabalhosos de manipular. Outro inconveniente são as representações que devem ser memorizadas. Basicamente existem duas representações gráficas: Diagramas de Nassin-Shneiderman- Chapin e Fluxogramas. o Diagramas de Nassin-Shneiderman-Chapin: Informar o primeiro valor – p1 Informar o segundo valor – p2 Informar o terceiro valor – p3 Calcular média – M = 3 321 ppp ++ Exibir M A representação através dos Diagramas de Nassin-Shneiderman-Chapin foi muito utilizada por vários anos principalmente no inicio da programação de computadores. Como pode-se analisar na figura acima, é fácil entender a idéia do algoritmo e principalmente acompanhar as instruções de sua execução. Esse diagrama não utiliza grande variedade de símbolos, portanto a sua memorização é mais fácil. o Fluxograma: O fluxograma utiliza uma variedade de símbolos diferentes. Sua compreensão também é fácil, mas como já destacado, com o aumento do problema a ser resolvido, o diagrama também fica extenso. M >= 6 Exibir “Média maior que 6” Exibir “Média maior que 6” Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 15 Por outro lado, as linguagens de baixo nível são linguagens onde as instruções são baseadas em linguagem de máquina. Um exemplo de linguagem de baixo nível e a linguagem Assembler. A linguagem de programação C é classificada por alguns pesquisadores como linguagem de nível médio por apresentar instruções em alto nível e também em baixo nível. 2.6 Variáveis Na introdução desse capítulo foi mencionado que um algoritmo manipula dados de entrada para gerar a solução de um programa. A pergunta que será colocada agora é: como esses dados ficam armazenados para serem processados? Existe no computador uma área de armazenamento chamada de memória. A memória é um dispositivo físico onde todos os dados a serem processados ou já processados são armazenados. Basicamente existem dois tipos de memória: memória primária e memória secundária. A memória primária também chama de RAM (Random Access Memory) é uma memória de acesso aleatório e volátil. As memórias secundárias podem ser dispositivos externos tais como: discos magnéticos, CD-ROM, dentre outros. A grosso modo, podemos tentar visualizar a memória primária como uma caixa. Essas caixas são subdividas em caixas menores e dispostas de forma seqüencial. É nas “caixas” que as informações ficam armazenadas, ou seja, podemos ter um número, um caractere, uma seqüência de caracteres, etc. Essas caixas são chamadas de posições de memória. O número de subdivisões é finito. É por esse motivo que algumas vezes o Sistema Operacional envia mensagens informando que há pouca memória disponível, ou seja, praticamente o número total de posições de memória estão quase todos preenchidos. Para que o computador faça a manipulação das informações armazenadas é necessário conhecer quais são as posições de memórias que estão preenchidas. A cada posição de memória é associado um endereço físico. Esse endereço é representado por valor hexadecimal (base 16). Veja um exemplo na tabela abaixo: Endereço Físico Conteúdo Armazenado 1000:3AC89 “Hoje é feriado” 2000:AAFF3 25 Imagina se ao escrevermos nossos programas tivéssemos que conhecer quais as posições de memória que o nosso programa estivesse utilizando. Certamente a dificuldade seria bem maior e também o número de erros aumentaria em virtude da manipulação de erros na manipulação desses valores. As linguagens de programação permitem que os programadores forneçam nome às posições de memória. Cada posição de memória deve ter um nome diferente de outra posição. As regras para formação dos nomes variam de uma linguagem de programação para outra. Os nomes fornecidos as posições de memória são chamados de endereços lógicos. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 16 Endereço Lógico Conteúdo Armazenado Frase “Hoje é feriado” Idade 25 Quando fornecemos um nome para uma posição de memória, o computador automaticamente associa o nome a um endereço físico de memória. Dessa forma, ao invés de manipularmos os endereços físicos trabalhamos apenas com os nomes das posições. A escolha de uma posição de memória é determinada automaticamente pelo computador quando o mesmo irá executar um programa. O conteúdo de uma posição de memória não é um valor fixo, e durante a execução de um programa esse conteúdo pode variar. Portanto, o conteúdo de uma posição de memória é variável. As posições de memória que o computador manipula durante a execução de um programa damos o nome de variável. Como já discutido, toda variável em um programa deve ter um nome e as regras para a formação do nome das variáveis mudam de uma linguagem de programação para outra. Antigamente, os nomes de variáveis eram restritos a apenas oito caracteres, mas com a evolução dos sistemas operacionais essa limitação já foi superada. Como o nosso curso será baseado em linguagem C, inicialmente adotaremos algumas regras próximas dessa linguagem. Eis as regras:  Utilize nomes sugestivos, relacionados com o conteúdo que a variável irá armazenar;  Nomes de variáveis deverão ser iniciados com caracteres e não com números;  Alguns símbolos especiais não são aceitos, tais como: *, !, ?, etc;  O underline (“_”) pode ser utilizado; 2.7 Tipos de Dados Toda informação manipulada por um programa tem um tipo. O tipo é importante para que o computador possa armazenar de forma eficiente os dados a serem manipulados e também para saber quais são as operações básicas que podem ser realizadas com a variável. A quantidade de tipos e os nomes podem variar de uma linguagem de programação para outra, mas os tipos básicos, chamados de tipos primitivos são:  Inteiro;  Real;  Caractere;  Cadeia de caracteres ou string;  Booleano ou lógico; Tipo Inteiro:  Utilizado para armazenar valores numéricos sem casa decimal. Exemplo: 12, -12, 100, 0, -56, etc;  Operações que podem ser realizadas: adição, subtração, multiplicação, divisão, potenciação e resto de divisão (esta operação só é definida para valores inteiros); Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 17 Tipo Real:  Armazena valores numéricos com casa décima. Exemplo: 1.0, 2.456, -5.9090, 0.0, etc.  Operações que podem ser realizadas: adição, subtração, multiplicação, divisão, potenciação; Tipo Caractere:  Utilizado para armazenar um único caractere (podendo ser um dígito ou não). Exemplo: ‘1’, ‘a’, ‘A’, ‘*’, ‘?’, ‘/’, ‘:’, etc.  Os valores caracteres são representados entre apóstrofo (‘’) para diferenciar dos nomes das variáveis; Tipo String (cadeia de caracteres):  Uma string é formada por dois ou mais caracteres. Exemplo: “aa”, “Maria”, “Pedro”, “112”, etc;  Toda string é representada entre aspas (“”). Isso é necessário para diferenciar do nome das variáveis; Tipo Booleano:  Representado por apenas dois valores excludente: verdadeiro ou true e falso ou false; 2.8 Declaração de Variáveis Como já sabemos, uma variável é uma posição de memória que será utilizada por um programa para armazenar informações que serão manipuladas. Toda variável a ser utilizada em um programa dever ser declarada. Declarar uma variável significa fornecer um nome para a mesma e também indicar o tipo de dado que a variável irá armazenar. Do ponto de vista da máquina, quando declaramos uma variável o computador simplesmente “reserva” um endereço físico para armazenar informações e também associa a esse endereço físico um nome (endereço lógico). Através do tipo, o computador determina a quantidade de memória para cada variável e também “sabe” quais são as operações possíveis para cada uma. Existem algumas linguagens de programação que não exigem a declaração de variáveis. Programas escritos nessas linguagens são mais complicados de serem entendidos e também de dar manutenção. A maneira de declarar variáveis varia. A sintaxe em Porto-C para declarar uma variável é: <tipo_de_dado> <nome_da_variável> onde tipo_de_dado é qualquer tipo válido na linguagem e nome_da_variável será o endereço lógico a ser manipulado. Exemplo de declaração de variável: inteiro a real b caractere c inteiro x, y, z Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 20 se os conteúdos são iguais ou diferentes, se o conteúdo de uma variável é maior ou menor que o conteúdo de outra variável. Os operadores relacionais são: Operação Símbolo Exemplo Igualdade == A == B Maior > A > B Maior ou igual >= A >= B Menor < A < B Menor ou igual <= A <= B Diferente != A != B Quando utilizamos os operadores aritméticos o resultado será um valor numérico, mas quando utilizamos os operadores relacionais o resultado será um valor booleano (verdadeiro ou falso). Por exemplo: considere duas variáveis inteiras com os seguintes conteúdos A ← 3 e B ← 10. Operação Resultado A == B Falso A != B Verdadeiro A >= B Falso A <= B Verdadeiro Operadores Lógicos Os operadores lógicos são extremamente importantes no desenvolvimento de programas porque normalmente podemos ter várias expressões aritméticas e relacionais e devemos combinar os seus resultados afim de obter apenas um. Os operadores lógicos são utilizados para esse propósito. O resultado de uma expressão com a utilização dos operadores lógicos é booleano. Em algoritmos iremos utilizar três operadores lógicos: E, OU e NÃO. A operação E resulta em um valor verdadeiro se todos os operandos tiverem valor verdadeiro, caso contrário o resultado será falso. Para a operação OU o resultado será verdadeiro se um dos operandos tiverem resultado verdadeiro e será falso somente quando todos os operandos tiverem valor falso. A operação NÃO é utilizada para inverter o resultado de uma operação. Veja a tabela abaixo: Tabela Verdade: p q p E q NÃO(p E q) p OU q NÃO(p OU q) Verdadeiro Verdadeiro Verdadeiro Falso Verdadeiro Falso Verdadeiro Falso Falso Verdadeiro Verdadeiro Falso Falso Verdadeiro Falso Verdadeiro Verdadeiro Falso Falso Falso Falso Verdadeiro Falso Verdadeiro Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 21 2.10 Comandos de Entrada e Saída de Dados Até esse ponto já sabemos como o computador armazena os dados que serão processados e também como manipular as informações. Agora nos restar saber como armazenar uma informação digitada por um operador através do teclado e também como enviar mensagens no vídeo para que o usuário possa leia e seguir as instruções do programa. Comando para entrada de dados A instrução para entrada de dados é muito importante para um programa, pois normalmente os dados que serão processados devem ser informados por um operador. Quando o comando para entrada de dados é executado, deve-se informar o nome da variável onde o computador irá armazenar a informação. O comando para entrada de dados em Portu-C seguirá o mesmo padrão adotado para a linguagem C. Para este comando devemos informar dois parâmetros: o primeiro será uma string que representa o tipo de informação que será armazenado e o segundo o nome da variável que receberá o valor. O comando utilizado será leia(). Exemplos:  leia(“%d”, &idade) → armazena um valor inteiro na variável idade  leia(“%f”, &media) → armazena um valor real na variável média  leia(“%c”, &letra) → armazena um caractere na variável letra. O símbolo (&) indica para o computador o endereço físico da variável que receberá o valor. Caso o & seja omitido o valor lido pelo teclado não será armazenado na variável. As strings de controle utilizadas são: String de controle Descrição %d ou %i Valor inteiro %f Valor real (ponto flutuante) %c Valor caractere Comando para saída de dados Um comando de saída é uma instrução definida nas linguagens de programa que tem como objetivo principal exibir uma informação para o usuário. Essa informação é exibida no vídeo. Em Portu-C iremos utilizar a instrução imprima(). Alguns exemplos com a instrução imprima():  imprima(“Qual sua idade?”) → após a execução dessa instrução a string entre parênteses será impressa no vídeo.  imprima(“Informe a sua média semestral”)  imprima(“Sua idade é %d”, idade) → ao executar esse comando, a string %d será substituída pelo conteúdo armazenado na variável idade. Veja que o nome da variável não aparece entre as aspas. 2.11 Exemplos de Algoritmos  Algoritmo para leia dois números inteiros, executar a soma e exibir o resultado: Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 22 Inicio inteiro a, b, r imprima(“Digite o primeiro valor”) leia(“%d”, &a) imprima(“Digite o segundo valor”) leia(“%d”, &b) r = a + b imprima(“O resultado da soma é %d”, r) Fim  Algoritmo para leia dois valores inteiros e imprima o resto da divisão do primeiro valor pelo segundo Inicio inteiro a, b, r imprima(“Digite o primeiro valor”) leia(“%d”, &a) imprima(“Digite o segundo valor”) leia(“%d”, &b) r = a % b imprima(“O resto da divisão é %d”, r) Fim  Algoritmo para leia as duas notas da prova de um aluno e calcular a sua média semestral Inicio real p1, p2, m imprima(“Digite a primeira nota”) leia(“%f”, &p1) imprima(“Digite a segunda nota”) leia(“%f”, &p2) m = (p1+p2)/2 imprima(“A média é %f”, m) Fim 2.12 Exercícios em Classe 1. Escreva um algoritmo para beber um refrigerante em lata que está na geladeira. 2. Escreva um algoritmo para trocar a lâmpada da sala de aula. Suponha que todos os itens necessários para a troca estejam disponíveis na sala. 3. Um homem precisa atravessar um rio com um barco que possui capacidade apenas para carregar ele mesmo e mais um de seus três pertences, que são: um lobo, uma cabra e um maço de alfafa. Em cada viagem só poderá ir o homem e apenas um de seus pertences. A seguinte regra deverá ser respeitada: o lobo não pode ficar sozinho com a cabra e nem a cabra sozinha com o maço de alfafa. Escreva um algoritmo para fazer a travessia dos pertences que estão em uma margem do rio para a outra (uma travessia segura). Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 25 15. Escreva um algoritmo que leia um número entre 0 e 60 e imprima o seu sucessor, sabendo que o sucessor de 60 é 0. Não pode ser utilizado nenhum comando de seleção ou repetição. 2.13 Exercícios Complementares 1. Defina Algoritmos. 2. O que são variáveis? Por que são utilizadas em um programa? 3. O que são tipos de dados? Como são aplicados em um programa? 4. Quais os valores das expressões a seguir: a) 2+3*6 b) 12/3*2-5 c) 31/4 d) 31%4 e) 92 5. Indique o valor armazenado em cada variável após a execução das instruções abaixo: Início inteiro q, w, r real e q = 10 q = 10 + 30 w = -1 w = w + q q = q % w q = w / (q+40) e = 2*q/w r = 0 r = r + 1 r = r + 1 Fim 6. Determine o valor de cada uma das expressões abaixo sabendo que A, B, C contêm respectivamente 2, 7 e 3. Considere também a existência de uma variável lógica L contendo o valor falso (F). a) B == A * C E (L OU V) b) B > A OU B == AA c) L E B / A >= C OU NÃO(A<=C) d) NÃO(L) OU V E BA + >= C 7. Escreva um algoritmo que leia o valor do raio de uma esfera e calcule o seu volume dado pela expressão abaixo: Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 26 3 4 3r V π = . Considere que π vale 3.1416. 8. Escreva um algoritmo que leia quatro valores inteiros. Calcule e mostre o valor da sua média harmônica. dcba mh 1111 4 +++ = 9. Faça um algoritmo que leia um valor inteiro positivo e menor que 1000. Armazene-o numa variável inteira e determine a soma dos dígitos que formam o valor. Por exemplo: o valor 397 tem soma 19. 10. Escreva um algoritmo que leia um valor inteiro composto por três dígitos. Inverta o valor lido e o armazene em outra variável. Por exemplo: valor lido = 235 deverá ser armazenado em outra variável o valor 532. 11. Faça um algoritmo que lei um valor inteiro composto por três dígitos. Inverta o valor lido e faça a soma com o valor original. Por exemplo: valor lido foi 432. Deverá ser exibido o resultado da soma: 432 + 234 12. Faça um algoritmo que leia o valor de um depósito e o valor da taxa de juros. Calcule e exiba o valor do rendimento. 13. Faça um algoritmo que leia dois valores inteiros e positivos e armazene nas variáveis A e B respectivamente. Em seguida troque o conteúdo das variáveis, ou seja, A deverá receber o valor de B e B o valor de A. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 27 Capítulo 3 Estruturas de Seleção 3.1 Introdução Nos capítulos anteriores os nossos algoritmos eram caracterizados apenas por uma estrutura seqüencial, ou seja, não havia nenhum desvio condicional. O algoritmo começava com a declaração de variáveis, executava um conjunto de instruções e era finalizado. Na prática nem sempre se tem um algoritmo seqüencial. A maioria dos problemas do dia-a-dia e muitas das aplicações comerciais necessitam de testes para se chegar a solução do problema. Um exemplo muito simples ocorre no fechamento das notas aqui na faculdade. Todo final de ano, no boletim escolar na frente do nome de cada disciplina aparece escrito se o aluno foi aprovado, ou se está de exame ou retido. Neste caso, para cada aluno da faculdade, a partir de suas notas semestrais o sistema pode realizar uma entre três opções. A escolha de uma das opções depende da média do aluno. Vale destacar que o sistema escolherá apenas uma opção e automaticamente eliminará as outras. Outro exemplo muito comum ocorre no pagamento de prestações, mensalidades dentre outras. Nesses sistemas, o operador deverá entrar com a data do vencimento da parcela e o sistema automaticamente detectará se o cliente em atraso e conseqüentemente calculará o valor dos juros. Como pode ser percebido, a utilização de desvios condicionais é de extrema importância na construção de sistemas computacionais. Neste capítulo serão abordadas duas estruturas de seleção ou desvio condicional. 3.2 Estrutura de Seleção Simples Uma estrutura de seleção é utilizada quando um algoritmo necessita escolher uma instrução ou um conjunto de instruções quando uma condição (representada por uma expressão relacional ou lógica) é satisfeita ou não. Em Portu-C a instrução de seleção será representada pela instrução se. Sua sintaxe é: se (condição) Inicio <instrução_1> <instrução_2> . . <instrução_n> Fim Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 30 Exemplo 4: algoritmo para verificar se um número fornecido pelo usuário é positivo ou negativo. Inicio inteiro n imprima(“digite um valor inteiro: “) leia(“%d”, &n); se( n >= 0 ) imprima(“o número informado é positivo”) senão imprima(“o número informado é negativo”) Fim Exemplo 5: Um time de basquete está fazendo uma peneira para selecionar alguns jogadores. Para ser aceito no time o jogador deverá ter mais que 15 anos e ter altura acima de 180cm. Inicio inteiro idade real altura imprima(“digite a sua idade: “) leia(“%d”, &idade) imprima(“informe a sua altura: “) leia(“%f”, &altura) se( idade > 15 E altura > 180 ) imprima(“você foi aceito no time”) senão imprima(“você não foi aceito no time”) Fim 3.4 Estrutura de Seleção Agrupada Dentro de uma instrução se ou senão pode-se ter qualquer outra instrução, até mesmo outra estrutura de seleção. Considere agora a seguinte situação: calcular a média de um aluno que fez duas provas. Caso a média seja maior ou igual a 6 o aluno foi aprovado, caso contrário pode-se ter duas situações possíveis. Se a média for menor que 4 o aluno foi reprovado, por outro lado, se a média for maior que 4 e menor que 6 o aluno está de exame. A sintaxe para o comando de seleção alinhado é: se(condição1) Instrução_1 Instrução_2 . . . senão se(condição2) instrução_1 instrução_2 . . . senão Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 31 se(condição3) instrução_1 instrução_2 . . . Não se esqueça que cada instrução senão sempre está associada a uma instrução se. Através de comandos de seleção agrupados pode-se testar várias condições. A única desvantagem desse recurso é que a medida que o número de condições aumenta significativamente o número de instruções agrupadas aumentará proporcionalmente e dessa forma, a legibilidade do programa será prejudicada. Exemplo 6: algoritmo para calcular a média do aluno conforme situação descrita. Inicio real p1, p2, m imprima(“Informe o valor da primeira nota: “) leia(“%f”, &p1) imprima(“Informe o valor da segunda nota: “) leia(“%f”, &p2) m = (p1+p2)/2 se( m >= 6 ) imprima(“o aluno foi aprovado”) senão se( m < 4 ) imprima(“o aluno foi reprovado”) senão imprima(“o aluno ainda fará o exame”) Fim 3.5 Exercícios em Classe 1. Escreva o comando de seleção para cada uma das situações a seguir:  Se x for maior que y, multiplique o valor de x por y e armazene em y.  Se x for menor ou igual a y, some o valor de x com y e armazene em x. Caso contrário, subtraia o valor de x por y e armazene em y. 2. Escreva um algoritmo que leia dois valores inteiros, some os valores e imprima o resultado somente se os valores forem diferentes. 3. Escreva um algoritmo que leia um valor inteiro e imprima uma mensagem no vídeo informando se o valor é ou não múltiplo de 4. 4. Uma empresa de vendas oferece para seus clientes um desconto em função do valor da compra do cliente. Este desconto é de 20% se o valor da compra for maior ou igual a R$ 200,00 e 15% se for menor. Escreva um algoritmo que imprima o valor da compra do cliente e o valor do desconto obtido. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 32 5. Escreva um algoritmo que leia a altura e o sexo de uma pessoa. Calcule e imprima o seu peso ideal utilizando as seguintes fórmulas:  Para homens: (72.7*h)-58;  Para mulheres: (62.1*h)-44.7; 6. Um vendedor tem seu salário calculado em função do valor total de suas vendas. Este cálculo é feito de acordo com o seguinte critério: se o valor total de suas vendas for maior que R$ 20000,00 o vendedor receberá como salário 10% do valor das vendas. Caso contrário receberá apenas 7,5% do valor das vendas. Escreva um algoritmo que calcule o valor ganho pelo vendedor. 7. Escreva um algoritmo que leia três valores e verifique se os mesmos podem formar os lados de um triângulo. Para que os valores formem os lados de um triângulo é necessário que a soma de cada lado seja menor que a soma dos outros dois. 8. Desenvolva um algoritmo que calcule o valor da expressão abaixo: x y − = 2 8 9. Um hotel cobra R$ 60,00 a diária e mais uma taxa de serviços. A taxa de serviços é de:  R$ 5,50 por diária, se o número de diárias for maior que 15;  R$ 6,00 por diária, se o número de diárias for igual a 15;  R$ 8,00 por diária, se o número de diárias for menor que 15. Construa um algoritmo que mostre o valor da conta de um cliente. 10. Faça um algoritmo que calcule o valor de y:        = , , ,2 ,1 3 2 x x y 11. Escreva um algoritmo que resolva as raízes de uma equação do segundo grau na forma: 02 =++ cbxax . 12. Construa um algoritmo que leia três valores inteiros (suponha que o usuário tenha digitado três valores diferentes). Imprima o menor valor informado. 13. Escreva um algoritmo que leia três valores inteiros e diferentes. Mostre-os em ordem crescente. 3.6 Exercícios Complementares 1. Escreva o comando de seleção para cada uma das situações abaixo:  Se x for maior que y ou, se z for menor ou igual a 30, multiplique x por 2. Caso contrário, divida x por 2 e divida z por 5;  Se o desconto for menor que 25% e o preço do produto for maior que R$ 50,00 então, de um desconto de 25% no preço do produto. Se x <= 1 Se 1 < x <= 2 Se 2 < x <= 3 Se x > 3 Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 35 Capítulo 4 Estruturas de Repetição 4.1 Introdução No capítulo anterior foi mostrado que no desenvolvimento de programas de computadores normalmente há a necessidade de se fazer testes lógicos para que o programa possa executar determinadas instruções, ou seja, através do teste lógico existe a seleção de instruções a serem executadas. Até este ponto do curso, os algoritmos desenvolvidos realizavam apenas um conjunto de instruções uma única vez e o algoritmo era finalizado. Suponha a seguinte situação: em uma sala com 50 alunos, deseja-se calcular a média semestral de cada aluno considerando que todos realizaram duas provas. Para resolver esse problema com os conceitos de programação apresentados até agora seria necessário executar o mesmo programa 50 vezes. Isso não parece algo eficientes, mas resolveria o problema. Uma outra solução e a mais recomendada é a utilização de estruturas de repetição. Uma estrutura de repetição nada mais é do que uma instrução que indica ao computador para repetir um conjunto de instruções várias vezes. O número de repetições pode ser controlado pelo programador ou até mesmo pelo operador do sistema. A quantidade de vezes que um conjunto de instruções será executado depende de um teste lógico. As estruturas de repetição em programação também são conhecidas como laços de repetição. Basicamente serão estudadas três estruturas básicas de repetição. O número de estruturas de repetição e a sua sintaxe são específicos de cada linguagem de programação, mas o conceito central é o mesmo. O que difere uma estrutura de repetição da outra é a ordem de execução do teste lógico. Em algumas estruturas o teste é realizado no inicio e em outras no final. 4.2 Estrutura de Repetição Enquanto ... A estrutura de repetição enquanto é utilizada para repetir um conjunto de instruções várias vezes de acordo com um teste lógico que é realizado no inicio da instrução. A sintaxe para a estrutura enquanto é: enquanto (condição_lógica) início Instrução_1 Instrução_2 . . . instrução_n fim Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 36 sendo condição_lógica é uma expressão composta por operadores relacionais e lógicos. O conjunto de instruções dentro do bloco de repetição só será executado caso a condição_lógica resulte em um valor verdadeiro, caso contrário, não será executado. Ao atingir o final da instrução enquanto, o computador automaticamente retorna para o inicio da instrução e testará novamente a condição e todo o processo se repetirá até que a condição resulte em um valor falso. Exemplo 1: algoritmo para imprima os valores de 1 até 10 no vídeo. Inicio inteiro cont cont = 1 enquanto( cont <= 10 ) início imprima(“%d”, cont) cont = cont + 1 fim Fim Exemplo 2: Algoritmo para calcular a média dos números pares entre 0 e 100. Inicio inteiro cont, soma cont = 1 soma = 0 enquanto(cont <= 100) início se(cont % 2 == 0 ) soma = soma + cont cont = cont + 1 fim imprima(“A soma dos números pares é %d”, soma) Fim Exemplo 3: Calcular e imprima a média dos 50 alunos de uma sala de aluno. Suponha que cada aluno fez duas provas durante o semestre. Inicio inteiro cont real p1, p2, media cont = 1 enquanto(cont <= 50) início imprima(“Digite a primeira nota: “) leia(“%f”, &p1) imprima(“Digite a segunda nota: “) leia(“%f”, &p2) media = (p1+p2)/2 imprima(“A media do aluno %d é %f”, cont, media) Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 37 cont = cont + 1 fim Fim 4.3 Estrutura de Repetição Faça-Enquanto Como já destacado na introdução deste capítulo, o que difere uma estrutura de repetição de outra é a ordem de realização do teste lógico. Na estrutura enquanto, o teste lógico era realizado logo no início da estrutura e dependendo do valor do teste, o conjunto de instruções dentro da estrutura podia ser executado ou não. Outra estrutura de repetição é faça-enquanto. Essa estrutura é semelhante a estrutura enquanto. A diferença é que na estrutura faça-enquanto o teste lógico é realizado no final. Dessa forma, o conjunto de instruções pertencentes a estrutura é realizado pelo menos uma vez. A sintaxe para a estrutura faça-enquanto é: faça início Instrução_1 Instrução_2 . . . instrução_n fim enquanto (condição_lógica) Exemplo 4: Refazendo o exemplo 1 usando a estrutura faça-enquanto. Inicio inteiro cont cont = 1 faça imprima(“%d”, cont) cont = cont + 1 enquanto( cont <= 10 ) Fim Exemplo 5: Refazendo o exemplo 2 usando a estrutura faça-enquanto Inicio inteiro cont, soma cont = 1 soma = 0 faça início se(cont % 2 == 0 ) soma = soma + cont cont = cont + 1 Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 40 para(; cont <= 10;) início imprima(“%d”, cont) cont = cont + 1 fim Fim 4.5 Exercícios em Classe Estrutura equanto 1. Dado o conjunto de instruções a seguir, coloque o comando de repetição adequadamente: a) executar um conjunto de instruções 10 vezes; b) executar um conjunto de instruções N vezes, onde N é uma variável informada pelo usuário. 2. Execute o teste de mesa para os trechos abaixo: a) A = 1 S = 0 enquanto (A<5) início S = S + A A = A + 2 fim b) A = 1 N = 0 S = 0 enquanto (S < 12 ) início S = S + A A = A + 1 N = N + 1 fim 3. Represente cada uma das seqüências de números abaixo usando expressões matemáticas (lei formação – somatório ou produtório) a) 1 + 2 + 3 + 4 + .... + 20 b) 1 * 2 * 3 * 4 * ... * 20 c) 50 1 ... 3 1 2 1 1 1 ++++ d) n n       ++      +      +      1... 3 1 2 1 1 1 321 e) 10 1 ... 4 1 3 1 2 1 1 1 −+−+− 4. Faça um algoritmo que imprima todos os números pares entre 85 e 907. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 41 5. Escreva um algoritmo que calcule a soma dos primeiros 10 valores inteiros, ou seja, 1+2+3...+10. 6. Construa um algoritmo que, para um grupo de 50 valores inteiros fornecidos pelo usuário determine: a) a soma dos números positivos; b) a quantidade de valores negativos; 7. Criar um algoritmo que leia um número que será o limite superior de um intervalo e o incremento. Imprimir todos os números no intervalo de 0 até o limite lido. Por exemplos: Limite superior: 20 Incremento: 5 Saída no vídeo: 0 5 10 15 20 8. Escreva um algoritmo que leia 15 números fornecidos pelo usuário. Imprima o maior valor informado. 9. Escreva um algoritmo que leia vários números fornecidos pelo usuário. Imprima o menor valor informado. 10. Escreva um algoritmo que calcule o fatorial de um número. 11. Escreva um algoritmo que calcule o valor da expressão abaixo: 20 1 3 1 2 1 1 1 ++++= h Estrutura faça...equanto 12. Reescrever os algoritmos do exercício 2 usando a estrutura de repetição faça...enquanto. 13. Faça um algoritmo que imprima no vídeo todos os números entre 1 e 20. 14. Escreva um algoritmo que multiplique dois valores inteiros e positivos sem utilizar o operador de multiplicação (*). 15. Criar um algoritmo que imprima os 10 primeiros termos da série de Fibonacci. A série é dada por: 1 1 2 3 ... 16. Escreva um algoritmo que leia 20 valores inteiros e imprima a soma dos números cujos quadrados são menores que do que 225. 17. Calcular e imprima a média de cada um dos 50 alunos de uma turma. Suponha que foram aplicadas 2 provas. 18. Faça um algoritmo que leia um número e imprima todos os seus divisores. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 42 19. Escreva um algoritmo que leia 15 números fornecidos pelo usuário. Imprima quantos números maiores que 30 foram digitados. 20. Desenvolva um algoritmo que calcule o valor da expressão abaixo: n h 1 3 1 2 1 1 1 ++++=  Estrutura para 21. Reescreva os algoritmos do exercício 2 usando a estrutura de repetição para. 22. Desenvolva um algoritmo para calcular o valor da expressão abaixo: n nnnn y + − + − + − += 4 4 3 3 1 21 23. Faça um algoritmo para calcular o valor da expressão: n h 1 3 1 2 1 1 1 ±−+−=  24. Desenvolva um algoritmo para calcular o valor da expressão: !!3 3 !2 2 !1 1 n n x ++++=  25. Chico tem 1,50m e cresce 2 centímetros por ano, enquanto que, Juca tem 1,10m e cresce 3 centímetros por ano. Escreva um algoritmo que calcule e imprima quantos anos são necessários para que Juca seja maior que Chico. 26. Criar um algoritmo que calcule e imprima o valor de bn. O valor de n deverá ser maior ou igual a zero e o valor de b deverá ser inteiro. 4.6 Exercícios Complementares 1. Faça o teste de mesa nos algoritmos abaixo: a) A = 1 B = 4 S = 0 enquanto (A <= 6 ) início se (A <= B) S = S + A*B senão S = S - A*B A = A + 1 B ← B - 1 fim Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 45 5.2 Mapa de Memória em C Todo programa em C ao ser compilado, cria e usa quatro regiões na memória. Cada uma dessas regiões é distinta e possuem funções específicas. A figura abaixo ilustra as quatro regiões. A pilha tem diversas aplicações durante a execução de um programa. É na pilha que ficam armazenados os endereços de retorno das funções. O heap é uma área livre que é utilizado através das funções de alocação dinâmica de memória. 5.3. Tipos de Dados em C Em tem-se basicamente cinco tipos de dados:  Caractere – char  Inteiro – int  Ponto flutuante (real) – float  Ponto flutuante de precisão dupla (real) – double  Sem valor – void A declaração de uma variável em C é feita da mesma forma que foi utilizada em Porto-C: primeiro o tipo da variável e logo depois o nome da variável. Toda linha de comando em C é terminada por ponto e vírgula (;). Exemplos: int x; int a, b; float g; double v, s; char nome; Código do programa Variáveis globais Heap Pilha Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 46 Repare que em C não existe um tipo específico para trabalhar com cadeias de caracteres (strings). Sua formação será estudada no capítulo 7. 5.4 Inicialização de Variáveis No momento da declaração de uma variável pode-se atribuir um valor inicial a mesma. O operador responsável pela atribuição de valores a uma variável é representado pelo símbolo de igualdade (=). Exemplos: int x = 5; int a = 2, b = 3; float y = 12.3; char letra = ‘a’; 5.5 Operadores em C  Operador de atribuição: Como já mostrado, o operador de atribuição é responsável por atribuir um valor a uma variável. Esse operador é representado pelo símbolo de igualdade. Exemplos: int x = 2, y = 5; x = 10; y = x; x = y = 20;  Operadores aritméticos: Os operadores aritméticos em C são: adição (+), subtração (-), multiplicação (*), divisão (/) e módulo da divisão ou resto (%).  Operadores relacionais: Os operadores relacionais em C são: >, >=, <, <=, == e !=.  Operadores lógicos: Os operadores lógicos são: e (&&), ou (||) e não (!). 5.6 Comandos de entrada e saída de dados  Comando de saída: Um comando de saída de dados é responsável por enviar uma mensagem, ou seja, uma string podendo ser composta por letras ou número para o vídeo. Em C o comando para saída de dado será representado pela instrução printf(). A sintaxe para o comando printf() é semelhante a do comando imprima() usado em Porto-C. Exemplo: printf(“Esta é uma mensagem de exemplo”); Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 47 printf(“Tenham todos uma\n boa noite”); printf(“Sua nota é %f”, y); printf(“Os valores são %d e %d”, x, y );  Comando de entrada: Um comando de entrada é responsável por leia a informação informada via teclado por um operador e armazenar em uma posição de memória, ou seja, em uma variável já declarada. O comando utilizado para entrada de dados é scanf(). A sintaxe é semelhante ao do comando leia() previamente utilizado. Exemplo: scanf(“%d”, &x ); scanf(%f”, &media); scanf(“%c”, &letra); scanf(“%d %d %d”, x, y, z); 5.7 Estrutura de um programa em C Um programa em linguagem C é composto por vários blocos de códigos e pela declaração de bibliotecas. Dentro do programa deve haver um bloco principal de código chamado main() que representa o início do programa. É a partir do main() que todo as outras instruções do programa serão executadas. Exemplo: #include <stdio.h> void main() { int y; printf(“digite um valor inteiro: “); scanf(“%d”, &y); printf(“o valor informado foi %d”, y ); } 5.8 Estrutura de Seleção 5.8.1 Comando de Seleção if Em C tem-se dois comandos utilizados para trabalhar com seleção: if e switch. O funcionamento destas estruturas é semelhando ao apresentado em Porto-C:  Seleção Simples: Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 50 if(condição_lógicaA) { Instrução_1A; Instrução_2A; . . . Instrução_nA; } else { if(condição_lógicaB) { Instrução_1B; Instrução_2B; . . . Instrução_nB; } else { if(condição_lógicaC) { Instrução_1C; Instrução_2C; . . . Instrução_nC; } else { if(condição_lógicaD) { Instrução_1D; Instrução_2D; . . . Instrução_nD; } else { Instrução_1; Instrução_2; . . . Instrução_n; } } } } Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 51 5.8.2 Comando de Seleção switch Uma alternativa para o comando de seleção if é o comando switch. O comando switch também é utilizado para realizar seleções. A sua sintaxe é: switch ( op ) { case valorA: instrução 1A; instrução 2A; ... instrução nA; break; case valorB: instrução 1B; instrução 2B; ... instrução nB; break; . . . case valorn: instrução 1n; instrução 2n; ... instrução nn; break; default: instrução 1; instrução 2; ... instrução n; } A variável op passada para o comando switch só pode ser de dois tipos: ou inteira ou caractere. O comando switch testa o valor de op contra cada um dos valores presentes na instrução case. Caso algum valor seja igual, todas as instruções internas ao case são executadas e o comando break é utilizado para interromper a execução do switch. Se o comando switch não encontrar nenhum case corresponde ao valor da variável que está sendo testada as instruções internas ao comando default são executadas. 5.9 Estruturas de repetição 5.9.1 Comando while O comando while em C é a tradução para o comando “enquanto” utilizado em Porto-C. Sua sintaxe e utilização são a mesma. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 52 Exemplo 1: algoritmo para imprima os valores de 1 até 10 no vídeo. #include <stdio.h> void main() { int cont; cont = 1; while( cont <= 10 ) { printf(“%d”, cont); cont = cont + 1; } } Exemplo 2: Algoritmo para calcular a média dos números pares entre 0 e 100. #include <stdio.h> void main() { int cont, soma; cont = 1; soma = 0; while(cont <= 100) { if(cont % 2 == 0 ) soma = soma + cont; cont = cont + 1; } printf(“A soma dos números pares é %d”, soma); } Exemplo 3: Calcular e imprima a média dos 50 alunos de uma sala de aluno. Suponha que cada aluno fez duas provas durante o semestre. #include <stdio.h> void main() { int cont = 1; float p1, p2, media; while(cont <= 50) { printf(“Digite a primeira nota: “); scanf(“%f”, &p1); printf(“Digite a segunda nota: “); scanf(“%f”, &p2); media = (p1+p2)/2; printf(“A media do aluno %d é %f”, cont, media); cont = cont + 1; Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 55 Exemplo 10 #include <stdio.h> void main() { int cont; cont = 1; for( ; cont <= 10;) { printf(“%d”, cont); cont = cont + 1; } } Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 56 Capítulo 6 Arrays Unidimensionais (Vetores) 6.1 Introdução Nos capítulos 3 e 4 foram apresentadas as estruturas de seleção e de repetição que são de extrema importância no desenvolvimento de algoritmos. Nas técnicas de construção de algoritmos já comentadas em nenhum momento houve a necessidade de armazenar grandes quantidades de informação. Considere a seguinte situação prática. Um professor tem um total de 100 alunos. O professor gostaria de armazenar para processamento as duas notas referentes as provas aplicadas e também calcular e armazenar a média de cada aluno. Do ponto de vista prático sabe-se que a área de armazenamento utilizada por um programa é a memória RAM e que um programa armazena dados na memória através da declaração de variáveis que é realizada logo no inicio do programa. No problema descrito, qual seria inicialmente o número de variáveis necessárias para armazenar todas as informações? Para quem pensou em 150 variáveis acerto! Declarar 150 variáveis parece algo muito complicado e também nada prático. As linguagens de programação oferecem um recurso muito interessante e importante chamado de arrays. Os arrays são utilizados quando há a necessidade de manipular e conseqüentemente armazenar grandes quantidades de informação. 6.2 Arrays unidimensionais Um array é definido formalmente como um conjunto de variáveis, ou seja, um conjunto de posições de memória contíguas que são referenciadas pelo mesmo nome. A sintaxe para a declaração de um array unidimensional é: tipo nome_variável[tamanho] onde: tipo representa qualquer tipo válido da linguagem C, nome_variável é o nome que será utilizado para referenciar os conteúdos das posições de memória e tamanho representa o número máximo de elementos que podem ser armazenados na variável. Exemplo de declarações:  int y[50];  float media[1000]; Na primeira declaração tem-se uma variável x do tipo inteiro armazenando no máximo 50 valores inteiros e na segunda declaração tem-se uma variável chamada media com capacidade para 1000 valores do tipo float. Graficamente pode-se visualizar um array da seguinte forma: Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 57 10 2 4 87 23 . . . 50 90 28 Já vimos como declarar um array e também como um array pode ser visualizado graficamente. Mas como podemos acessar os elementos individuais de um array se todos são representados pela mesma variável? 6.3 Acessando elementos de um array unidimensional Como todos os elementos são referenciados pelo mesmo nome deve haver uma maneira de diferenciar o primeiro valor do segundo, do terceiro e assim por diante. O acesso a cada elemento do array é feito através de sua posição dentro da variável. Essa posição, chamada de índice do array, deve ser especificada através do uso de colchetes. Por exemplo:  y[0] → 10  y[1] →2  y[3] → 4 Como já foi mencionado, as posições de memória ocupadas por um array são contíguas, ou seja, uma ao lado da outra. O índice do primeiro elemento do array sempre começará em zero e o último índice dependerá do tamanho total do array, especificado no momento da declaração da variável. Por exemplo, ao escrever: int z[10] está sendo declarado um array com 10 elementos onde o primeiro elemento está na posição z[0] e o último está na posição z[9]. Para atribuir um elemento a um array deve-se especificar o nome do array juntamente com a posição que irá armazenar o valor. Por exemplo: z[0] = 2; z[1] = 45; ... Na prática a utilização de arrays sempre está associada com o uso de estruturas de repetição. Suponha um array com 1000 posições que deverá armazenar as médias de um aluno. Para armazenar os valores, deve-se executar 1000 atribuições. Com o uso de estruturas de repetição fica mais fácil realizar as operações. O espaço total em bytes ocupado por um array dependerá do tipo do array e também do número total de posições. Com essas informações consegue-se determinar o espaço total através da expressão: espaço = sizeof(tipo) * tamanho onde, sizeof() é uma função da linguagem C utilizada para determinar o número de bytes ocupados por um tipo de dado da linguagem e tamanho representa o número de posições definidas para o array. y = Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 60 6.7 Exercícios Complementares 1. Escreva um programa em C que preencha um vetor de 3000 posições com valores aleatórios. Imprima no vídeo o menor valor armazenado e também a média aritmética dos valores. A média deverá ser impressa com 4 casas decimais. 2. Escreva um programa em C que preencha um vetor de 500 posições com valores aleatórios. Imprima a quantidade de números ímpares. 3. Escreva um programa em C que preencha um vetor de 20 posições com valores aleatórios entre 100 e 200. Imprima o maior valor armazenado e também todos os seus divisores. 4. Altere o programa do exercício anterior para imprima também a diferença entre o maior e o menor elemento do vetor. 5. Escreva um programa em C que crie um algoritmo que leia um vetor de 30 números inteiros e gere um segundo vetor cujas posições pares são o dobro do vetor original e as ímpares o triplo. 6. Escreva um programa em C que armazene 50 notas e calcule quantas são 10% acima da média e quantas são 10% abaixo da média. Considere que a média seja 6. 7. Escreva um programa em C que leia a nota da primeira e da segunda prova de um aluno. Calcule sua média levando em consideração que a prova 1 tem peso 4 e a segunda tem peso 6. Imprima as notas e sua respectiva média. 8. Escreva um programa em C que leia dois vetores A e B, contendo cada um 25 elementos inteiros. Intercale esses dois conjuntos (A[0] | B[0] | A[1] | B[1] | ...) formando um vetor V de 50 elementos. 9. Fazer um algoritmo que leia a matrícula e a média de 10 alunos. Ordene da maior nota para a menor e imprima uma relação contendo todas as matrículas e médias. 10. Escreva um programa em C que preencha um vetor de 20 posições com valores aleatórios. Em seguida, imprima as seguintes informações: i) quantos números pares foram armazenados? ii) quantos números ímpares? iii) qual a média aritmética do vetor? iv) qual a porcentagem de números acima da média? Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 61 Capítulo 7 Manipulação de Strings e Caracteres 7.1 Introdução Como já comentado anteriormente em nosso curso de Algoritmos, a linguagem C não apresenta um tipo “string”. Sabemos também desde o início do nosso curso que uma string nada mais é do que uma cadeia (conjunto) de caracteres. Dessa forma temos: “Maria” “São Paulo” “Faculdade de Informática” Para manipularmos uma cadeia de caracteres em C devemos trabalhar com vetores unidimensionais. A utilização mais comum de um array unidimensional em C é na definição de uma string. Portanto, strings são vetores de do tipo char. Devemos estar atentos ao fato de que as strings têm como último elemento um ‘\0’, que é adicionado automaticamente ao final da string. A forma geral para declararmos uma string segue o mesmo padrão para a declaração de um array unidimensional: char nome_da_string[tamanho]; sendo tamanho representa o número máximo de caracteres que a string irá armazenar. Devemos incluir neste valor o finalizador de strings. Exemplo de declaração: char nome[20]; No exemplo acima, temos uma variável vetor que armazena no máximo 20 caracteres. Lembre-se que o tamanho da string deve incluir o finalizador de strings (‘\0’). As variáveis strings podem ser inicializadas no momento da declaração da mesma forma que as variáveis de outros tipos. Não se esqueça que uma string sempre vem entre aspas (“ “). Exemplo: char x[] = “Testando o programa”; char y[] = {‘T’,’e’,’s’,’t’,’e’,’ ‘,’d’,’e’,’ ‘,’c’,’o’,’n’,’h’,’e’,’c’,’i’,’m’,’e’,’n’,’t’,’o’,’\0’}; char t[] = {84, 101, 115, 116, 101, ‘\0’}; Nos exemplos acima, percebemos três maneiras diferentes de inicializar uma variável string. Quando fornecemos valores decimais, estes são convertidos em caracteres conforme tabela ASCII (veja no final do capítulo). Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 62 7.2 Funções para manipulação de strings A linguagem C apesar de não apresentar um tipo específico “string”, apresenta uma série de funções que podem ser aplicadas a uma variável do tipo vetor de caracteres. Essas funções apresentam seus cabeçalhos em string.h. Dentre as principais funções destacam-se: Função gets() A função gets() é utilizada para leia uma string do teclado. A função scanf() também pode ser utilizada, mas não apresenta um bom desempenho quando a string é formada por duas ou mais palavras separadas por caracteres em branco. Dessa forma, a função gets() apresenta um melhor resultado. O cabeçalho da função gets() está em stdio.h. Sua forma geral é: gets( nome_da_string ); Exemplo de utilização da função gets(): #include <stdio.h> int main() { char string[100]; printf (“Digite o seu nome: “); gets (string); printf (“\n\n Ola %s”,string); return(0); } A impressão de uma string no vídeo é realizada com a função printf(). Repare que o caractere de impressão utilizado para string é %s. Função strcpy() Esta função é utilizada para copiar uma string para outra. A sua forma geral é: strcpy( string_destino, string_origem ); A string_origem é copiada na string_destino. Exemplo: #include <stdio.h> #include <string.h> int main() { char str1[100], str2[100], str3[100]; printf (“Entre com uma string: “); gets (str1); strcpy (str2, str1); /* Copia str1 em str2 */ strcpy (str3, “Voce digitou a string “); Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 65 Tabela ASCII – American Standard Code for Interchange Information Char Dec Char Dec Char Dec Char Dec NUL ^@ 0 SPACE 32 @ 64 ‘ 96 ^A 1 ! 33 A 65 a 97 ^B 2 “ 34 B 66 b 98 ^C 3 # 35 C 67 c 99 ^D 4 $ 36 D 68 d 100 ^F 5 % 37 E 69 e 101 ^F 6 & 38 F 70 f 102 ^G 7 ‘ 39 G 71 g 103 ^H 8 ( 40 H 72 h 104 TAB ^I 9 ) 41 I 73 i 105 ^J 10 * 42 J 74 j 106 ^K 11 + 43 K 75 k 107 ^L 12 , 44 L 76 l 108 ^M 13 - 45 M 77 m 109 ^N 14 . 46 N 78 n 110 ^O 15 / 47 O 79 o 111 ^P 16 0 48 P 80 p 112 ^Q 17 1 49 Q 81 q 113 ^R 18 2 50 R 82 r 114 ^S 19 3 51 S 83 s 115 ^T 20 4 52 T 84 t 116 ^U 21 5 53 U 85 u 117 ^V 22 6 54 V 86 v 118 ^W 23 7 55 W 87 w 119 ^X 24 8 56 X 88 x 120 ^Y 25 9 57 Y 89 y 121 ^Z 26 : 58 Z 90 z 122 ^[ 27 ; 59 [ 91 { 123 ^| 28 < 60 \ 92 | 124 ^] 29 = 61 ] 93 } 125 ^^ 30 > 62 ^ 94 ~ 126 ^_ 31 ? 63 _ 95 del 127 5. Faça um programa em C que leia uma palavra pelo teclado e faça a impressão conforme o exemplo a seguir para a palavra AMOR AMOR AMO AM A 6. Faça um programa em C que leia uma palavra pelo teclado e faça a impressão conforme o exemplo a seguir para a palavra AMOR Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 66 A AM AMO AMOR 7. Escreva um programa em C que leia uma string via teclado. Converta os caracteres para minúsculo e informe a quantidade de caracteres que tem código ASCII par. 8. Escreva um programa em C que solicite o nome do usuário do sistema. O seu programa irá gerar uma senha que é formada apenas pelos caracteres das posições ímpares mais a soma do código ASCII dos caracteres nas posições pares. 7.4 Exercícios Complementares 1. Faça um programa em C que leia quatro strings pelo teclado. Depois, concatene todas as strings lidas em única e imprima-a no vídeo. 2. Faça um programa em C que leia uma palavra pelo teclado e informe a quantidade de caracteres que não são vogais. 3. Escreva um programa em C que leia uma palavra fornecida pelo teclado e em seguida imprima o caractere presente no meio da palavra, caso esta tenha um número ímpar de caracteres. Como exemplo, considere a palavra SONHO. O caractere a ser impresso será o N. 4. Uma string é considerada um palíndromo se quando lida da esquerda para a direita e da direita para a esquerda apresentam o mesmo valor. Por exemplo: ANA. Escreva um programa em C em que o usuário possa digitar várias palavras e informe se são palíndromos ou não. A cada palavra informada pergunte ao usuário se ele deseja continuar a execução do programa. 5. Escreva um programa em C que leia uma string (no máximo 100 caracteres) via teclado e informe a quantidade de palavras presentes na string. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 67 Capítulo 8 Arrays Bidimensionais (Matrizes) 8.1 Introdução Até agora, trabalhos com arrays unidimensionais (vetores). Um array bidimensional é formado por linhas e colunas, ou seja, temos uma tabela de elementos dispostos em linhas e colunas. Podemos também afirmar que um array bidimensional é basicamente um array de arrays unidimensionais. Um array bidimensional pode ser representado pela figura abaixo: 2 10 5 0 1 256 33 85 9 66 65 63 69 63 58 70 8.2 Declarando um array bidimensional Para declararmos um array bidimensional devemos especificar o número de linhas e o número de colunas presentes. A forma geral para declaração é: tipo nome_do_array[número_de_linhas][número_de_colunas]; tipo pode ser qualquer tipo válido em C (int, float, double, char). O primeiro índice presente representa o número total de linhas presentes no array e o segundo índice o número total de colunas. Exemplos de declaração: int x[5][5]; float y[2][3]; O primeiro exemplo declara um array x com 5 linhas e 5 colunas e, no segundo exemplo temos um array y com 2 linhas e 3 colunas. Tanto o índice da linha quanto da coluna começam em 0. Para acessarmos um elemento específico em um array bidimensional devemos informar o índice da linha e o da coluna. Por exemplo: x[2][1], retorna o elemento armazenado no array x, na linha 2 e coluna 1. Por exemplo, considere o array x abaixo: linhas colunas Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 70 2. Dada a matriz:           − = 702 642 513 A . Considere o programa abaixo que manipula a matriz A . #include <stdio.h> int main() { int i, j, A[3][3]; for( i = 0; i < 3; i++ ) for( j = 0; j < 3; j++ ) if( A[i][j] % 2 == 0 ) A[i][j] = A[i][j] * 3; return( 0 ); } Desenhe a nova matriz resultante após a execução do programa acima. 3. Escreva um programa em C que preencha uma matriz quadrada de ordem 4 com valores inteiros fornecidos pelo usuário. Mostre a soma de todos os elementos da matriz. 4. Para a matriz do exercício anterior, calcule e imprima a soma dos elementos da diagonal principal. 5. Para a matriz do exercício 3, calcule e imprima a soma dos elementos da diagonal secundária. 6. Dadas as matrizes 33xA e 33xB preenchidas com valores aleatórios entre 0 e 20, gere a matriz BAC += . 7. Escreva um programa em C que preencha uma matriz 1010xD com valores aleatórios entre 0 e 1000. Imprima o maior valor armazenado bem como a sua localização. 8. Faça um programa em C que entre com valores reais para uma matriz 32xC . Gere e imprima a t C . A matriz transposta é gerada trocando linha por coluna. Veja o exemplo a seguir:       = 654 321 C           = 63 52 41 tC 9. Dadas as matrizes 23xA e 32xB , gere BAC *= . 10. Escreva um programa em C que leia e armazene 50 nomes. Mostre a quantidade de nomes que começam com a letra “a”. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 71 11. Para o exercício 10, imprima apenas os nomes que começam com a letra “c”. 12. Para a matriz do exercício 10, imprima o maior nome armazenado (aquele que apresenta o maior número de caracteres). 13. Escreva um programa em C que leia o nome de 10 alunos de uma turma. Leia também a nota da primeira e da segunda prova. Calcule a média aritmética e imprima todas as informações no vídeo. 8.4 Exercícios Complementares 10. O que o programa abaixo imprime? #include <stdio.h> int main() { int t, i, M[3][4]; for (t=0; t<3; ++t) for (i=0; i<4; ++i) M[t][i] = (t*4)+i+1; for (t=0; t<3; ++t) { for (i=0; i<4; ++i) printf ("%d ", M[t][i]); printf ("\n"); } return(0); } 11. Escreva um programa em C para gerar a seguinte matriz:             = 161284 12963 8642 4321 t 12. Faça um programa em C que preencha uma matriz quadrada de ordem 5 com valores aleatórios entre 0 e 50. Em seguida, imprima todos os elementos que estão acima da diagonal secundária bem como a sua soma. 13. Escreva um programa em C que preencha uma matriz quadrada de ordem 10 com valores aleatórios entre 0 e 1000. Imprima todos os elementos da diagonal principal e da secundária. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 72 14. Dadas as matrizes 22xX e 22xY preenchidas com valores inteiros fornecidos pelo usuário, gere a matriz YXZ −= . 15. Escreva um programa em C que entre com valores para uma matriz 43xA . Gere e imprima a matriz B que é o triplo da matriz A . 16. Escreva um programa em C que preencha uma matriz 54xC com valores reais informados pelo usuário. Calcular e imprima a soma de todos os seus elementos. 17. Dada uma matriz B (quadrada de ordem 10) de números inteiros, determine a quantidade de números ímpares e pares armazenados. 18. Faça um programa em C que leia uma matriz 12 x 4 com valores das vendas de uma loja, em que cada linha representa um mês do ano, e cada coluna, uma semana do mês. Calcule e imprima: a) total vendido em cada mês; b) total vendido no ano; 19. Escreva um programa em C que preencha uma matriz quadrada de ordem 5 com valores inteiros fornecidos pelo usuário. Verifique se a matriz é ou não uma matriz triangular superior. Matriz triangular superior é uma matriz onde todos os elementos de posição L < C são diferentes de 0 e todos os elementos de L > C são iguais a 0. L e C representam respectivamente linha e coluna. 20. Considere a seguinte matriz ]3][2][3[B . Preencha a matriz com valores aleatórios entre 0 e 50. Em seguida calcule e imprima a soma dos elementos. 21. Criar um programa em C que possa armazenar as alturas de dez atletas de cinco delegações que participarão dos jogos de verão. Imprima a maior altura de cada delegação. 22. Escreva um programa em C que leia 10 nomes via teclado. Os nomes deverão ser armazenados em ordem crescente de tamanho (em relação ao número de caracteres presentes na string). Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 75 int *p; num = 55; p = &num; valor = *p; //atribuição de forma indireta printf("\n\n%d\n",valor); printf("Endereço para onde o ponteiro aponta: %p\n",p); printf("Valor da variável apontada: %d\n",*p); return(0); } #include <stdio.h> int main() { int num,*p; num = 55; p = &num; /* Pega o endereço de num */ printf("\nValor inicial: %d\n",num); *p = 100; /*Muda o valor de num de uma maneira indireta */ printf("\nValor final: %d\n",num); return(0); } Nos exemplos acima vemos um primeiro exemplo do funcionamento dos ponteiros. No primeiro exemplo, o código %p usado na função printf() indica à função que ela deve imprima um endereço. Podemos fazer algumas operações aritméticas com ponteiros. A primeira, e mais simples, é igualar dois ponteiros. Se temos dois ponteiros p1 e p2 podemos igualá-los fazendo p1=p2. Repare que estamos fazendo com que p1 aponte para o mesmo lugar que p2. Se quisermos que a variável apontada por p1 tenha o mesmo conteúdo da variável apontada por p2 devemos fazer *p1=*p2. Basicamente, depois que se aprende a usar os dois operadores (& e *) fica fácil entender operações com ponteiros. 9.4 Cuidados com ponteiros O principal cuidado ao se usar um ponteiro deve ser: saiba sempre para onde o ponteiro está apontando. Isto inclui: nunca use um ponteiro que não foi inicializado. Um pequeno programa que demonstra como não usar um ponteiro: #include <stdio.h> int main() /* Errado - Não Execute */ { int x,*p; x = 13; *p = x; return(0); } Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 76 Este programa compilará e rodará. O que acontecerá? Ninguém sabe. O ponteiro p pode estar apontando para qualquer lugar. Você estará gravando o número 13 em um lugar desconhecido. Com um número apenas, você provavelmente não vai ver nenhum defeito. Agora, se você começar a gravar números em posições aleatórias no seu computador, não vai demorar muito para travar o micro (se não acontecer coisa pior). 9.5 Exercícios em Classe 1. Após a execução do trecho de programa abaixo, o que será impresso? #include <stdio.h> void main( void ) { int x, *y; x = 25; y = &x; *y += 2; printf(“%d”, x ); } 2. Considere o trecho de programa abaixo. Quais serão os valores armazenados nas variáveis após sua execução? #include <stdio.h> void main( void ) { int a = 2, b = 3, temp; int *pa, *pb; pb = &b; pa = &a; temp = *pb; *pb = *pa; *pa = temp; } 3. Analise o trecho de programa abaixo e informe o que será impresso após a execução. #include <stdio.h> void main( void ) { float x, y, *z; x = 10.0; z = y; *z = x + 2.5; printf(“x = %f, y = %f”, x, y); } Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 77 Capítulo 10 Funções 10.1 Introdução Até agora os nossos programas foram codificados com uma função principal (main()) onde toda a atividade do programa ocorre. Em algumas situações, utilizamos algumas funções definidas da linguagem C tais como: rand(), pow(), sqrt(). Lembre-se que essas funções foram utilizadas dentro da função principal. A medida que os nossos programas vão ficando maiores, sua complexidade aumenta e portanto fica também mais difícil fazer manutenções e até mesmo entender a lógica do programa. Dessa forma, as linguagens de programação permitem que os usuários separem seus programas em blocos. A idéia é dividir programas grandes e complexos em blocos para facilitar a sua construção. Esses blocos de construção são chamados em C de funções. Portanto, uma função nada mais é do que um bloco de construção que realiza uma atividade específica. A declaração de uma função em C segue o mesmo padrão adotado para a função principal do programa. A sua forma geral é: tipo_de_retorno nome_da_função ( declaração_de_parâmetros ) { corpo_da_função; } O tipo_de_retorno é o tipo de variável que a função vai retornar. O default é o tipo int, ou seja, uma função para qual não declaramos o tipo de retorno é considerada como retornando um inteiro. A declaração de parâmetros é feita de forma semelhante a declaração de variáveis que estamos acostumados a fazer em nossos programas. A grande diferença na declaração dos parâmetros é que devemos especificar o tipo para cada variável. Exemplo: tipo variavel1, tipo variavel2, tipo variavel3, ..., tipo variavelN Estas variáveis que compõem os parâmetros da função representam as entradas para a função. A saída da função está especifica no tipo de retorno. O copo_da_função contém as instruções que irão processar os dados de entrada (parâmetros), gerando as saídas da função. Para que um valor seja retornado pela função, deve-se utilizar o comando return. Quando se chega a uma declaração return a função é encerrada imediatamente e, se o valor de retorno é informado, a Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 80 void imprima( void ) { printf(“Testando!”); } Repare no exemplo acima que só utilizamos o comando return quando uma função deve retornar um valor ou ser interrompida (como já foi visto). 10.3 Passagem de Parâmetros Nos exemplos anteriores, quando chamamos as funções passamos valores paras as mesmas. Isso acontece porque valores declarados em uma função não são acessíveis dentro de outra. Em C temos dois tipos de passagem de parâmetros: passagem por valor e passagem por referência. Na passagem por valor como o próprio nome indica, apenas uma “cópia” dos valores são passados para a função. As alterações realizadas pela função não são feitas nos valores originais do parâmetro. Como exemplo podemos citar o programa para o cálculo do quadrado de um número codificado anteriormente. Vamos considerar outro exemplo abaixo: #include <stdio.h> float somar( float x, float y ); int main( void ) { float a, b, total; printf(“Digite um valor: “); scanf(“%f”, &a ); printf(“Digite um valor: “); scanf(“%f”, &b ); total = somar( a, b ); printf(“a soma dos números é: %f”, total ); return( 0 ); } float somar( float x, float y ) { float t; t = x + y; return t; } No exemplo acima, os valores declarados na função main() são passados para a função somar(), que realiza a soma e retorna o resultado. Veja que os valores originais na função main() não são alterados. Esse tipo de passagem de parâmetro é por valor, e é o padrão da linguagem. Uma outra maneira de passagem de parâmetros é quando a função que recebe os parâmetros consegue alterar os valores originais na função onde os mesmos foram declarados. Esse tipo de Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 81 passagem de parâmetro é conhecido como passagem por referência. Neste caso a referência (endereço) das variáveis são passadas para as funções. Considere o exemplo abaixo: #include <stdio.h> void troca( float *x, float *y ); int main( void ) { float a, b; printf(“Digite um valor: “); scanf(“%f”, &a ); printf(“Digite um valor: “); scanf(“%f”, &b ); troca( &a, &b ); printf(“a = %f e b = %f”, a, b ); return( 0 ); } void troca( float *x, float *y ) { float t; t = *x; *x = *y; *y = t; } O que acontece no exemplo acima é que estamos passando para a função troca() os endereços das variáveis a e b. Estes endereços são armazenados nos ponteiros x e y da função. Como vimos no capítulo anterior, o operador (*) é utilizado para acessar o conteúdo apontado pelos ponteiros. Uma utilização muito comum de passagem de parâmetros por referência é quando uma função deve retornar dois ou mais valores. Lembre-se que uma função retorna apenas um valor. Dessa forma, a solução é passar os parâmetros por referência. 10.4 Passagem de arrays para funções Da mesma forma que passamos variáveis comuns para as funções, também podemos passar arrays. Vamos considerar como exemplo a seguinte declaração para um array unidimensional: int y[200]; Considere também que queiramos chamar a função alterar() e passar o array y como parâmetro. Para passarmos o array para a função, apenas referenciamos o nome da variável. Exemplo: alterar( y ); Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 82 O diferencial está na declaração da variável que irá receber o parâmetro. Essa declaração pode ser feita de duas maneiras diferentes: 1. void alterar( int t[200] ); 2. void alterar( int *t ); Quando passamos um array para uma função em C, a passagem de parâmetros é feita por referência. Nas três situações acima, a função alterar() recebe um ponteiro (endereço) do primeiro elemento armazenado no array. Esse tipo de passagem de parâmetro é bem prático para a linguagem. Imagine a situação onde temos um array com uma quantidade grande de elementos, se a passagem dos parâmetros fosse por valor, o compilador teria que fazer uma cópia de todos os valores para a função, o que poderia haver uma perda de desempenho do programa. A manipulação do array dentro da função é realizada da mesma forma que estávamos manipulando, independentes da forma com que o parâmetro é declarado. 10.5 Escopo de variáveis As variáveis que utilizamos em nossos programas podem ser declaradas em três lugares diferentes. Dependendo da sua declaração, a abrangência das variáveis muda. Os três tipos são: ⇒ Variáveis locais; ⇒ Variáveis globais; ⇒ Parâmetros formais. Os nossos primeiros programas em C usavam apenas a função main(). Dessa forma, todas as variáveis eram declaradas dentro dessa função. Essas variáveis são denominadas variáveis locais, e só tem validade dentro do bloco onde foram declaradas. As variáveis globais são declaradas fora das funções de um programa, podendo ser acessadas e alteradas por todas as funções. Os parâmetros formais se referem as variáveis que são declaradas para receber os parâmetros das funções. Essas variáveis só apresentam abrangência enquanto a função está sendo executada, ou seja, essas variáveis são locais a função. 10.6 Exercícios em Classe 1. Considere o programa em C abaixo #include <stdio.h> int teste( int a, int b ); int main( void ) { int x = 9, y = 5, total; total = teste( x, y ); Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 85 14. Reescreva a função do exercício 9, utilizando passagem de parâmetro por referência. 15. Escreva apenas uma função em C que receba como parâmetro uma string e retorne a última letra. 16. Escreva apenas uma função em C que receba um valor representando uma temperatura na escala Fahrenheit e converta para a escala Centígrados. A fórmula de conversão é: 5 1609 + = C F , onde F representa a temperatura em Fahrenheit e C em Centígrados. 17. Escreva um programa em C, contendo uma função que receba três valores inteiros. Seu programa deverá imprima os valores em ordem crescente. Utilize passagem de parâmetros por referência. 18. Escreva um programa em C para calcular e imprima as raízes de uma equação do 2º grau. Seu programa deverá ter duas funções: uma para o cálculo do delta e a outra para calcular as raízes da equação. 19. Escreva apenas uma função em C que receba como parâmetro três valores inteiros e positivos e verifique se os mesmo podem formar um triângulo. Lembre-se que: três números podem representar os lados de um triângulo se cada lado é menor que a soma dos outros dois. Utilize passagem de parâmetro por referência. 20. Escreva um programa em C, contendo uma função que calcule e retorne o valor da expressão: 16 35 2 − + = x x y . 21. Escreva apenas uma função em C que receba como parâmetro uma frase e retorne o valor do caractere localizado no meio da frase, caso a frase tenha um número ímpar de caracteres. 22. Escreva um programa em C, contendo uma função que calcule e retorne o valor da expressão: N h 1 ... 4 1 3 1 2 1 1 ++−+−= . 23. Escreva apenas uma função em C que calcule e retorne o valor da expressão: n n nnn y + − ++ − + − += 2 1 ... 2 3 1 21 . 24. Repare a seguinte característica do número 3025: 30 + 25 = 55 e 552 = 3025. Escreva um programa em C contendo uma função que verifique um número com quatro dígitos apresenta a característica acima. Seu programa deverá leia vários números(um de cada vez). O programa termina quando for lido um valor menor do que 1000 ou maior que 9999. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 86 25. Uma empresa classifica seus funcionários em três níveis de acordo com um índice de produtividade. São eles: (1) Excelente, (2) Bom e (3) Regular. Cada nível acrescenta um abono ao salário base do funcionário, de acordo com a seguinte tabela: Nível Aumento Excelente 80% do salário base Bom 50% do salário base Regular 30% do salário base Escreva um programa em C que leia o código do funcionário (numérico), seu salário base e seu nível. O programa deverá imprima o novo salário do funcionário. O cálculo do salário deverá ser feito por uma função. O programa deverá ser executado para vários funcionários até que o código 0 seja informado. 26. Escreva um programa em C que apresente o seguinte menu de opções para os usuários: Escolha uma opção: 1. somar 2. subtrair 3. Multiplicar 4. Dividir Resultado: O usuário deverá escolher uma opção válida e em seguida fornecer dois valores. Dependendo da opção escolhida, seu programa deverá executar os cálculos e exibir o resultado. Utilize uma função para cada opção. 27. A concessionária local de telefonia de uma cidade do interior gostaria de fazer um programa que pudesse controlar a central de 1000 assinantes que foi disponibilizada para a cidade. Faça um programa que funcione de acordo com o seguinte menu: Menu de Opções: 1. Inclusão de novo telefone 2. Alteração de telefone 3. Exclusão de telefone 4. Impressão dos telefones cadastrados. 5. Consulta por nome 6. Sair Para cada uma das opções do menu deverá ter uma função no seu programa. Sugestão: trabalhe com dois arrays, um para o número dos telefones e o outro para os nomes. Declare os arrays como variáveis globais. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 87 Capítulo 11 Estruturas 11.1 Definição e declaração de estruturas em C Até o momento vimos como agrupar várias informações (utilizando arrays) do mesmo tipo. Em C podemos agrupar também informações de tipos diferentes formando um novo tipo de dados. Esse novo tipo é chamado de tipo personalizado ou tipos definidos pelo usuário. Este tipo é conhecido como estrutura em C ou como registro em algumas linguagens de programação como o pascal. Define-se estrutura como um conjunto de variáveis que são referenciadas sob o mesmo nome, oferecendo um meio de manter as informações relacionadas juntas. Como exemplo de uma estrutura podemos citar uma ficha pessoal contendo nome, telefone e endereço. Essas três informações estão relacionadas entre si para compor a ficha. A ficha em si é a estrutura. Para se criar uma estrutura em C usa-se o comando struct. Sua forma geral é: struct nome_da_estrutura { tipo_1 nome_1; tipo_2 nome_2; ... tipo_n nome_n; } variáveis_estrutura; O nome_da_estrutura é o nome para a estrutura. As variáveis_estrutura são opcionais e seriam nomes de variáveis que o usuário já estaria declarando e que seriam do tipo nome_da_estrutura. Note que a declaração é terminada com ponto e vírgula (;). Um primeiro exemplo: struct teste{ float i; int f; } a, b; Neste caso, teste é uma estrutura com dois campos, i e f. Foram também declaradas duas variáveis, a e b que são do tipo da estrutura, isto é, a possui os campos i e f, o mesmo acontecendo com b. O exemplo abaixo cria uma estrutura de endereços: struct tipo_endereco { Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 90 char x; int y; float z; char s[10]; } teste; func( teste.x ); //passa apenas o valor do caractere x para a função func( teste.y ); //passa apenas o valor da variável y para função func( teste.s[2] ); //passa o valor do caractere de s[2] Nos exemplos mostrados acima, temos a passagem de parâmetros por valor. Caso seja necessário passar o endereço de um elemento individual da estrutura, basta colocar o operado & antes da variável do tipo da estrutura. Exemplo: func( &teste.x ); //passa o endereço do caractere x para a função func( &teste.y ); //passa o endereço da variável y para a função func( teste.s ); //passa o endereço da string s para a função. Não se esqueça que o operador & precede o nome da variável do tipo estrutura e não o nome do elemento individual da estrutura. Outro ponto a destacar é com relação a variáveis do tipo vetores de caracteres (strings) que já significam endereços de memória, portanto a utilização do operador & é dispensável. 11.4 Passando estruturas inteiras para funções No tópico anterior passamos elementos individuais como parâmetros para funções. Da mesma forma, podemos passar para uma função a estrutura inteira. Quando uma estrutura for passada como parâmetro para uma função, não se esqueça que o tipo de argumento deve coincidir com o tipo de parâmetro. Veja o exemplo abaixo: void main( void ) { struct exemplo{ int a, b; char c; } d; d.a = 1000; f( d ); } f( struct { int x, y; char h; } p ) { printf(“%d”, p.x); } Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 91 11.5 Ponteiros para estruturas A linguagem de programação C permite a utilização de ponteiros para estruturas da mesma forma que permite a utilização de ponteiros para os outros tipos de variáveis. Como para as outras variáveis, a declaração do ponteiro é feita utilizando o operador * na frente do nome da estrutura. Exemplo: struct teste *p; No exemplo acima, a variável p armazena o endereço de memória da estrutura teste. Ponteiros para estruturas apresentam duas aplicações básicas: ⇒ Gerar passagem por referência ⇒ Criação de estruturas de dados encadeadas (listas). Este será o enfoque do curso de Estruturas de Dados 1 no próximo ano. A principal desvantagem da passagem de estruturas por valor está no tempo necessário para armazenar e retirar todos os elementos da estrutura da pilha, caso a estrutura apresente muitos membros. Estruturas grandes quando passadas por valor podem prejudicar o desempenho do programa. O mesmo não acontece para estruturas pequenas. Uma solução para não comprometer o desempenho do programa quando uma estrutura grande precisa ser passada para uma função, é a utilização de ponteiros para estruturas. Neste caso, apenas um endereço de memória é armazenado na pilha. Exemplo da atribuição do endereço de uma estrutura para uma variável ponteiro. struct teste { int a, b; float x; } y; struct teste *p; p = &y; Quando utilizamos ponteiros para estruturas, a forma de acessar os dados sofre alteração. Nesta situação utiliza-se o operador (→) ao operador (.). Por exemplo: p→a = 10; O operador seta somente é utilizado quando se está acessando um elemento de estrutura através de um ponteiro para a estrutura. 11.6 Comando typedef A linguagem C permite que o programador defina novos nomes aos tipos de dados que estão sendo criados. Para definir esses nomes utiliza-se o comando typedef. Vale salientar que o comando Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 92 typedef é utilizado apenas para definir um novo nome para um tipo existente. A forma geral do comando typedef é: typedef tipo nome; sendo tipo qualquer tipo de dados permitido pela linguagem e nome é o novo nome para esse tipo. O novo nome a ser definido nada mais é do que uma opção ao nome antigo e não uma substituição. Como exemplo, podemos criar um novo nome para o tipo de dado int usando: typedef int carro; A instrução acima informa ao compilador que carro é um outro nome para o tipo int. Dessa forma, para declarar uma variável do tipo inteiro podemos ter duas opções: int y; carro y; 11.7 Exercícios em Classe 1. Analise o programa em C abaixo: #include <stdio.h> struct teste { int x, y; }; void func ( struct teste *t ); int main( void ) { struct teste p; p.x = 10; p.x = 20; func( &p ); return( 0 ); } void func( struct teste *t ) { t → x = t → x * 2; t → y = t → x - t → y; } Após a execução do programa acima, quais são os valores armazenados respectivamente nas variáveis x e y? Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 95 Capítulo 12 Manipulação de arquivos em C 12.1 Introdução O armazenamento de dados em variáveis e arrays é temporário, ou seja, os dados são perdidos quando uma variável local “sai do escopo” ou quando o programa termina. Portanto, os arquivos são utilizados para retenção em longo prazo de grandes quantidades de dados, mesmo depois que o programa termina. Estes dados são armazenados em dispositivos de armazenamento secundário como discos magnéticos, discos ópticos, etc. 12.2 Streams Em C, o sistema de arquivos trabalha com vários dispositivos diferentes. Dessa forma, o sistema de arquivos deve conseguir trabalhar com esses dispositivos da mesma forma, embora esses dispositivos sejam muito diferentes. Isso acontece porque o sistema de arquivo transforma-os em um dispositivo lógico chamado streams. Estas streams são independentes do dispositivo. Existem dois tipos de streams: texto e binária. Uma stream de texto nada mais é do que uma seqüência de caracteres. Por outro lado, uma stream binária é uma seqüência de bytes. Em C devemos associar uma stream com um arquivo específico através da operação de abertura. Cada stream associada a um arquivo tem uma estrutura de controle de arquivo do tipo FILE. Essa estrutura é definida no cabeçalho STDIO.H As principais funções para manipular um arquivo estão relacionadas na tabela abaixo: Nome Função fopen() Abre um arquivo fclose() Fecha um arquivo putc() Escreve um caractere em um arquivo getc() Lê um caractere de um arquivo fseek() Posiciona o ponteiro de arquivo em um byte específico feof() Devolve verdadeiro se o fim de arquivo for atingido ferror() Devolve verdadeiro se ocorreu um erro rewind() Repõe o ponteiro de posição de arquivo no início do arquivo remove() Apaga um arquivo fflush() Descarrega um arquivo Para realizar as operações básicas em um arquivo (escrever e leia), seu programa precisa usar ponteiros para arquivos. Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 96 Um ponteiro de arquivo é um ponteiro para as informações sobre o arquivo tais como seu nome, status e posição atual do arquivo. Um ponteiro de arquivo é uma variável do tipo FILE que é definido em STDIO.H. A declaração dessa variável é: FILE *arq; 12.3 Abrindo um arquivo A abertura de um arquivo é realizada com a função fopen(). Esta função associa um arquivo a uma stream. O retorno da função fopen() é um ponteiro do tipo FILE para o arquivo que está sendo aberto. A função fopen() necessita de dois parâmetros: o primeiro é um ponteiro para uma cadeia de caracteres que representa o nome do arquivo e o segundo é o modo como o arquivo será aberto, ou seja, apenas para leitura, apenas para escrita ou leitura e escrita ao mesmo tempo. Os valores para o modo de leitura estão relacionados na tabela abaixo. Modo Função r Abre um arquivo texto para leitura w Cria um arquivo texto para escrita a Anexa a um arquivo texto rb Abre um arquivo binário para leitura wb Cria um arquivo binário para escrita ab Anexa a um arquivo binário r+ Abre um arquivo texto para leitura/escrita w+ Cria um arquivo texto para leitura/escrita a+ Anexa ou cria um arquivo texto para leitura/escrita r+b Abre um arquivo binário para leitura/escrita w+b Cria um arquivo binário para leitura/escrita a+b Anexa um arquivo binário para leitura/escrita No momento da abertura de um arquivo, caso ocorra algum problema, a função fopen() devolverá um ponteiro nulo. Portanto, devemos sempre testar o valor de retorno antes de utilizarmos o ponteiro. O trecho de código abaixo mostra a abertura de um arquivo. FILE *arq; arq = fopen( “teste”, “w” ); if( arq == NULL ) { printf(“O arquivo não pôde ser aberto”); exit(1); } Caso você utilize a função fopen() para abrir um arquivo no modo de escrita, e exista algum arquivo com o mesmo nome este será apagado e um novo arquivo será criado, caso não exista, o arquivo será criado. Arquivos existentes só podem ser abertos no modo de leitura. Se porventura Algoritmos / Linguagem C – Prof. Ms. Antonio Marcos SELMINI 97 você quiser adicionar informações ao final do arquivo, o mesmo deve ser aberto no modo anexar. O modo de leitura/escrita não apagará um arquivo se ele já existir. 12.4 Fechando um arquivo Para fechar um arquivo associado a uma stream usamos o comando fclose(). Se a operação for bem- sucedida, a função retornará o valor zero. Qualquer outro valor indica erro. A utilização do comando fclose() é exemplificada abaixo. fclose( arq ); 12.5 Escrevendo e lendo caracteres em um arquivo A operação para escrever caracteres em um arquivo pode ser realizada através de duas funções equivalentes: putc() e fputc(). Ambas as funções são utilizadas para escrever caracteres em um arquivo que foi previamente aberto no modo escrita. A sintaxe para a função putc() é: int putc( int ch, FILE *arq ); sendo que ch é o caractere que será escrito no arquivo e arq o ponteiro de arquivo devolvido pela função fopen(). Por razões mais antigas, o caractere ch é do tipo inteiro. Caso a operação for bem- sucedida, a função retornará o caractere escrito, caso contrário retornará EOF (end of file). O processo de leitura de caracteres de um arquivo também envolve duas funções: getc() e fgetc(). Ambas as funções lêem caracteres de um arquivo previamente aberto no modo leitura. A sintaxe para a função getc() é: int getc( FILE *arq ); Se a operação for bem sucedida, a função retornará um inteiro. Quando o final do arquivo for atingido um EOF será retornado. O programa abaixo utiliza as funções apresentadas acima para abrir e escrever caracteres em um arquivo. #include <stdio.h> #include <stdlib.h> int main() { FILE *arq; char ch; arq = fopen( “teste.txt”, “w” ); if( arq == NULL ) { printf(“arquivo não pode ser aberto”); exit(1); }
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved