Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Terceira Edição
Juazeiro – BA
2020
Programação Básica com Linguagem C 2
O conteúdo deste livro eletrônico é totalmente livre para uso de qualquer natureza
desde que citado a fonte. Toda e qualquer parte desta publicação pode ser
reproduzida, distribuída ou transmitida de qualquer forma ou por qualquer meio, ou
armazenada de qualquer forma ou em qualquer sistema desde que reconhecida a
autoria.
O autor
e–mail: brauliro.leal@univasf.edu.br
site: www.univasf.edu.br/~brauliro.leal
Fonte: https://publicdomainvectors.org/photos/World-in-Hand-Small.png
Programação Básica com Linguagem C 4
Prefácio
Este livro tem como principal objetivo o de servir de texto para a disciplina de
Introdução à Programação do curso de Engenharia da Computação da Universidade
Federal do Vale do São Francisco.
Considerando que um programa de computador tem fundamento na lógica, é
impessoal, seus critérios são abstratos, generalizados e são dirigidos para a
resolução de problemas com vista a resultados objetivos.
Considerando que nosso cérebro, em especial o córtex cerebral, é "responsável
por descobrir padrões, raciocinar de modo lógico, prever o pior e preparar–se para
lidar com ele, criar tecnologia e transmiti–la através da cultura" (Suzana Herculano–
Houzel), este texto busca responder, para fins de aprendizagem, as questões:
• O que é algoritmo?
• O que é programa de computador?
• Como e quando usar os conceitos da linguagem de programação C.
• Como criar programas de computador para resolver problemas de engenharia.
valem muitas palavras. Também pode ser inspiração para outros programas.
Deixo aqui minhas antecipadas desculpas por eventuais erros neste texto, que
certamente existem, agradeço antecipadamente toda e qualquer correção ou
sugestão de melhoramentos, que deverão ser enviadas para o e–mail do autor.
Serão colocadas na página
http://www.univasf.edu.br/~brauliro.leal/page/feedback.htm as Errata, Críticas e
Sugestões recebidas.
Programação Básica com Linguagem C 7
Índice
1. Introdução...............................................................................................................................................11
1.1. Computador.....................................................................................................................................11
1.2. O Sistema Operacional....................................................................................................................16
1.3. Programação de Computadores.......................................................................................................17
1.4. Programação Estruturada................................................................................................................24
2. Linguagens de Programação...................................................................................................................26
3. Compiladores C.......................................................................................................................................31
4. Linguagem C...........................................................................................................................................35
4.1. Visão Geral......................................................................................................................................35
4.1.1. A Função main.........................................................................................................................36
4.1.2. Bloco de Comando..................................................................................................................36
4.1.3. Estrutura Sequencial................................................................................................................37
4.1.4. Funções de Entrada/Saída (E/S)..............................................................................................37
4.2. Tipos de Dados................................................................................................................................39
4.2.1. Modificadores de Tipo de Dado..............................................................................................40
4.2.2. Tipo void..................................................................................................................................41
4.2.3. Tipo char..................................................................................................................................41
4.2.4. Tipo int....................................................................................................................................42
4.2.5. Tipos float e double.................................................................................................................44
4.2.6. Estrutura dos Tipos Simples....................................................................................................45
4.2.7. Tipos Estruturados...................................................................................................................48
4.2.8. Tipos Apontador......................................................................................................................48
4.2.9. Exercícios................................................................................................................................49
4.3. Constantes.......................................................................................................................................49
4.4. Variáveis..........................................................................................................................................51
4.4.1. Declaração...............................................................................................................................52
4.4.2. Leitura e Escrita de Variáveis..................................................................................................53
4.4.3. Escopo de Variáveis................................................................................................................59
4.4.4. Classe de Armazenamento de Variáveis.................................................................................61
4.5. Expressões.......................................................................................................................................62
4.5.1. Operadores Aritméticos e Lógicos..........................................................................................62
4.5.2. Precedência e Associatividade de Operadores........................................................................64
4.5.3. Expressões Lógicas..................................................................................................................64
4.5.4. Expressões Aritméticas............................................................................................................66
4.5.5. Operador de Atribuição...........................................................................................................67
4.5.6. Abreviaturas do Comando de Atribuição................................................................................69
4.5.7. Transbordamento de Dados.....................................................................................................70
4.5.8. Promoção de Tipo de Dado em Expressões............................................................................70
4.5.9. Cast..........................................................................................................................................72
4.5.10. Funções Matemáticas............................................................................................................74
4.5.11. Gerando Dados de Entrada....................................................................................................75
4.5.12. Estrutura e Estilo...................................................................................................................75
4.5.13. Resumo..................................................................................................................................75
4.5.14. Exercícios..............................................................................................................................76
4.6. Estrutura Condicional......................................................................................................................78
4.6.1. Comando if/else.......................................................................................................................78
4.6.2. Comando Ternário (?:)............................................................................................................84
4.6.3. Comando switch......................................................................................................................85
4.6.4. Exercícios................................................................................................................................88
4.7. Estrutura de Repetição....................................................................................................................92
Programação Básica com Linguagem C 8
14.3. Fluxograma..................................................................................................................................250
14.4. Formatos de E/S..........................................................................................................................251
14.5. Portas Lógicas.............................................................................................................................253
14.6. Revisão de Matrizes....................................................................................................................258
14.7. Palavras Reservadas da Linguagem C........................................................................................261
15. Terminologias Úteis............................................................................................................................263
16. Bibliografia.........................................................................................................................................265
Programação Básica com Linguagem C 11
1. Introdução
1.1. Computador
Computadores são máquinas versáteis e permitem a execução de uma grande
1 Os termos linguagem natural, linguagem de programação, linguagem de máquina e programa executável possuem
definições mais rigorosa, estes aqui expressos são de ordem didática.
Programação Básica com Linguagem C 12
variedade de operações de acordo com suas capacidades. Por isso eles estão em
todos os lugares na sociedade moderna, onde as relações sociais podem ser
mediadas pela tecnologia, criando um mundo digital.
2 Fonte: https://locomotiva26.com.br/wp–content/uploads/2015/09/integracao–hardware–software–563x353.jpg
Programação Básica com Linguagem C 14
Um byte é composto por 8 bits e cada bit pode ser 0 ou 1. Dessa forma pode
haver 256 (28) formas de arranjar bits para formar bytes. Para facilitar ainda mais a
leitura e a escrita do código de máquina foi criado o Código ASCII (American
Standard Code for Information Interchange ou Código Padrão Americano para o
Intercâmbio de Informação).
O Código ASCII é binário e codifica um conjunto de 256 sinais: 95 símbolos
gráficos (letras do alfabeto latino, sinais de pontuação e sinais matemáticos) e 33
sinais de controle, Tabela 14.1 do Anexo. Outros 128 sinais compõem a parte
estendida deste código, Tabela 14.2 do Anexo.
A codificação ASCII é usada para representar textos em computadores,
Programação Básica com Linguagem C 15
Seguem exercícios.
Exemplo 1.3 Para representar nosso conhecimento usamos símbolos, leia este
texto.
50M05 53R35 QU3 49R3ND3 3 R39R353N74M05 N05505 C0NH3C1M3N705 90R
M310 D3 51M80L05. 4 M473M471C4 3 UM 6R4ND3 3X3M9L0, 70D05 C0NH3C3M
53U5 51M80L05 QU3 540 4D074D05 90R 70D45 45 CUL7UR45. 0 M35M0 V4L3
94R4 4 MU51C4, 05 51N415 D3 7R4N5170, 05 M4945, 05 1C0N35 D05
9R06R4M45 D3 C0M9U74D0R. 3 MU170 M415. 3NC0N7R3 V0C3 0U7R05
3X3M9L05. 3573 73X70 3574 35CR170 3M 51M80L05, N40 3 F4C1L D3 49R3ND3R
3 3N73D3R? 9R06R4M4R 74M83M U54 51M80L05 C0M0 3573, 3 MU170 F4C1L D3
49R3ND3R 74M83M.
Por enquanto, os algoritmos dos Exemplo 1.4 e Exemplo 1.5 não podem ser
transformados em Programa de Computador mas o Exemplo 1.6 pode.
Programação Básica com Linguagem C 18
Ouso afirmar que, de posse dos ingredientes, qualquer ser humano é capaz de
montar a citada cadeira a partir do algoritmo.
Ouso afirmar que, de posse dos ingredientes, qualquer ser humano é capaz de
fazer o citado bolo a partir do algoritmo.
Exemplo 1.6 Algoritmo para somar dois números usando uma calculadora comum.
Pode–se observar que pessoas e computadores são muito diferentes, mas eles
precisamento se comunicar, o que leva a necessidade de linguagens de
programação com diferentes níveis. Os processadores normalmente executam
instruções simples e elementares e usam linguagens de baixo nível – aquelas mais
próximas das linguagens de máquina. As linguagens de máquina são consideradas
difíceis de programar e, portanto, foram criadas as linguagens de alto nível para
tornar mais fácil a tarefa de programação de computadores.
Como computadores não podem fazer julgamentos e nem resolver
ambiguidades, as linguagens de programação devem ser capazes de comunicar
instruções de forma precisa. Em geral, elas são muito mais simples do que as
linguagens humanas, denominadas linguagens naturais.
As Linguagens de Programação foram criadas para comunicar instruções para
computadores. Elas possuem uma gramática e um dicionário que formam um
Programação Básica com Linguagem C 24
2. Linguagens de Programação
1. palavras reservadas
2. símbolos
3. regras para dar significado aos seus elementos, seus usos e combinações
Conforme pode ser visto na Figura 1.1, qualquer que seja a linguagem de
programação, ela deve ser capaz de produzir programas para gerenciar o fluxo de
controle nos Barramento de Dados, Endereços e Controle. Para isso, elas possuem
vários elementos que estão discutidos na Tabela 2.1.
De modo geral, os tipos básicos de dados são os literais, ponto fixo e ponto
flutuante.
Programação Básica com Linguagem C 27
4 Dividir para conquistar é uma técnica útil de resolução de problema, de origem militar; mas deve ser usada com cuidado
pois há muitos problemas que possuem sinergia entre suas partes e, nestes, o todo é maior que a soma de suas partes – e
esta técnica é de pouca utilidade.
Programação Básica com Linguagem C 29
decisões lógicas.
Uma estrutura de repetição pode executar várias vezes seu bloco de comandos.
Toda estrutura de repetição possui uma expressão (denominada condição) que,
quando avaliada, permite a decisão de executar ou não executar o bloco de
comandos programado.
As principais comandos para estruturas de repetição são: para e enquanto/faça e
faça/enquanto.
O comando para é usado para executar um número definido de repetições. Ele
possui um contador automático para este fim.
O comando enquanto/faça avalia sua condição e pode ou não executar seu bloco
de comandos, ou seja, ele pode executar seu bloco de comandos uma única vez,
nenhuma vez ou várias vezes.
O comando faça/enquanto avalia sua condição e executa seu bloco de comandos
ao menos uma vez, ou seja, ele pode executar seu bloco de comandos uma única
vez ou várias vezes.
O formato dos comandos das estruturas de repetição varia entre as linguagens de
programação.
Sub–Rotinas e Funções
As sub–rotinas são blocos de comandos que recebem um nome para identificá–la e
permitir seu uso. Dessa forma, as sub–rotinas permitem organizar um programa
em módulos, agrupando as tarefas repetitivas presentes no programa, deixa–o
melhor estruturado. Os módulos que retornam valor são denominadas funções,
caso contrário são denominados sub–rotinas.
Compiladores
Um compilador é um programa de computador que traduz um programa de uma
linguagem textual facilmente entendida por um ser humano para uma linguagem
de máquina, específica para um processador e sistema operacional.
O código original é denominado programa–fonte ou código fonte, em geral escrito
no formato texto e legível por seres humanos.
O código final é denominado programa executável ou código de máquina, em geral
escrito no formato binário que pode ser executados por um processador.
Como há variados tipos de processadores e sistemas operacionais, também há
vários compiladores para uma mesma linguagem de programação, um compilador
para cada combinação processador/sistemas operacional.
Interpretadores
Interpretadores são programas de computador que leem um código fonte de uma
linguagem de programação e o converte, em geral linha a linha, em código
executável.
Como há variados tipos de processadores e sistemas operacionais, também há
vários interpretadores para uma mesma linguagem de programação, um
interpretador para cada combinação processador/sistemas operacional.
Existem também, as linguagens de script, que são linguagens interpretadas,
executadas do interior de programas e de outras linguagens de programação como
em navegadores web.
Notas:
3. Compiladores C
declarações de funções, tipos de dados e macros 10. Ela é uma caixa de ferramentas
prontas para uso.
4. Linguagem C
11 Token ou componente léxico é uma cadeia de caracteres que tem um significado na linguagem de programação.
Programação Básica com Linguagem C 36
/* menor programa C */
int main( void ){
return 0;
}
Este programa tem a função main (obrigatória) que não recebe parâmetros
(indicado por void), retorna 0 (comando return) e não tem nem entrada/saída.
printf e scanf:
Exemplo 4.2 Programa simples para imprimir texto no vídeo (saída padrão –
stdout).
// macro para inclusão de recursos da Biblioteca Padrão
#include <stdio.h>
int main( void ){
printf( “Ola mundo!” );
return 0;
}
Tabela 4.1 Códigos para formatação das “strings de controle” das funções printf e
scanf
Código Descrição
\\ barra invertida
\’ apóstrofo
\" aspas
\0 nulo ou NULL
\a sinal sonoro
12 Default – configurações pré estabelecidas; pode ser entendido como configurações originais ou “de fábrica”.
Programação Básica com Linguagem C 39
\b retrocesso
\f alimentação de formulário
\n nova linha
\N constante octal (N é um número octal)
\r retorno de carro
\t tabulação horizontal
\v tabulação vertical
\xN constante hexadecimal (N é um número hexadecimal)
Os tipos de dados de uma linguagem de programação são recursos valiosos para
programadores.
Erros a Evitar
Ao copiar a sentença printf( “Ola mundo!” ); para um editor de
texto, pode dar erro de compilação.
Causa: as aspas duplas do editor (“”) de texto não são iguais às que a
Linguagem C usa, que são (""). Logo, as aspas da sentença precisam
ser trocadas, assim: printf( "Ola mundo!" );
Note a diferença! Detalhes, detalhes, …, que, para nós humanos, são
insignificantes.
O mesmo se aplica às aspas simples.
13 Tipos simples ou primitivos pois podem ser combinados para criar tipos de dados estruturados.
14 A Biblioteca Padrão incluiu o arquivo #include<stdbool.h> para implementar o tipo lógico bool. Ao declarar bool x, é criada
a variável x do tipo lógico, que pode assumir valores true ou false.
Programação Básica com Linguagem C 41
Tabela 4.3 Tipo char, tamanhos, faixas e formatos de E/S do tipo char e seus
modificadores
Tamanho Tamanho Faixa de Variação Formato
Tipo char
(b) (B) E/S
Programação Básica com Linguagem C 42
• Os tipos signed char e char são os mesmos tipos, o modificador signed é o default da
Linguagem C.
• Os modificadores short/long não se aplicam ao tipo char.
• O tipo char pode assumir valores inteiros com sinal na faixa {–128 a 256}.
• A Linguagem C pode tratar valores de tipos char como números ou como símbolos e,
dependendo dos valores, são os mesmos dos códigos ASCII.
• As operações matemáticas { + – * } são definidas para valores do tipo char podem
resultar em valores fora de sua faixa de variação, com resultados inesperados,
devendo ser usados como muito cuidado.
• Pode–se escrever valores de char utilizando as funções printf e scanf, os formatos
necessários estão na Tabela 4.3. O tipo char pode ser impresso como valores inteiros
(%d) ou como símbolos (%c).
• O computador utiliza os símbolos char para representar textos nos dispositivos de
saída mas, internamente, são tratados como números.
O tipo int não possui parte fracionária por isso são denominados de tipos de
ponto fixo.
Na Linguagem C, char é tratado como ponto fixo.
Tabela 4.4 Tipo int, tamanhos, faixas e formatos de E/S do tipo int da Linguagem C
Programação Básica com Linguagem C 43
• Os tipos int são chamados tipos de ponto fixo (os tipos char também são ponto fixo
se tratados como inteiros).
• Os tipos signed int e int são os mesmos tipos, o modificador signed é o default da
Linguagem C.
• O tipo long int pode ser abreviado para long.
• O tipo int pode assumir valores inteiros com sinal na faixa {–2 31 a 264–1}.
• As operações matemáticas { + – * / % } são definidas para valores do tipo int.
• O transbordamento de dados em operações com valores destes tipos é pouco
comum, devido à sua grande faixa de variação – mas pode ocorrer.
• A subtração envolvendo valores de tipo unsigned int resultar em transbordamento de
dados, com resultados inesperados, devendo ser usados como muito cuidado.
• Como na matemática, não há divisão por zero, cabendo ao programador cuidar para
evitá–las.
• A divisão entre inteiros tem como resultado outro inteiro, a parte fracionária é
perdida.
• Pode–se escrever valores int utilizando as funções printf e scanf, os formatos
necessários estão na Tabela 4.4.
• O computador utiliza o tipo unsigned int e também unsigned long int para
representar grandezas positivas ou nulas, como endereços de memória.
• Estes tipos são muito úteis em Matemática Discreta, uma grande área da
Computação.
• A Biblioteca Padrão possui muitas funções exclusivas destes tipos, facilitando seu
uso.
A divisão inteira tem suas peculiaridades, leia com atenção o texto Divisão
Inteira, abaixo.
Divisão Inteira
São duas as divisões inteiras, cujos símbolos são {/ %}, com resultados
mostrado abaixo:
Programação Básica com Linguagem C 44
Tabela 4.5 Tipo float e double, tamanhos, faixas e formatos de E/S do tipo int da
Linguagem C
Tamanho Tamanho Faixa de Variação Formato
Tipo
(b) (B) E/S
float 32 4 [±3.4E–38,±3.4E38] %f
double 64 8 [±1.7E–308,±1.7E308] %lf
long double 128 16 [±3.4E–4932,±3.4E4932] %Lf
Notas:
• Os tipos float, double e long double são chamados tipos ponto flutuante.
• Os tipos float, double e long double podem assumir uma grande faixa dos números
reais usados na Matemática.
• O tipo double é o default da Biblioteca Padrão e da Linguagem C.
• As operações matemáticas { + – * / } são definidas para valores destes tipos, e
também as funções matemáticas convencionais, como exponencial, trigonométricas,
potência e suas inversas.
• A operação { % } não é definida para estes tipos.
• O transbordamento de dados em operações com estes tipos é pouco comum, devido
à sua grande faixa de variação – mas pode ocorrer.
• Como na matemática, não há divisão por zero, cabendo ao programador cuidar para
evitá–las.
• A divisão entre tipos ponto flutuante tem como resultado outro tipos ponto flutuante,
o que inclui a parte fracionária.
• Pode–se escrever valores float e double utilizando as funções printf e scanf, os
formatos necessários estão na Tabela 4.5.
• O computador utiliza os tipos float, double e long double para cálculos de grande
precisão, notadamente em Cálculo Numérico, uma área com muitas aplicações.
• Em geral, os computadores realizam operações matemáticas por meio de
coprocessadores aritméticos, um dos componentes das modernas CPU’s.
• A Biblioteca Padrão possui muitas funções exclusivas destes tipos, facilitando seu
Programação Básica com Linguagem C 45
uso.
• char – a adição concatena variáveis char e não tem sentido subtrair, multiplicar e
dividir variáveis do tipo char se tratadas literalmente
• int e long int – a adição, subtração, multiplicação e divisão de variáveis int é como
se faz na matemática, mas a parte fracionária da divisão é perdida; os unsigned int e
unsigned long não assumem valores negativos, limitando as subtrações
• float e double – a adição, subtração, multiplicação e divisão destas variáveis é
como se faz na matemática com a precisão inerente a cada tipo
• int, long int, float e double – as operações permitidas com estes tipos não
possuem a precisão da matemática, todos eles têm limites inferiores e superiores
que limitam estas operações; por exemplo, não existe dízima periódica em
programas C porque mesmo os pontos flutuantes têm sua a parte fracionária
limitada pela precisão da máquina
A Figura 4.4 mostra a estrutura dos tipos da Linguagem C em escala, nela pode–
se observar a estrutura interna dos tipos char e int (com e sem bit de sinal, short,
unsigned e long) e também dos tipos float e double (com bit de sinal, expoente e
fração). O tipo long double não foi apresentado por ser muito grande.
Nesta figura, o tamanho dos tipos são dados em octetos, com a cor amarela
representa o bit de sinal, a cinza indica número inteiro, o azul refere–se ao
expoente e o verde à fração dos pontos flutuantes.
O sinal tem sempre o mesmo tamanho (1 bit), em que 0 representa o sinal
positivo e 1 o sinal negativo. O tamanho do expoente e da fração varia entre os
tipos float e double, devido à precisão numérica dos mesmos.
Em geral, float são de 7 dígitos, double de 15 dígitos e long double de 19 dígitos
de precisão. A precisão dos tipos ponto flutuante depende do compilador. O tipo
ponto flutuante (float, double e long double) são padrões internacionais,
regulamentados pelo IEEE 754–1985.
Programação Básica com Linguagem C 46
Figura 4.4 Tipos simples da Linguagem C com seus octetos e as cores indicando: a)
amarelo - bit de sinal, b) cinza - número inteiro, c) azul - expoente e d) verde –
fração
Erros a Evitar
#include <stdio.h>
int main(void){
#include <limits.h>
#include <float.h>
return 0;
}
Observe os formatos usados para cada um dos tipos (%e é formato para notação
científica).
Cada tipo de dados tem suas regras próprias, seus limites, suas
aplicações e, sobretudo, seu formato de E/S – é necessário
compreendê-los muito bem.
A Biblioteca Padrão possui muitas funções para cada tipo de dados,
fornecendo ferramentas úteis para a programação.
4.2.9. Exercícios
4.3. Constantes
Notas:
Além do uso de macro pode–se usar a palavra reservada const para declarar
constantes.
A sintaxe15 para declarações uma constante em C é:
#include <stdio.h>
#define PI 3.141592
#define LETRA ‘A’
const float RAIO = 2.172;
const int MIN = 0, MAX = 0;
const double SALARIO = 30000.00;
int main(void){
const int DUZIA = 12;
printf( "\n PI = %lf”, PI );
printf( "\n LETRA = %c” , LETRA ); // LETRA é tratada como
símbolo
printf( "\n LETRA = %d” , LETRA ); // LETRA é tratada como
número int
printf( "\n RAIO = %f” , RAIO );
printf( "\n MIN = %d” , MIN );
printf( "\n MAX = %d” , MAX );
printf( "\n SALARIO = %lf”, SALARIO );
printf( "\n DUZIA = %d” , DUZIA );
return 0;
}
MIN e MAX foram declaradas juntas, separadas por vírgula.
A vírgula é o separador de elementos de uma lista.
A constante DUZIA é dita local à função main e as demais são ditas globais do
programa.
PI e LETRA estam declaradas usando macro e as demais usam declaração const.
A macro não requer ponto e vírgula (e se usar dá erro de compilação).
A declaração const requer ponto e vírgula no final (e se não usar dá erro de
compilação).
Observe os formatos usados para imprimir cada uma das constantes. A constante
do tipo char pode ser impressa como símbolo ou como número, só depende do
formato usado.
São detalhes importantes que, para nós humanos, são insignificantes.
4.4. Variáveis
Conforme pode ser visto na Figura 1.1, os dados utilizados pelo computador são
armazenados locais da sua memória de trabalho. Dar nome a estes locais da
memória permite gerenciar o processamento de dados no computador.
Os locais não mudam mas os valores neles armazenados mudam conforme a
necessidade, ou seja, os valores variam. O conceito de variáveis está relacionado
aos locais da memória principal onde valores são armazenados.
Variável são instâncias armazenadas na memória cujos valores são utilizados
durante a execução de um programa.
Nota:
programa, Figura 4.5. Cada variável declarada tem sua própria região demarcada
na memória do computador – tecnicamente seu endereço de memória.
Figura 4.5 Esquema da associação entre nome de variável de tipo char e a sua
região da memória do computador.
4.4.1. Declaração
A sintaxe16 de declaração de uma variável em C é:
#include <stdio.h>
int main(void){
char c1, c2 = ‘A’, c3 = 65;
int i1, i2 = 3;
float f1, f2 = 4.0;
double d1, d2 = 5.0;
// imprimindo valores
printf( "\n c1 = %c” , c1 ); // sem valor inicial, impressão do
“lixo da memória”
printf( "\n c2 = %c” , c2 );
printf( "\n c2 = %d” , c2 );
printf( "\n c3 = %c” , c3 );
“lixo da memória”
printf( "\n i2 = %d” , i2 );
return 0;
}
As variáveis c2 e a3 possuem o mesmo valor pois, em ASCII, ‘A’ é o decimal 65.
Todas as variáveis são ditas locais à função main. Este programa não tem variável
global.
Foram declaradas duas variáveis de cada tipo de dado, uma sem valor inicial e a
outra com valor inicial. Veja que o tipo char permite valores iniciais da tabela
ASCII, podendo ser seus valores simbólico ou decimal. Vale lembrar que ‘A’ e o
decimal 65 em ASCII.
Variável que cujo valor é o chamado lixo de memória é de pouca ou nenhuma
utilidade uma vez que não pode produzir resultado confiável.
Observe os formatos usados para cada imprimir cada uma das variáveis. Variáveis
do tipo char pode ter valor inteiro ou literal e impressas como símbolo ou como
número, só depende do formato usado.
São detalhes importantes que, para nós humanos, são insignificantes.
Tanto o printf quanto o scanf escreve/lê mais de uma variável. A Figura 4.6
mostra o formato do printf que escreve o valor da hora. Este mesmo conceito se
aplica ao scanf.
Erros a Evitar
Ao executar este programa, digite dois números inteiros separados por vírgula e
tecle ENTER.
Exemplo 4.13 Programa C para leitura dos valores de variáveis do tipos simples e
seus modificadores. O programa foi organizado em quatro funções, para facilitar o
seu entendimento, a função main chama as demais.
#include <stdio.h>
void Bool( void ){
bool b;
printf( "\n" );
printf( "De um valor bool {0,1}:" );
scanf ( "%d" , &b );
printf( "Valor lido: %d" , b );
}
printf( "\n" );
printf( "De um valor char:" );
scanf ( "%c" , &c );
printf( "Valor lido: %c" , c );
printf( "\n" );
printf( "De um valor unsigned char:" );
scanf ( "%hhu" , &uc );
printf( "Valor lido: %hhu" , uc );
}
void Int( void ){
int i;
unsigned int ui;
short int si;
unsigned short int usi;
long int li;
unsigned long int uli;
printf( "\n" );
printf( "De um valor int:" );
scanf ( "%d" , &i );
printf( "Valor lido: %d" , i );
printf( "\n" );
printf( "De um valor unsigned int:" );
scanf ( "%u" , &ui );
printf( "Valor lido: %u" , ui );
printf( "\n" );
printf( "De um valor short int:" );
scanf ( "%hd" , &si );
printf( "Valor lido: %hd" , si );
printf( "\n" );
printf( "De um valor unsigned short int:" );
scanf ( "%hu" , &usi );
printf( "Valor lido: %hu" , usi );
printf( "\n" );
printf( "De um valor long int:" );
scanf ( "%ld" , &li );
Programação Básica com Linguagem C 58
printf( "\n" );
printf( "De um valor unsigned long int:" );
scanf ( "%lu" , &uli );
printf( "Valor lido: %lu" , uli );
}
printf( "\n" );
printf( "De um valor float:" );
scanf ( "%f" , &f );
printf( "Valor lido: %f" , f );
printf( "\n" );
printf( "De um valor double:" );
scanf ( "%lf" , &d );
printf( "Valor lido: %lf" , d );
printf( "\n" );
printf( "De um valor long double:" );
scanf ( "%Lf" , &ld );
printf( "Valor lido: %Lf" , ld );
}
int main( void ){
Bool();
Char();
Int();
Float();
return 0;
}
Nas funções, exceto main, são declaradas uma variável de cada tipo e seus
modificadores, em seguida é feita a leitura de stdin e escrita em stdout. Estes
exemplos servem de modelos para outros programas com E/S.
Programação Básica com Linguagem C 59
Sintaxe para declarar uma string de nome str e tamanho 25 e valor inicial
“valor inicial de str”:
Parâmetro
• São variáveis locais da função
Formal
• São variáveis declaradas fora dos blocos das funções
Variável • São acessíveis a todo programa a partir do ponto em que foi
Global declarada, podendo ser usadas e modificadas a partir daí
• Existem durante toda a execução do programa
}
}
}
declaração da variável
l) foi declarada em outro arquivo.
4.5. Expressões
O propósito de uma expressão é especificar um valor a ser calculado.
Exercício 4.1 A figura abaixo possui 10 (10) regiões. Denominadas R1, R2, …, R10.
Considere que R10 contém todas as outras regiões. Escreva expressões lógicas
para representar as sentenças abaixo:
1. R1
2. R10 + R1
3. R1 + R2 – R4
4. R2 + R3 + R4 + R5
a d = (a/b)*c;
d= ×c
b
a c e = a/b + c/d;
e= +
b d
a e = (a/b – c)/d;
−c
b
e=
d
a mod b−c e = (a % b – c)/d;
e=
d
É uma boa prática testar expressões aritméticas para verificar se foram codificadas
corretamente.
O operador de atribuição (=) define dois lados, o lado à sua direita e o lado à sua
esquerda. O seu significado não é o de igualdade matemática entre os dois lados.
lado esquerdo. O valor que o lado esquerdo possuía, antes da atribuição, é perdido,
dando lugar ao valor do lado direito.
No caso do comando z = x + y temos a variável z, x e y são regiões na
memória da máquina do tamanho do tipo float. Na região correspondente a x foi
escrito o valor 10.0. Na região correspondente a y foi escrito o valor 20.0. A região
correspondente a z permanece sem valor inicial17. Para avaliar a expressão x + y, a
CPU busca os valores destas variáveis na memória principal, faz a soma das duas e
obtém o valor 30.0. O lado direito tem valor igual a 30.0 e está guardado na CPU.
Em seguida a CPU escreve o valor 30.0 na região de memória de nome z, ou seja, a
CPU atribui o valor 30.0 ao nome z.
variavel = expressao
A variável pode ser char, int, float ou outro tipo válido. A expressão pode ser
lógica ou aritmética ou mista.
O operador de atribuição divide uma expressão em dois lados, o lado esquerdo e
o lado direito. O lado esquerdo do operador de atribuição (=) é chamado de lvalue,
e o lado direito é denominado rvalue.
lvalue = rvalue
lvalue – denominação do lado esquerdo do operador de atribuição
rvalue – denominação do lado direito do operador de atribuição
O lvalue não podem ser constante porque a atribuição modifica o seu valor,
ocorre escrita na memória RAM.
O lvalue é uma variável para que possa ter seu valor modificado, pois o
operador de atribuição requer escrita na memória RAM.
O rvalue podem ser ou conter constantes e/ou variáveis porque seus valores não
são alterados, são apenas usados, ocorre apenas leitura da memória RAM.
Os rvalues devem possuir valores válidos para que os lvalues correspondentes
sejam válidos.
Na programação tem uma regra: entra lixo, sai lixo.
Como bons profissionais, essa regra tem que mudar para: entra lixo, sai um
aviso que entrou lixo.
Acostumem–se a verificar se os valores iniciais dos rvalues foram atribuídos ou
17 O valor da variável z é desconhecido pelo programador mas a região da memória associada a esta variável possui 0s e 1s,
usualmente chamado lixo da memória.
Programação Básica com Linguagem C 69
lidos.
S=S*x S *= x
S=S/x S /= x
As abreviações do comando de atribuição são opcionais.
A ordem importa, x = i++ é diferente de x = ++i:
4.5.9. Cast
Como já visto, a divisão de dois números inteiros retorna um número inteiro.
int a = 9, b = 5;
float c;
c = a/b;
c = float(a)/b;
ou
c = a/float(b);
c = float(a)/float(b);
Exercício 4.3 Faça um programa para avaliar o cast de: char → int → float → double.
Exercício 4.4 Faça um programa para avaliar o cast de: char → int → float → double,
incluindo os tipos unsigned
Exercício 4.5 Faça um programa para avaliar o cast de: char → int → float → double,
incluindo os tipos unsigned, short e long.
Protótipos:
4.5.13. Resumo
Programação Básica com Linguagem C 76
4.5.14. Exercícios
√
3+ 4+
2 +n 2 3
(x 1−m) +( x2−m) +(x 3−m)
u=
n
3+
3
2
1 x−m
1 − ( )
f= e 2 s
√2π s²
x
−
a−1 b
x e
f= a b
b +a
b
x
−( )
b−1 a
bx e
y= b
a
Programação Básica com Linguagem C 77
p−1 q−1
v (1−v )
z= p+ q
(1+ v)
b
x
−( )
b−1 a
bx e
g= b
a
q2 3 q
x=
−b
3a
2
+
1+
4
2a
R2
R1
√
+p −
3
4
√ 2
V 2=V 1 ( )
1 R2
+ +1
G GR 1
(−1)n 2 n−1
y= 2 n+1
( x+ y)
(2n−1)
2. Entrar com valores para a, b, c, imprimir o valor de x, sabendo–se que
b
x=a+ −2×(a−b−c) .
a+ b
3. Entrar com valores para a, b, c, d, imprimir o valor de f, sabendo–se que
f=
√cos (a)+ sen(b) .
ec −ln (d)
4. Entrar com valores para a, b, c, imprimir o valor de x, sabendo–se que
2
−b− √ b −4 ac
x= .
2a
5. Entrar com valores para m, s, x, imprimir o valor de f, sabendo–se que
2
1 x−m
1 − ( )
f= e 2 s
.
√2 π s ²
6. Embora por lei não possa obrigar o cliente a pagar gorjeta. Fazer um algoritmo que
leia o valor da despesa realizada em um restaurante e imprima o valor total com a
gorjeta.
7. Alguns tributos usa a base de cálculo salário–mínimo. Fazer um algoritmo que leia o
valor do salário–mínimo e o valor do salário de uma pessoa. Calcular e imprimir
quantos salários–mínimos ela ganha.
8. Preencha o quadro abaixo com a expressão lógica correspondente em C:
#include <stdio.h>
int main( void ){
int x;
printf( "Digite um numero inteiro: " );
scanf( "%d", &x );
if( x % 2 == 0 ){
printf("numero lido e par" );
}
else{
printf("numero lido e impar" );
}
return 0;
}
o valor padrão que é igual a 18, para isso utiliza–se o comando if, como abaixo
indicado.
#include <stdio.h>
int main( void ){
int idade;
printf( "Digite a idade do cidadao brasileiro em anos: " );
scanf( "%d", &idade );
if( idade >= 18 ){
printf(" o cidadao e de maior" );
}
else{
printf(" o cidadao e de menor" );
}
return 0;
}
O comando if pode ser aninhado. Pode–se ter if dentro de if, permitindo tomar
decisões complexas.
Basta declarar uma variável para receber o valor do número inteiro, seja x o nome
desta variável.
Ler o valor de x do teclado e avaliar a expressão (x % 3 == 0 || x % 4 == 0 ) && !
( x % 5 == 0) e decidir, como o programa abaixo.
#include <stdio.h>
int main( void ){
int x;
printf( "Digite o valor de x: " );
scanf( "%d", &x );
if( (x % 3 == 0 || x % 4 == 0 ) && !( x % 5 == 0) ){
printf(" %d e multiplo de 3 ou 4 mas nao de 5", x );
}
else{
printf(" %d nao e multiplo de 3 ou 4 mas nao de 5", x );
}
return 0;
}
Teste bem esta solução para verificar se ela não tem algum erro de lógica!
x k∗x
Matematicamente, os valores de w= e z= são iguais, logo
k k∗k
w−z=0 .
Mas como os tipos de dados da Linguagem C são limitados pela precisão da
máquina, o cálculo computacional de w-z = -0.000000000000000028; como
w-z != 0, programa vai escrever na tela: diferente de zero.
Seja um double, por exemplo x, para saber se x == 0.0 é melhor não compará-
los. Para contornar este problema, pode-se verificar se fabs(x) > 0.0. O valor fabs(x)
é positivo ou nulo. Se x for muito pequeno, pode ser muito pequeno positivo ou
muito pequeno negativo. A condição fabs(x) > 0.0 indica se x é exatamente 0.0 ou
não.
switch( seletor ){
case valo1 : <bloco de comandos da opção 1>
break;
case valo2 : <bloco de comandos da opção 2>
break;
...
case valon : <bloco de comandos da opção n>
break;
default : <bloco de comandos do default>
}
A Figura 4.11 ilustra o comando witch.
Exemplo 4.31 Identifica o nome do dia da semana a partir do seu número, usando
switch.
#include <stdio.h>
int main( void ){
int dia;
printf( "Digite um valor de 1 a 7: " );
scanf( "%d", &dia );
switch( dia ){
case 1 : printf("domingo");
break;
case 2 : printf("segunda–feira");
break;
case 3 : printf("terca–feira");
break;
case 4 : printf("quarta–feira");
break;
case 5 : printf("quinta–feira");
break;
case 6 : printf("sexta–feira");
break;
case 7 : printf("sabado");
break;
default: printf("dia invalido");
}
return 0;
}
Ao encontrar o comando switch, o programa executará o comando que for igual a
valor da variável dia corresponde ao de alguma constante do case, o comando
break encerra o switch. Caso contrário será executado o comando default que é o
printf("dia invalido") e encerra o switch.
Cada comando case do switch deve ser encerrado pelo break. O comando default
não possui break, e deve ser o último do switch.
Sempre alguma opção de switch é selecionada, na falta de opções validas, o
default é executado – corresponde ao nosso Plano B.
O comando switch por ser escrito usando if/else compostos aninhados, como
mostrado do Exemplo 4.32.
Exemplo 4.32 Identifica o nome do dia da semana a partir do seu número, usando
if/else compostos aninhados.
#include <stdio.h>
int main( void ){
int dia;
Programação Básica com Linguagem C 87
}
O código deve ser escrito com cuidado para evitar divisão por zero. O programa
testa se o valor absoluto do denominador é maior do zero.
Como o denominador é do tipo float, a expressão if( b == 0.0 ) pode ser usada
mas a if( fabs(b) > 0.0 ) é mais segura.
Nas implementações acima, o seletor do switch é do tipo char.
Para ler um valor char corretamente usando scanf é necessário incluir um espaço
antes de %c – scanf( " %c", &op ) – isto se deve ao fato de que a tecla ENTER é
tratada como caractere e qualquer ENTER deve ser ignorado.
O \b no formato do printf faz o computador emitir um beep (se o alto–falante
estiver funcionando e ligado).
4.6.4. Exercícios
Dados de entrada: X, Y, Z, H e R.
Dados de saída: C e Q.
Relações úteis:
a) custo é dado por quantidade de latas*X
b) quantidade de latas é dada por quantidade total de litros/Y
c) a quantidade total de litros é dada por área do cilindro/Z
d) área do cilindro é dada por área da base + área lateral
e) área da base é (PI*R2)
f) a área lateral é altura*comprimento: (2*PI*R*H)
g) PI é uma constante de valor conhecido: 3,141592
Fonte: http://thiagoccampos.blogspot.com/2012/03/construa–um–algoritmo–que–calcule.html
Conforme definido, a Páscoa deve ser celebrada no domingo seguinte à primeira lua cheia da
Primavera (na Europa). Gauss desenvolveu uma regra prática para calcular a data da Páscoa no
calendário gregoriano, a partir de 1583.
Considere A como sendo o ano, e m e n dois números que variam ao longo do tempo de acordo
com a seguinte tabela:
Ano Valores
1583–1699 m=22, n=2
1700–1799 m=23, n=3
1800–1899 m=23, n=4
1900–2099 m=24, n=5
2100–2199 m=24, n=6
Considere também:
Observações:
b) O dia 25 de abril deve ser substituído por 18 de abril se d=28, e=6 e a>10.
Faça um programa em C para calcular a páscoa de qualquer ano no intervalo de 1583 a 2199.
Fonte: http://www.somatematica.com.br/mundo/pascoa.php
Na figura abaixo, a posição inicial do cavalo é d4, e ele pode se mover para as
seguintes casas: f5, f3, e6, e2, c6, c2, b5 ou b3.
Fonte: https://sites.google.com/site/tecprojalgoritmos/problemas/Passeio–do–cavalo
printf("\n");
switch( regiao ){
case 'L': printf("Vendedores são: Rafael, João e Maria\n");
printf("Informe a primeira letra do vendedor: ");
vendedor = toupper( getche() );
printf("\n");
switch( vendedor ){
case 'R': printf("Vendas: R$%d\n",10000); break;
case 'J': printf("Vendas: R$%d\n",12000); break;
case 'M': printf("Vendas: R$%d\n",14000);
}
break;
case 'O': printf("Vendedores são:Ronaldo, Lisa e Hilton\n");
printf("Informe a primeira letra do vendedor: ");
vendedor = toupper( getche() );
printf("\n");
switch( vendedor ){
case 'R': printf("Vendas: R$%d\n",10000); break;
case 'L': printf("Vendas: R$%d\n",9500 ); break;
case 'H': printf("Vendas: R$%d\n",13000);
}
break;
case 'N': printf("Vendedores são: Tomás, João e Raquel\n");
printf("Informe a primeira letra do vendedor: ");
vendedor = toupper(getche());
printf("\n");
switch( vendedor ){
case 'R': printf("Vendas: R$%d\n",5000 ); break;
case 'J': printf("Vendas: R$%d\n",9000 ); break;
case 'T': printf("Vendas: R$%d\n",14000);
}
break;
}
return 0;
}
Exercício 4.21 Faça um fluxograma do Exercício 4.20.
Estas estruturas executam uma ou mais instruções reiteradas vezes até que a
condição seja falsa. Eles permitem que programas executem um bloco de
instruções sem precisar escrevê–lo várias vezes. Eles fazem uso da condição como
um critério de parada ou de continuação, a verificar seu valor booleano antes de
iniciar a execução do bloco de comandos ou após a execução do mesmo.
A Figura 4.12 mostra o fluxograma de uma estrutura de repetição. Esta figura
mostra que o fluxo de controle, ao avaliar a condição como verdade, executa o
bloco de comando, retornando novamente à condição para avaliá–la e se ela for
verdadeira, o bloco de comando é executado. Este ciclo se repete até que, no bloco
de comando, a condição mude para false e assim, ao avaliar a condição novamente,
o fluxo de controle vai para o próximo comando.
Ele deve se usado sempre que se souber, de antemão, quantas vezes o bloco de
comandos deverá ser executado.
Observe na Figura 4.13 que o comando valor inicial é executado uma única
vez; e também que a estrutura de repetição for pode não ser executado, ou seja,
ele pode ser executado zero vezes ou mais.
O programa é inciado pela função main. Nela é declarada uma variável int
contador, para ser usado como contador do laço (não há necessidade de atribuir
um valor inicial para esta variável).
O programa executa o laço for em seguida.
No primeiro comando do laço (contador = 1) é atribuído o valor inicial do contador.
O laço for executa este comando uma única vez.
O segundo comando do laço é a condição de parada. Neste caso, a condição de
parada é contador < 5. Como o valor de contador é 1, a condição é true. Sendo
assim, o bloco é executado. O bloco possui apenas o comando de impressão na
tela, o valor do contador (1) é impresso na tela do computador.
Na sequência, é executado o terceiro comando do laço, o incremento. Neste caso,
o incremento é de 1 e o novo valor da variável contador é 2.
Após executar o terceiro comando do laço for, ele passa para o seu segundo
comando, a condição de parada. Como contador é igual a 2 que é menor do 5, a
condição de parada é true. Sendo assim, o bloco é executado, imprimindo o valor 2
na tela.
O laço for incrementa o contador, contador = 3. A condição 3 < 5 é true. O laço
executa o bloco – imprime 3 na tela.
O laço for incrementa o contador, contador = 4. A condição 4 < 5 é true. O laço
executa o bloco – imprime 4 na tela.
Programação Básica com Linguagem C 97
Esta solução é genérica, se for necessário imprimir mais vezes basta substituir o
valor 5 pela quantidade desejada.
Programação Básica com Linguagem C 98
int i;
for( i = 0; i <= 100000; i++ ){
printf( "\n %d ", i );
if( i % 2 == 0 ) printf( " par" );
}
return 0;
}
(a) (b)
Figura 4.14 Fluxograma para: a) contar de 0 até N–1; b) somar N–1 valores lidos e
imprimir o resultado.
Será necessário declarar o int c para contador do laço for e também a constante
MAX com valor 7, número de idade medidas que deverão ser lidas no laço for.
Dentro do laço for serão colocados os comandos conforme a Tabela 4.17.
Ao sair do laço for, serão impressos os valores Imin, Imax e S/n, a idade média.
#include <stdio.h>
#define MAX 7
int main( void ){
int idade, n, Imin, Imax, c;
float S;
n = 0;
Imin = 1000;
Imax = 0;
S = 0.0;
return 0;
}
Não foi atribuído um valor inicial para leitura pois seus valores são dados de
entrada para o programa.
Pode–se criar a variável float de nome m e, depois do laço for, colocar o comando
m = S/n e imprimir o valor de m.
É conveniente que valores de média sejam do tipo float pois são obtidos por meio
da operação de divisão, cujo valor esperado são números fracionários.
Observe que foi criado um pequeno dicionário com as varáveis do programa, seus
tipos e valores iniciais. E, o mais importante, a finalidade de cada uma delas, as
operações a realizar com cada uma delas e onde colocar cada comando a elas
referentes. Isso tudo antes de começar a digitar o programa de computador.
No início, o acadêmico fica um pouco confuso com estes procedimentos mas, ao
Programação Básica com Linguagem C 103
(a) (b)
Figura 4.15 Fluxograma para: a) calcular a média de N–1 valores lidos e imprimir o
resultado; b) obter o máximo de N–1 valores lidos e imprimir o resultado.
4.7.3. Exercícios
1. Faça um programa para ler imprima N = 22 vezes a frase "Alo mundo!" usando
estrutura sequencial e a estrutura de repetição for. Como seria este programa se N =
222?
2. Faça um programa para ler um número inteiro positivo e informar se ele é triangular.
Um número natural n é triangular se é igual à soma dos k primeiros números
naturais consecutivos, a partir de 1. Por exemplo, 10 = 1 + 2 + 3 + 4 é triangular.
3. Foi feita uma estatística de cinco turmas de Linguagem C, da Univasf, para verificar a
aprendizagem dos estudantes. Foram obtidos os seguintes dados:
• código da turma
• número de estudantes por turma
• número de estudantes com nota maior do que 7.0
Deseja–se saber:
a) qual é a média das notas, das cinco turmas juntas
b) qual é a média das notas menores ou iguais a 7.0, das cinco turmas juntas
c) qual é a média das notas maiores do que 7.0, de cada turma
4. Faça um programa que receba duas notas de seis estudantes da Univasf. Calcule e
mostre:
a) a média de cada estudante
Programação Básica com Linguagem C 105
saldo inicial e dez lançamentos de operações de crédito e/ou débito. A saída são o
total de créditos, o total de débitos, os juros pagos ao banco (5% do total de débitos)
e o saldo final.
12.Execute este programa e explique seu comportamento.
#include <stdio.h>
int main ( void ){
char c;
for( c = 0; c < 300; c++ ){
if( c % 16 == 0 ) printf("\n");
printf(" %+3c ", c );
}
return 0;
}
#include <stdio.h>
int main ( void ){
int i;
for( i = 0; i < 120; i++ ){
if( i % 16 == 0 ) printf("\n");
printf(" %+3c ", i );
}
return 0;
}
* * ************* ************* 1 2 3 4 5 6 7
** *** * * 2 3 4 5 6 7
*** ***** ************* ************* 3 4 5 6 7
**** ******* * * * 4 5 6 7
***** ********* ************* ************* 5 6 7
****** *********** * * * 5 6
******* ************* ************* ************* 6
(a) (b) (c) (d) (e)
7 # # # # # # # | # # # # # # # 7 | 7
7 6 # # # # # # | # # # # # # 7 6 | 6 7
7 6 5 # # # # # | # # # # # 7 6 5 | 5 6 7
7 6 5 4 # # # # | # # # # 7 6 5 4 | 4 5 6 7
7 6 5 4 3 # # # | # # # 7 6 5 4 3 | 3 4 5 6 7
7 6 5 4 3 2 # # | # # 7 6 5 4 3 2 | 2 3 4 5 6 7
7 6 5 4 3 2 1 # | # 7 6 5 4 3 2 1 | 1 2 3 4 5 6 7
(f) (g) (h)
Programação Básica com Linguagem C 107
O laço while é uma estrutura de repetição muito utilizada nos programas C. Ele
deve se usado sempre que não se souber de antemão quantas vezes o bloco de
comandos deverá ser executado. O laço while repetirá seu bloco de comando
enquanto uma condição for verdadeira.
Este laço possui:
while( condição ){
comando;
...
comando;
}
onde:
Observe que, para que seja possível fazer o teste, a variável de controle deve
ter sido declarada e inicializada previamente pois o teste da condição ocorre no
início do laço.
A condição de parada pode ser uma expressão lógica, cujo resultado deve ser
FALSO ou VERDADEIRO. Nestes casos, as variáveis que compões a expressão usada
como condição de parada devem ter sido declaradas e inicializadas previamente
pois o teste da condição ocorre logo no início do laço.
Enquanto a condição permanecer VERDADE o laço while executará seu laço. De
alguma forma, o bloco deve mudar a condição de VERDADE para FALSO para que o
laço while seja encerrado.
Exemplo 4.42 Estrutura de repetição while com condição lida do teclado – ler e
imprimir números inteiros positivos lidos do teclado, o valor 0 (zero) encerra as
leituras.
Números inteiros devem ser lidos do teclado e impressos na tela enquanto seus
valores forem diferentes de zero.
O programa é resolvido com o laço while pois não se sabe o número de repetições
a serem feitas.
A condição de parada é dada pelo usuário.
O algoritmo é simples, inicialmente o primeiro número deve ser lido do teclado,
antes de entrar no laço.
O algoritmo entra no laço e verifica se o valor do número é igual a 0. Se for encerra
e nada é impresso. O programa é encerrado.
Se o primeiro valor lido é diferente de 0, o programa entra no laço, imprime o valor
do número na tela. Lê um novo valor do teclado e testa a condição. O laço while
será repetido indefinidamente até que o valor lido seja 0.
Observe que a condição de parada do while utiliza o valor lido do teclado e, por
isso, são necessário dois comandos de leitura. O primeiro, antes do laço while,
para que ele tenha com o que testar sua condição de parada. O segundo, dentro
do laço while, para que ele atualize o valor lido porque senão ele entra em loop –
laço eterno.
#include <stdio.h>
int main( void ){
int numero;
while( contador == 0 ){
printf("\n O numero digitado foi %d ", numero );
printf("\n Digite um número inteiro positivo " );
scanf("%d", &numero );
}
return 0;
}
numero = 0;
conta = 0;
Soma = 0;
return 0;
}
Programação Básica com Linguagem C 111
Exemplo 4.44 Somar números inteiros e positivos lidos pelo teclado enquanto o
total for menor do que 100.
#include <stdio.h>
int main( void ){
int numero, conta, Soma;
conta = 0;
Soma = 0;
return 0;
}
Exemplo 4.45 Calcule a soma de números inteiros e positivos lidos pelo teclado.
#include <stdio.h>
int main( void ){
conta = 0;
Soma = 0;
while( numero != 0 ){
conta = conta + 1;
Soma = Soma + numero;
return 0;
}
4.7.6. Exercícios
ser as opções:
• Candidato 1
• Candidato 2
• Candidato 3
• Candidato 4
• Candidato 5
• Nulo
• Branco
• Entre com o seu voto:
O programa deverá ler os votos dos eleitores e, quando for lido o número 8,
apresentar as seguintes informações:
a) o número de votos de cada candidato
b) a porcentagem de votos nulos
c) a porcentagem de votos brancos
d) o candidato vencedor.
A condição de parada pode ser uma expressão lógica, cujo resultado deve ser
FALSO ou VERDADEIRO. Nestes casos, as variáveis que compões a expressão usada
como condição de parada devem ter sido declaradas e mas não é necessário
inicializá–las previamente pois o teste da condição ocorre no final do laço.
No algoritmo abaixo, o laço do/while é repetido indefinidamente até que seja lido
0 do teclado.
#include <stdio.h>
int main( void ){
char op;
do{
Programação Básica com Linguagem C 115
Observe que o laço do/while é executado ao menos uma vez, como a variável op
é lida dentro do laço é desnecessário dar um valor inicial a ela, Figura 4.18.
R2
1+
V out R1
=
V iin 1 R 2
+ +1
G GR 1
4.7.8. Exercícios
1. Faça um programa que leia números inteiros não-nulos do teclado e calcule a soma e
Programação Básica com Linguagem C 118
Figura 4.19 Efeito do comando break nos laços de repetição for, while e do/while.
O comando continue ignora todos os comandos abaixo dele e volta ao for, while
ou do/while, como ilustrado na Figura 4.20.
Figura 4.20 Efeito do comando continue nos laços de repetição for, while e do/while.
4.7.10. Resumo
4.8. Funções
Quando os programas C tornam–se maiores e mais complexos, pode–se
melhorar sua clareza e compreensão dividindo–o em partes menores, denominadas
funções.
Funções é uma forma de reutilização de código, ou seja, escreve o código
apenas uma vez e use quantas vezes for necessário. A de reutilização de código é
uma boa prática de programação pois evita retrabalho, aumentando a eficiência da
programação.
Sintaxe da função:
O tipo de retorno das funções podem ser void (a função não tem return), char,
bool, int, float, double e seus derivados. O mesmo é válido para a lista de
parâmetros formais; void indica que a função não recebe parâmetros, pode ter um
ou mais parâmetros de tipos de dados válidos, separados por vírgula. Uma função
pode receber parâmetros de diversos tipos.
1. 1. O comando s = SomaInt(a,b) precisa ser avaliado, mas ele contém uma função,
Programação Básica com Linguagem C 121
logo ela deve ser avaliada primeiramente. Neste ponto o programa faz a chamada
da função SomaInt passando os argumentos (5,7).
2. 2. O fluxo de controle é transferido para a função e SomaInt e ela atribui os valores
(5,7) para seus parâmetros. Ela processa todos os seus comandos até encontrar o
comando return 12, o valor de soma.
3. 3. O fluxo de controle é transferido para o programa com o resultado 12.
4. 4. O programa substitui SomaInt pelo resultado e atribui 12 a s, ou seja, s = 12 e
passa para o próximo comando.
1. Ao encontra uma função, o programa faz a chamada desta função passando seus
argumentos
2. O fluxo de controle é transferido para a função; ela atualiza seus parâmetros com os
argumentos recebidos e processa os seus comandos até encontrar o comando
return.
3. O fluxo de controle é transferido para o programa com o resultado do return.
4. O programa atribui o resultado ao nome da função e passa para o próximo comando.
return 0;
}
As variáveis a, b, o vetor R e a matriz S são globais, são acessíveis em qualquer
lugar do programa, abaixo de suas declarações.
A função main faz uso de a e b como argumentos para a função Soma.
A função Soma possui dois parâmetros: x e y.
A função Soma possui três variáveis locais: x, y e s.
A função main, ao chamar Soma, envia os valores de a e b como argumentos. O
SO cria Soma na Stack e os parâmetros x e y para receber os valores de a e b. Os
comandos do corpo da função são executados e, ao encontrar return s, o SO faz
uma cópia do valor de s e envia para main. O SO destrói Soma e tudo a ela
relacionado. A função main recebe a cópia de s e envia para a função printf.
Vale ressaltar que os valores de a e b são podem ser alterados pela função pois ela
recebeu uma cópia dos valores de a e b. É o denominado passagem de
argumentos por valor.
A função Soma pode fazer operações com as variáveis a, b, R e S, que são globais.
4.8.2. Recursividade
Diz que uma função é recursiva quando ela chama a si mesma, direta ou
indiretamente.
Muitos problemas complexos como, por exemplo, ordenação e busca em textos, a solução
é inerente recursiva e a solução iterativa pode não existir ou ser difícil de ser encontrada.
Exemplo 4.51 As funções fat e Fib, para calcular fatorial e a série de Fibonacci,
respectivamente, são funções recursivas pois elas chamam a si mesmas.
int fat(int n){
Programação Básica com Linguagem C 124
if( n == 0 ) return 1;
else return n*fat(n–1);
}
int Fib(int n){
if( (n == 0) || (n == 1) ) return n;
else return Fib(n-2)+Fib(n-1);
}
Uma função recursiva pode ser reescrita com o uso de iteração, e vice–versa. O
exemplo a seguir calcula a soma de um vetor de forma recursiva.
Exemplo 4.54 O jogo conhecido como Torre de Hanói consiste de três torres
chamadas origem, destino e auxiliar e um conjunto de n discos de diâmetros
diferentes, colocados na torre origem na ordem decrescente dos seus diâmetros. O
objetivo do jogo e, movendo um único disco de cada vez e não podendo colocar
um disco sobre outro de diâmetro menor, transportar todos os discos para torre
destino, podendo usar a torre auxiliar como passagem intermediaria dos discos.
#include <stdio.h>
Maneira 1 Maneira 2
T1 = 1 T1 = 1
T2 = 1+2 T2 = T1 + 2
T3 = 1+2+3 T3 = T2 + 3
T4 = 1+2+3+4 T4 = T3 + 4
··· ···
Tn = 1 + 2 + 3 + ··· + n-1 + n Tn = Tn-1 + n
A Maneira 1 é chamada de solução interativa, basta a última equação.
A Maneira 2 é chamada de solução recursiva, a última equação depende da
equação anterior, e assim por diante, até T1 = 1, que não tem antecedente.
Pode-se elaborar dois algoritmos, com diferentes técnicas, para resolver o
mesmo problema. A técnica interativa (Algoritmo da Maneira 1) usa a estrutura de
repetição for como solução. A técnica recursiva (Algoritmo da Maneira 2) usa a
recursividade como solução. O mesmo problema, duas soluções.
4.8.5. Resumo
4.8.6. Exercícios
1. Faça uma função que receba um número inteiro e positivo N como parâmetro e
retorne a soma dos números inteiros existentes entre o número 1 e N (inclusive).
2. Crie uma função que receba três números inteiros como parâmetros, representando
horas (h), minutos (min) e segundos (s), e os converta em segundos. Exemplo: 2 h,
40 min e 10 s correspondem a 9.610 s.
3. Faça uma função que receba um valor inteiro e verifique se ele é positivo ou
negativo.
4. Crie uma função que receba como argumento a altura (h) e o sexo de uma pessoa e
retorne seu peso ideal. Para homens, deverá calcular o peso ideal usando a fórmula:
peso ideal = 72.7 h − 58; para mulheres: peso ideal = 62.1 h − 44.7.
5. Elabore uma função que leia um número não determinado de valores positivos e
retorne a média aritmética desses valores. Terminar a entrada de dados com o valor
zero.
6. Faça uma função que receba um valor inteiro e positivo, calcule e mostre seu
fatorial.
7. Elabore uma função que receba como parâmetro um valor n (inteiro e maior ou igual
a 1) e determine o valor da soma S = 1 +1/2 + 1/3 + … + 1/n.
8. Faça uma função que receba como parâmetro um valor inteiro e positivo n,
indicando a quantidade de parcelas de uma soma S, calculada pela fórmula: S = 1/3
+ 2/4 + 5/5 + 10/6 + 17/7 + 26/8 + ··· + (n2+1)/(n+3).
9. Foi realizada uma pesquisa entre 15 habitantes de uma região. Os dados coletados
Programação Básica com Linguagem C 128
de cada habitante foram: idade, sexo, salário e número de filhos. Faça uma função
que leia esses dados armazenando–os em vetores. Depois, crie funções que recebam
esses vetores como parâmetro e retornem a média de salário entre os habitantes, a
menor e a maior idade do grupo e a quantidade de mulheres com três filhos que
recebem até R$ 500,00 (utilize uma função para cada cálculo).
10.A prefeitura de uma cidade fez uma pesquisa entre seus habitantes, coletando dados
sobre o salário e o número de filhos. Faça uma única função que leia esses dados
para um número não determinado de pessoas e imprima a média de salário da
população, a média do número de filhos, o maior salário e o percentual de pessoas
com salário inferior a R$ 1.200,00.
11.Crie um programa que receba três valores (obrigatoriamente maiores que zero),
representando as medidas dos três lados de um triângulo. Todas as mensagens
deverão ser mostradas em main. Elabore funções para: a) determinar se esses lados
formam um triângulo (sabe–se que, para ser triângulo; b)a medida de um lado
qualquer deve ser inferior ou igual à soma das medidas dos outros dois). determinar
e mostrar o tipo de triângulo (equilátero, isósceles ou escaleno), caso as medidas
formem um triângulo.
12.Faça um programa que receba a temperatura média de cada mês do ano e
armazene–as em um vetor. O programa deverá calcular e mostrar a maior e a menor
temperatura do ano, junto com o mês em que elas ocorreram (o mês deverá ser
mostrado por extenso: 1 = janeiro; 2 = fevereiro; …). Observação: não se preocupe
com empates. Cada cálculo deve ser realizado e mostrado em uma função.
13.13. Crie um programa que receba o número dos 10 alunos de uma sala,
armazenando–os em um vetor, junto com as notas obtidas ao longo do semestre
(foram realizadas quatro avaliações). Elabore funções para: a) determinar e mostrar
a média aritmética de todos os alunos; b) indicar os números dos alunos que deverão
fazer recuperação, ou seja, aqueles com média inferior a 6. Todas as mensagens
deverão ser mostradas em main.
14.Encontre o elemento de maior valor gerado por uma série de Fibonacci utilizando os
tipos char, int e long. Explique estes resultados.
15.Encontre o elemento de maior valor gerado pelo fatorial tipos char, int, long, float e
double. Explique estes resultados.
16.Elabore e teste uma função recursiva para calcular o resto da divisão inteira usando
subtração.
17.Elabore e teste uma função recursiva para calcular o quociente da divisão inteira
usando subtração.
18.Elabore e teste uma função recursiva para calcular o produto de dois números
naturais usando adição.
19.Elabore e teste uma função que retorna o número de segundos de x horas.
20.Elabore e teste uma função para verificar se um ano é bissexto.
21.Elabore e teste uma função que retorna o número dias um dado mês.
22.Escreva e teste uma função que recebe dois ponteiros apontados para float e
compare os valores apontados.
4.9. Apontadores
Programação Básica com Linguagem C 129
a) são os meios pelos quais as funções podem modificar seus argumentos de chamada
b) gerenciam a memória de máquina via alocação dinâmica, uso de Heap
c) melhoram a eficiência de certas rotinas
d) fornecem suporte para estruturas dinâmicas de dados
e) manipulam o sistema de arquivos
f) permitem acesso ao hardware, local ou remoto
4.9.1. Ponteiro
As variáveis ponteiro ou apontadores são utilizadas para acessar hardware,
estas variáveis armazenam endereços de dispositivos físicos como, por exemplo,
memória, impressora, placa de rede. Os ponteiros são variáveis especializadas, elas
estão relacionadas aos seus tipos de declaração, portanto temos ponteiros para
todos os tipos, como char, int, float, double.
Os ponteiros são utilizados, principalmente, para:
tipo *NomePonteiro;
sendo:
double *pd;
long double *pld;
return 0;
}
Este código declara seis variáveis ponteiros, um ponteiro para cada tipo.
Numa declaração, o asterisco antecedendo o nome da variável indica que a
mesma é um ponteiro, trata–se de variáveis para armazenar endereços, não
podem armazenar valores.
Os ponteiros para variáveis tipo char, no caso pc – ponteiro char, são específicos
para variáveis tipo char. Não podem ser usados para apontar para variável de
outro tipo, serve apenas para variáveis tipo char.
O mesmo vale para os demais ponteiros.
O asterisco (*) tem dois usos e seu significado depende do contexto. No código
abaixo:
p = &n;
m = *p;
return 0;
}
printf("\n p = %p", p );
printf("\n p++ = %p", ++p );
printf("\n p-- = %p", --p );
printf("\n p+3 = %p", p+3 );
printf("\n p-3 = %p", p-3 );
return 0;
}
if( p < q ) puts("p aponta para uma memória menor que q");
tipo **ptr;
Essa declaração cria um ponteiro de nome ptr, o qual poderá apontar para outro
ponteiro que, por sua vez pode apontar para uma variável do tipo declarado. A
Figura 4.26 é uma representação gráfica da indireção simples e múltipla, no caso
dupla indireção.
Por exemplo:
p1 = &i;
p2 = p1;
p2 = &i;
p1 = p2;
Programação Básica com Linguagem C 136
• o apontador não recebeu um valor inicial, de modo que não se sabe o lugar da
memória para o qual ele aponta
• o apontador recebeu um endereço que não pertence ao seu programa, uma
atribuição com valor errado
• o apontador recebe um endereço inválido da memória, apesar de ter sido inicializado
corretamente
4.9.8. Resumo
4.9.9. Exercícios
Programação Básica com Linguagem C 137
#include <stdio.h>
int main( void ){
int n, *pi = &n;
printf("\n de o valor de int n: " );
scanf("%d", pi);
printf("\n n = %d", n );
return 0;
}
#include <stdio.h>
int main( void ){
char c, *pc = &c;
int i, *pi = &i;
long l, *pl = &l;
float f, *pf = &f;
double d, *pd = &d;
printf("\n\n");
printf("\n endereco pc = %p", pc );
printf("\n endereco pi = %p", pi );
printf("\n endereco pl = %p", pl );
printf("\n endereco pf = %p", pf );
printf("\n endereco pd = %p", pd );
Programação Básica com Linguagem C 138
printf("\n\n");
return 0;
}
4.10.1. Vetores
O vetor é uma estrutura de dados linear que necessita de somente um índice
para que seus elementos sejam endereçados. É utilizado para armazenar uma lista
de valores do mesmo tipo, ou seja, o tipo vetor permite armazenar mais de um
valor em uma mesma variável.
Vetores são definidos como tendo um número fixo de células idênticas (seu
conteúdo é dividido em posições). Cada célula armazena um e somente um dos
valores do vetor. Cada uma das células de um vetor possui seu próprio endereço,
ou índice, através do qual pode ser referenciada. Nessa estrutura, todos os
Programação Básica com Linguagem C 139
elementos são do mesmo tipo, e cada um pode receber um valor diferente, Figura
4.28.
int V[5];
Exemplo 4.60 O programa abaixo cria um vetor de inteiros, com cem elementos,
atribui valores a estes elementos e imprime o valor de cada elemento.
#include <stdio.h>
int main( void ){
int i, x [100];
for( i = 0; i < 100; i++ )
x[i] = i;
for( i = 0; i < 100; i++ )
printf (" %d ", x[i]);
return 0;
}
Por ter muitos elementos, eles não foram lidos do teclado.
#define n 20
float V[n]; // n é constante e V possui 20 elementos do tipo float
#define n 20
int c;
float V[n];
scanf("%f", &A[c] );
}
return 0;
}
Programa de uso geral, para qualquer tamanho de vetor n.
#define n 4
float A[n], B[n], C[n];
void LeiaA( void ){
int c;
printf("\n\n Leitura de A" );
for( c = 0; c < n; c++ ){
printf(" De o valor de A[%d]: ", c );
scanf("%f", &A[c] );
}
}
Tabela 4.21 Operações para obtenção dos valores mínimo e máximo de vetores e
seus algoritmos
Operação Procedimento
cria-se uma variável Xmin. O valor inicial de Xmin deve ser o valor do primeiro
elemento do vetor, Xmin = V[0]. Dentro da estrutura de repetição que percorre o
Mínimo
vetor, coloque o comando if( Xmin > V[i] ) Xmin = V[i];. Ao sai do laço o valor de
Xmin é o valor mínimo dentre os elementos do vetor.
cria-se uma variável Xmax. O valor inicial de Xmax deve ser o valor do primeiro
elemento do vetor, Xmax = V[0]. Dentro da estrutura de repetição que percorre o
Máximo
vetor, coloque o comando if( Xmax < V[i] ) Xmax = V[i];. Ao sai do laço o valor de
Xmax é o valor máximo dentre os elementos do vetor.
Observe que, no caso de vetores, tanto seu valor máximo quanto seu valor
Programação Básica com Linguagem C 146
Vmin = A[0];
Vmax = A[0];
return 0;
Programação Básica com Linguagem C 147
}
No início, o acadêmico fica um pouco confuso com estes procedimentos mas, ao
praticá-los, serão abstraídos e se tornarão boas práticas de programação.
Exemplo 4.69 Ordenação de vetor em ordem crescente, usando uma função para
trocar.
#include <stdio.h>
#define n 5
void troca( int *a, int *b ){
int aux = *a;
*a = *b;
*b = aux;
Programação Básica com Linguagem C 148
}
int main( void ){
int c, V[n] = { 4, 5, 1, 3, 6 };
for( c = 0; c < n; c++ ){
int i;
for( i = c; i < n; i++ )
if( V[c] > V[i] ) troca(&V[c],&V[i]);
}
printf("\n\n V: " );
for( c = 0; c < n; c++ )
printf(" %d ", V[c] );
return 0;
}
4.10.1.6. Vetor e Apontador
A Linguagem C convencionou que o nome do vetor estático é também seu
apontador, ele apontar para a sua primeira posição.
Seja int V[5] um vetor estático, como declarado abaixo.
int V[5] = { 4, 5, 1, 3, 6 };
int V[5] = { 4, 5, 1, 3, 6 };
void f( int *V );
#include<stdio.h>
void Ler( int *X, int n ){
int c;
printf("\n Lendo V");
for( c = 0; c < n; c++ ){
printf("\n De V[%d]: ", c );
scanf( "%d", &X[c] );
}
}
void Escrever( int *X, int n ){
int c;
printf("\n Escrevendo V: ");
for( c = 0; c < n; c++ )
printf(" %d ", X[c] );
}
}
int Soma( int *X, int n ){
int c, S = 0;
for( c = 0; c < n; c++ )
S += X[c];
return S;
}
int main( void ){
int V[5];
Ler(V,5);
Escrever(V,5);
printf("\n Soma de V = %d", Soma(V,5) );
return 0;
}
Depois da leitura, divida todos os seus elementos pelo maior valor do vetor. Mostre o
vetor após os cálculos.
19.Faça um programa que receba o código de oito clientes e armazene-os em um vetor.
Em um segundo vetor, armazene a quantidade de livros comprados em 2017 por
cada um dos oito clientes. Sabe-se que, para cada dez livros comprados, o cliente
tem direito a um livro grátis. Faça um programa que mostre o código de todos os
clientes, com a quantidade de livros grátis a que ele tem direito.
20.Uma escola deseja saber se existem alunos cursando, simultaneamente, as
disciplinas Lógica e Linguagem de Programação. Coloque os números das matrículas
dos alunos que cursam Lógica em um vetor, quinze alunos. Coloque os números das
matrículas dos alunos que cursam Linguagem de Programação em outro vetor, dez
alunos. Mostre o número das matrículas que aparecem nos dois vetores.
21.Faça um programa que receba o total das vendas de cada vendedor de uma loja e
armazene-as em um vetor. Receba também o percentual de comissão a que cada
vendedor tem direito e armazene-os em outro vetor. Receba os códigos desses
vendedores e armazene-os em um terceiro vetor. Existem apenas dez vendedores na
loja. Calcule e mostre: a) um relatório com os códigos dos vendedores e os valores a
receber referentes à comissão; b) o total das vendas de todos os vendedores; c) o
maior valor a receber e o código de quem o receberá; d) o menor valor a receber e
o código de quem o receberá.
22.Faça um programa para controlar o estoque de mercadorias de uma empresa.
Inicialmente, o programa deverá preencher dois vetores com dez posições cada,
onde o primeiro corresponde ao código do produto e o segundo, ao total desse
produto em estoque. Logo após, o programa deverá ler um conjunto indeterminado
de dados contendo o código de um cliente e o código do produto que ele deseja
comprar, com a quantidade. Código do cliente igual a zero indica fim do programa. O
programa deverá verificar: a) se o código do produto solicitado existe. Se existir,
tentar atender ao pedido; caso contrário, exibir mensagem Código inexistente; b)
cada pedido feito por um cliente só pode ser atendido integralmente. Caso isso não
seja possível, escrever a mensagem Não temos estoque suficiente dessa mercadoria.
Se puder atendê-lo, escrever a mensagem Pedido atendido. Obrigado e volte
sempre; c) efetuar a atualização do estoque somente se o pedido for atendido
integralmente; d) no final do programa, escrever os códigos dos produtos com seus
respectivos estoques já atualizados.
23.Uma maneira de embaralhar um vetor de tamanho N par é aplicar sucessivas
operações E1 e E2, como apresentado na tabela abaixo para N = 10. A primeira
operação troca as metades do vetor e a segunda gira o vetor uma posição à
esquerda como se ele fosse circular. Faça um programa em C que crie, atribua
valores a um vetor e aplique nele as operações E1 e E2, nessa sequência. Imprima
os resultados formatados a cada etapa como a tabela abaixo.
i 0 1 2 3 4 5 6 7 8 9
v[i] 1 2 3 4 5 6 7 8 9 10
E1 6 7 8 9 10 1 2 3 4 5
E2 7 8 9 10 1 2 3 4 5 6
Programação Básica com Linguagem C 153
#include <stdio.h>
#define N 4
int main( void ){
char c[N], *pc = &c;
int i[N], *pi = &i;
long l[N], *pl = &l;
float f[N], *pf = &f;
double d[N], *pd = &d;
int k;
for( k = 0; k < N; k++ ){
printf("\n Interacao %d", k );
printf("\n ----------------------------");
printf("\n endereco pc = %p", pc );
printf("\n endereco pi = %p", pi );
printf("\n endereco pl = %p", pl );
printf("\n endereco pf = %p", pf );
printf("\n endereco pd = %p", pd );
printf("\n\n");
pc++;
pi++;
pl++;
pf++;
pd++;
}
return 0;
}
#include <stdio.h>
#define N 4
int main( void ){
int k, P[N], Q[N], *p;
p = Q;
for( k = 0; k < N; k++ ){
P[k] = k+1;
*(p+k) = k+1;
}
printf("\n P: " );
Programação Básica com Linguagem C 154
#include <stdio.h>
#define N 4
int main( void ){
int k, P[N], Q[N], R[N], *p;
p = Q;
for( k = 0; k < N; k++ ){
P[k] = k+1;
*(p+k) = k+1;
}
p = R;
for( k = 0; k < N; k++ ){
*p = k+1;
p++;
}
printf("\n P: " );
for( k = 0; k < N; k++ )
printf(" %d ", P[k] );
printf("\n Q: " );
for( k = 0; k < N; k++ )
printf(" %d ", Q[k] );
printf("\n R: " );
for( k = 0; k < N; k++ )
printf(" %d ", R[k] );
return 0;
}
#include <stdio.h>
#define n 5
int main( void ){
int c, v[n] = { 4, 5, 1, 3, 6 };
printf("\n");
for( c = 0; c < n; c++ )
printf(" %d ", v[c] );
Programação Básica com Linguagem C 155
printf("\n");
for( c = 0; c < n; c++ )
printf(" %d ", *(v+c) );
return 0;
}
#include <stdio.h>
#define n 5
int main( void ){
int c, v[n] = { 4, 5, 1, 3, 6 };
for( c = 0; c < 2*n; c++ )
printf(" %d ", v[c] );
return 0;
}
4.10.2. Strings
O tipo de dado string da Linguagem C tem características similares às do tipo de
dados Vetor, ou seja:
NULL
char str[11];
Exemplo 4.72 A string sz[7] foi declarada com valor "abcdefg", pode-se imprimir a
string toda de uma vez ou carácter a carácter. Uma representação gráfica é
mostrada, relacionado estas operações.
char sz[7] = "abcdef";
printf( "%s", sz );
printf( "\n" );
printf( "%c", sz[0] );
printf( "%c", sz[1] );
printf( "%c", sz[2] );
printf( "%c", sz[3] );
printf( "%c", sz[4] );
printf( "%c", sz[5] );
a b c d e f \0
0 1 2 3 4 5 6
a b c d e f \0
Exemplo 4.73 A string sz[7] foi declarada e teve seus caracteres atribuídos
manualmente, neste caso é necessário atribuir o ‘\0’ via código (manualmente).
char sz[7];
sz[0] = ‘a’;
sz[1] = ‘b’;
sz[2] = ‘c’;
sz[3] = ‘d’;
sz[4] = ‘e’;
sz[5] = ‘f’’
Programação Básica com Linguagem C 157
sz[6] = ‘\0’;
printf( "%s", sz );
Exemplo 4.74 A string sz[7] pode declarada com valor inicial similarmente ao
usado em vetores.
char sz[7] = { ‘a’, ’b’, ’c’, ’d’, ’e’, ’f’ };
int c;
printf( "%s", sz );
printf("\n");
for( c = 0; c < strlen(sz); c++ )
printf( "%c", sz[c] );
Na declaração e atribuição, feitas simultaneamente, o compilador atribuir o ‘\0’
automaticamente. Nas demais operações é necessário atribuir o ‘\0’ via código.
Pergunte sempre: tenho ou não tenho que atribuir o ‘\0’ via código?
sz[0] = ‘a’;
sz[1] = ‘b’;
sz[2] = ‘c’;
sz[3] = ‘\0’;
sz[4] = ‘e’;
sz[5] = ‘f’’
sz[6] = ‘\0’;
printf( "%s", sz );
Se não encontrar ‘\0’ a string não acaba, sz avançará o quanto puder na memória
da máquina, é um erro muito grave.
Operações envolvendo string devem ser feitas com muito cuidado pois o
tamanho das strings são definidas e manipuladas manualmente, o compilador não
faz isso automaticamente.
4.10.2.1. Operações do Tipo de Dado string
A Biblioteca Padrão possui funções para a manipulação de strings, definidas na
em <string.h>, as mais comuns são listadas abaixo:
Programação Básica com Linguagem C 158
Exemplo 4.76 Este código mostra o uso de algumas funções para manipulação de
strings.
#include<stdio.h>
#include<string.h>
int main(void){
char s1[80], s2[80];
gets(s1);
gets(s2);
printf ("comprimentos: %d %d\n", strlen(s1), strlen(s2));
if( !strcmp(s1,s2) ) printf ("As strings são iguais \ n");
strcat(s1,s2);
printf ("%s\n", s1);
strcpy(s1,"Isto é um teste\n");
printf("%s",s1);
if( strchr("Olá",'e') ) printf ("e está em Olá \ n");
if( strstr("oi lá","oi") ) printf ("oi foi encontrado");
return 0;
}
Exemplo 4.77 Este código mostra a relação entre vetores strings, ao receber uma
string de no máximo 20 caracteres e imprimir conteúdo invertido.
#include<stdio.h>
#include<string.h>
int main( void ){
char s[21];
Programação Básica com Linguagem C 159
int n, c;
printf ("\n digite uma string de ate 20 caracteres: " );
gets(s);
n = strlen(s);
printf( "\n s invertida: " );
for( c = n; c >= 0; c-- )
printf (" %c ", s[c]);
printf( "\n s: %s", s );
return 0;
}
#include <stdio.h>
int main( int argc, char *argv[] ){
int i;
for( i = 0; i < argc; i++ )
printf( "%s\n", argv[i] );
return 0;
}
char Texto[numero_de_strings][tamanho_das_strings];
Exemplo 4.81 Este código lê e imprime um vetor com 5 strings de tamanho 20.
#include <stdio.h>
#include <string.h>
int main( void ){
char vet[5][21];
int c;
for( c = 0; c < 5; c ++){
printf(" Digite a string %d: ", c );
gets( Texto[c] );
Programação Básica com Linguagem C 161
}
for( c = 0; c < 5; c++ )
printf("\n string: %s", Texto[c] );
return 0;
}
4.10.2.6. Resumo
Programação Básica com Linguagem C 162
4.10.2.7. Exercícios
1. Escreva um programa em C que leia uma data, determine e imprima se ela é válida.
Ou seja, verifique se o mês está entre 1 e 12, e se o dia existe naquele mês. Note
que fevereiro tem 29 dias em anos bissextos, e 28 dias em anos não bissextos (um
ano é bissexto se ele for divisível por 4, 100 e 400. Desta forma, 1964 e 2000 são
bissextos, mas 1900 não é bissexto).
2. Faça um programa que lê nome e o sobrenome e imprime o número de letras de
cada um.
4.10.3. Matrizes
Matriz é uma estrutura de dados na forma de tabela, alocados e
sequencialmente e de forma estática. Ela é composta por linhas e colunas e, para
localizar seus elementos, necessita de dois índices, um para a linha e o outro para a
coluna.
Da mesma forma que Vetores, Matrizes são declaradas com um tamanho fixo,
todos os elementos são do mesmo tipo, todas as células são do mesmo tamanho,
cada célula contém somente um valor e seus elementos ocupam posições contíguas
na memória.
4.10.3.1. Aplicações com Matrizes
A matriz de nome A, com m linhas e n colunas, do tipo float, é declarada na
linguagem C da forma:
float A[m][n];
Se for uma matriz de nome M, com n linhas e m colunas, do tipo int, é declarada
na linguagem C da forma:
int M[m][n];
#define m 6
#define n 4
float V[m][n]; // n e m são constantes
Para fazer referência a um dos valores da matriz em C, basta usar o seu nome e
indicar os índices desejados da linha e da coluna.
Lembre-se que o índice da linha varia de 0 a m-1 e da coluna varia de 0 a n-1.
Nos laços abaixo, o primeiro for é o laço das linhas da matriz, e o segundo for é
o laço das colunas da matriz.
O for das linhas, faz variar seu contador de repetição de 0 a m-1, este contador
é usado como índice para os elementos das linhas da matriz A. A medida que vai
variando, o bloco é executado assim pode-se percorrer as linhas de A, uma a uma,
do início ao fim.
O for das colunas, faz variar seu contador de repetição de 0 a n-1, este contador
é usado como índice para os elementos das colunas da matriz A. A medida que vai
variando, o bloco é executado assim pode-se percorrer as colunas de A, uma a uma,
do início ao fim.
Os dois laços for em conjunto, ao variar seus contadores de repetição, percorre
as linhas da matriz A de cima para baixo e, as colunas de cada linha é percorrida da
esquerda para a direita, permitindo operar cada elemento A[l][c], um por um.
#define m 20
#define n 20
int l, c;
float A[m][n];
#define m 4
#define n 3
Programação Básica com Linguagem C 164
return 0;
}
#define m 3
#define n 4
}
}
return 0;
}
#define m 3
#define n 4
return 0;
}
Para atribuir valores para uma matriz basta organizá-los linha a linha, os
elementos da linha separados por vírgula, as linhas entre colchetes separadas por
vírgula, tudo isso entre colchetes.
Exemplo 4.86 Obtenha a soma das linhas e das colunas da matriz A de dimensão
20 x 30.
Os dados de entrada são os valores do vetor A – sejam ele do tipo float.
Os dados de saída são as somas de cada linha e cada coluna da matriz A.
São necessário declara a matriz A[M][N], e seus contadores l e c, ambos do tipo
int. As constantes M e NM serão declaradas como #define.
Para obter a soma das linhas de A, será usada um laço for para percorrer as linhas
de A, nomeado for linha. Dentro do for linha será declarada a variável S para a
soma das linhas, ela será to tipo for e valor inicial zero (0.0). Ainda dentro for linha,
será usada um laço for para percorrer as colunas de A, nomeado for coluna. Dentro
do for coluna será adicionado o comando para soma S com o valor de cada
elemento A[l][c]. Ao encerrar o for coluna, imprime-se S que corresponde a soma
da linha l.
Os dois for em conjunto permite somar linha a linha de A. Inicialmente, o for linha
tem l = 0. A variável S é declarada e tem valor S = 0.0. O for coluna percorre a
linha l = 0 e soma todos os valores A[0][c]. Encerrado o for coluna o valor de S é
impresso e corresponde a soma da linha 0.
O for linha avança para a próxima linha, l = 1. A variável S é declarada e tem valor
S = 0.0. O for coluna percorre a linha l = 1 e soma todos os valores A[1][c].
Encerrado o for coluna o valor de S é impresso e corresponde a soma da linha 1. E
assim por diante até a linha n-1.
No algoritmo abaixo o for linha está destacado com fundo vermelho e o for coluna
com fundo azul.
O algoritmo para calcular as somas das colunas é similar ao das linhas, exceto que
devem ser trocadas as posições dos for linha e for coluna.
No algoritmo abaixo o for linha está destacado com fundo verde e o for coluna com
Programação Básica com Linguagem C 168
fundo azul.
#include <stdio.h>
#define M 3
#define N 4
• a variável Sdp do tipo float para sua soma, com valor inicial zero (0.0)
• a variável DPmin do tipo float para seu mínimo, com valor inicial A[0][0]
• a variável DPmax do tipo float para seu máximo, com valor inicial A[0][0]
• a variável Sds do tipo float para sua soma, com valor inicial zero (0.0)
• a variável DSmin do tipo float para seu mínimo, com valor inicial A[0][N-1]
• a variável DSmax do tipo float para seu máximo, com valor inicial A[0][N-1]
Serão usados apenas um laço for para os cálculos com os comandos descritos na
Tabela 4.23. A final deste do for serão impressos os valores solicitados.
Os comandos para os valores iniciais para DPmin, DPmax, DSmin e DSmax devem
ser colocados após a leitura dos valores de A e não antes.
#include <stdio.h>
#define M 30
int main( void ){
int l;
float A[M][M], Sds, Sdp, DPmin, DPmax, DSmin, DSmax;
Sdp = 0.0;
Sds = 0.0;
}
}
DPmin = A[0][0];
DPmax = A[0][0];
DSmin = A[0][M-1];
DSmax = A[0][M-1];
return 0;
}
E uma boa prática de programação criar o dicionário com as varáveis do programa,
seus tipos e valores iniciais. E, o mais importante, a finalidade de cada uma delas,
as operações a realizar com cada uma delas e onde colocar cada comando a elas
referentes. Isso tudo antes de começar a digitar o programa de computador.
No início, o acadêmico fica um pouco confuso com estes procedimentos mas, ao
praticá-los, serão abstraídos e se tornarão boas práticas de planejamento de
Programação Básica com Linguagem C 171
programação.
printf("\n");
for( j = 0; j < P; j++ )
printf(" %lf ", C[i][j] );
}
return 0;
}
4.10.3.7. Resumo
4.10.3.8. Exercícios
1. Faça um programa que preencha uma matriz 3 x 5 com números inteiros, calcule e
mostre a quantidade de elementos entre 15 e 20.
2. Crie um programa que preencha uma matriz 2 x 4 com números inteiros, calcule e
mostre: a) a quantidade de elementos entre 12 e 20 em cada linha; b) a média dos
elementos pares da matriz.
3. Ler 10 elementos de uma matriz A. Construir uma matriz B de mesmo tipo, com a
seguinte lei de formação: todo elemento da matriz B deverá ser o quadrado do
elemento de A correspondente.
4. Elabore um programa que preencha uma matriz 6 x 3, calcule e mostre: a) o maior
elemento da matriz e sua respectiva posição, ou seja, linha e coluna; b) o menor
elemento da matriz e sua respectiva posição, ou seja, linha e coluna.
5. Faça um programa que receba: a) as notas de 15 alunos em cinco provas diferentes
e armazene-as em uma matriz 15 x 5; b) os nomes dos 15 alunos e armazene-os em
um vetor de 15 posições. O programa deverá calcular e mostrar: a) para cada aluno,
o nome, a média aritmética das cinco provas e a situação (aprovado, reprovado ou
exame); b) a média da classe.
6. Elabore um programa que preencha uma matriz 12 x 4 com os valores das vendas
de uma loja, em que cada linha representa um mês do ano e cada coluna representa
uma semana do mês. O programa deverá calcular e mostrar: a) o total vendido em
cada mês do ano, mostrando o nome do mês por extenso; b) o total vendido em
cada semana durante todo o ano; c) o total vendido pela loja no ano.
7. Faça um programa que preencha uma matriz 20 x 10 com números inteiros, e some
cada uma das colunas, armazenando o resultado da soma em um vetor. A seguir, o
programa deverá multiplicar cada elemento da matriz pela soma da coluna e mostrar
a matriz resultante.
8. Elabore um programa que preencha uma matriz M de ordem 4 x 6 e uma segunda
matriz N de ordem 6 x 4, calcule e imprima a soma das linhas de M com as colunas
de N.
9. Crie um programa que preencha duas matrizes 3 x 8 com números inteiros, calcule e
mostre: a) a soma das duas matrizes, resultando em uma terceira matriz também de
ordem 3 x 8; b) a diferença das duas matrizes, resultando em uma quarta matriz
também de ordem 3 x 8.
10.Faça um programa que preencha uma matriz 3 x 3 com números reais e outro valor
Programação Básica com Linguagem C 174
∑x .
N i=1 i
calcule e escreva a maior e a menor altura do grupo, a altura média das mulheres e
o número de homens.
26.Escreva uma função em C para imprimir na saída padrão a tabuada da soma de 1 a 5
formatada:
a + b = s a + b = s a + b = s a + b = s a + b = s
1 + 1 = 2 2 + 1 = 3 3 + 1 = 4 4 + 1 = 5 5 + 1 = 6
1 + 2 = 3 2 + 2 = 4 3 + 2 = 5 4 + 2 = 6 5 + 2 = 7
1 + 3 = 4 2 + 3 = 5 3 + 3 = 6 4 + 3 = 7 5 + 3 = 8
1 + 4 = 5 2 + 4 = 6 3 + 4 = 7 4 + 4 = 8 5 + 4 = 9
1 + 5 = 6 2 + 5 = 7 3 + 5 = 8 4 + 5 = 9 5 + 5 = 10
1 + 6 = 7 2 + 6 = 8 3 + 6 = 9 4 + 6 = 10 5 + 6 = 11
1 + 7 = 8 2 + 7 = 9 3 + 7 = 10 4 + 7 = 11 5 + 7 = 12
1 + 8 = 9 2 + 8 = 10 3 + 8 = 11 4 + 8 = 12 5 + 8 = 13
1 + 9 = 10 2 + 9 = 11 3 + 9 = 12 4 + 9 = 13 5 + 9 = 14
1 + 10 = 11 2 + 10 = 12 3 + 10 = 13 4 + 10 = 14 5 + 10 = 15
Exercício 4.30 Considere matrizes Am,n e Bm,n e faça uma função para:
a) gerar valores aleatórios para A
b) calcule bi,j como sendo o máximo da horizontal de a i,j, exceto ai,j
c) calcule bi,j como sendo o mínimo da diagonal principal de a i,j
d) calcule bi,j como sendo a média da diagonal secundária de a i,j
e) calcule bi,j como sendo a média dos elementos do entorno de a i,j, exceto ai,j
f) proponha testes para validar os algoritmos acima
g) imprima a matriz B para cada item acima
Programação Básica com Linguagem C 176
Exercício 4.31 Considere matrizes Am,n e Bm,n e alvo de k elementos, faça uma
função para:
a) gerar valores aleatórios para A
b) calcule bi,j como sendo o máximo da horizontal de a i,j, exceto ai,j
c) calcule bi,j como sendo o mínimo da diagonal principal de a i,j
d) calcule bi,j como sendo a média da diagonal secundária de a i,j
e) calcule bi,j como sendo a média dos elementos do entorno de a i,j, exceto ai,j
f) proponha testes para validar os algoritmos acima
g) imprima a matriz B para cada item acima
Exercício 4.32 Considere matrizes Am,n e Bm,n e alvo de k elementos, faça uma
função para:
a) gerar valores aleatórios para A
b) calcule bi,j como sendo o máximo da horizontal de a i-1,j
c) calcule bi,j como sendo o mínimo da diagonal principal de a i,j+1
d) calcule bi,j como sendo a média da diagonal secundária de a i-1,j-1
e) calcule bi,j como sendo a média dos elementos do entorno de a i+k,j+k
f) proponha testes para validar os algoritmos acima
g) imprima a matriz B para cada item acima
Exercício 4.33 Estenda os conceitos acima para Am,n,p e Bm,n,p e refaça os exercícios
acima.
Exercício 4.34 Aplique os resultados anteriores para criar um campo minado por
meio de uma matriz em que uma posição com valor 0 indica uma mina e, para
cada posição livre, o número de posições adjacentes que contêm bombas.
Exercício 4.36 Crie um vetor V[MxN] e leia-o e escreva-o como se fosse uma matriz
V[M][N].
Exercício 4.37 Diz a lenda do Xadrez que Lahur Sessa pediu a seguinte
recompensa por sua invenção: um grão de trigo para a primeira casa do tabuleiro,
dois para a segunda, quatro para a terceira, oito para a quarta e assim
sucessivamente até a última casa de um total de 64 casas. Se a massa de um grão
de trigo é igual 3,855ˣ10-5 kg e sua densidade é de 7,55 kg/m 3. Faça um programa
em C para calcular a massa e o volume de trigo devido ao brâmane utilizando os
tipos: a) float, b) double e c) long double. Interprete seus resultados.
4.10.4. Estruturas
Exemplo 4.89 Exemplo de um tipo struct de nome Pessoa com quatro campos,
nome, idade, peso e altura e de uma variável Jose do tipo struct Pessoa.
struct Pessoa{ // define o tipo struct
char Nome[35]; // define o campo Nome
float Peso ; // define o campo Peso
int Idade ; // define o campo Idade
float Altura ; // define o campo Altura
};
struct Pessoa Jose; // declara variável Jose do tipo struct Pessoa
Programação Básica com Linguagem C 178
struct NomeDaStruct{
tipo1 var12, ..., var1n;
tipo2 var22, ..., var2n;
…
tipok vark2, ..., varkn;
};
struct Aluno{
char nome[50], disciplina[30];
float media, nota[3];
};
Exemplo 4.90 Este código declara uma estrutura de nome pessoa com quatro
campos, nome, idade, peso e altura:
struct pessoa{
char nome[35];
int idade;
float peso, altura;
} x;
A variável x é do tipo pessoa, uma estrutura criada no programa, x também é
denominada registro.
Programação Básica com Linguagem C 179
Exemplo 4.91 Este código declara uma estrutura de nome pessoa com quatro
campos, nome, idade, peso e altura. E, simultaneamente, declara três variáveis de
nomes Pedro, Joao e Visitante.
struct pessoa{
char nome[35];
int idade;
float peso, altura;
} Pedro, Joao, Visitante;
struct pessoa{
char nome[12];
int idade;
float peso, altura, IMC;
};
struct nome{
tipo1 var1;
tipo2 var2;
tipo3 var3;
} var, *p;
Exemplo 4.93 Este código cria o tipo struct com escopo global. Cria a variável p de
escopo local. Chama a função prn e o ponteiro para o tipo struct, que recebe o
endereço de p vindo da função main. Em seguida, imprime os valores de nome,
idade e altura.
struct Pessoa{
char nome[35];
int idade;
double altura;
};
void prn( struct Pessoa *pessoa ){
printf( "\n\n Dados de Pessoa");
printf( "\n----------------------------");
printf( "\n nome: %s ", pessoa->nome );
Programação Básica com Linguagem C 181
struct Aluno{
char nome[12];
char disciplina[12];
float nota[3];
float media;
};
int main(void){
int c;
struct Aluno Turma[TAM];
for( c = 0; c < TAM; c++ )
Programação Básica com Linguagem C 182
Ler(c,&Turma[c]);
printf( "\n================================================");
printf( "\n No Nome Disciplina Nota 1 Nota 2 Nota 3 Media ");
printf( "\n------------------------------------------------");
for( c = 0; c < TAM; c++ ){
printf("\n");
printf(" %2d", c+1 );
printf(" %-12s", Turma[c].nome );
printf(" %-12s", Turma[c].disciplina );
printf(" %6.1f", Turma[c].nota[0] );
printf(" %6.1f", Turma[c].nota[1] );
printf(" %6.1f", Turma[c].nota[2] );
printf(" %6.1f", Turma[c].media );
}
printf( "\n================================================");
return 0;
}
Exemplo 4.95 Este código obtém a diferença em segundo de duas datas, ele faz
uso do tipo struct tm da Biblioteca Padrão e suas funções para manipulação de.
#include <stdio.h> // printf
#include <time.h> // time_t, struct tm, difftime, time, mktime
int main ( void ){
time_t timer;
struct tm y = {0};
double seconds;
y.tm_hour = 0;
y.tm_min = 0;
y.tm_sec = 0;
y.tm_year = 2000;
y.tm_mon = 0;
y.tm_mday = 1;
seconds = difftime(timer,mktime(&y));
4.10.5. União
Uma declaração union determina uma única localização de memória onde
podem estar armazenadas várias variáveis diferentes. A declaração de uma união é
semelhante à declaração de uma estrutura:
union nome{
tipo1 var1;
tipo2 var2;
tipo3 var3;
...
} var, *p;
union Angulo{
int grau;
float radiano;
};
angulo.grau = 180;
printf("\nAngulo: %d graus\n" , angulo.grau );
printf("\nAngulo: %f radianos\n", angulo.radiano );
angulo.radiano = acos(-1);
printf("\nAngulo: %d graus\n" , angulo.grau );
printf("\nAngulo: %f radianos\n", angulo.radiano );
return 0;
}
struct nome{
tipo1: comprimento;
tipo2: comprimento;
tipo3: comprimento;
…
tipon: comprimento;
};
Exemplo 4.97 Este código ilustra o uso da estrutura de dados campo de bit.
4.10.7. Enumeração
Enumerações são conjunto de constantes inteiras com nome e especificação de
todos os valores legais.
4.10.8. Typedef
Typedef é uma forma de definir explicitamente novos nomes de tipos de dados.
Sintaxe:
Programação Básica com Linguagem C 185
Exemplo 4.99 Este código cria um alias (apelido) para os tipos int e double.
#include <stdio.h>
4.10.9. Resumo
4.10.10. Exercícios
4.11. Arquivos
Para a Linguagem C, um arquivo é um conceito lógico que é aplicado aos
arquivos gravados em memória de massa, como os Discos Rígidos.
Uma representação gráfica do conceito de arquivo é uma sequência de bytes
Programação Básica com Linguagem C 186
EOF
Para o computador todos os arquivos são binários, eles armazenam apenas bits
{0,1}. Aqueles que podem ser manipulados por Editores de Texto são denominados
arquivos-texto. Caso contrário, são denominados arquivos binários.
A Linguagem C utiliza uma estrutura chamada FILE para manipular arquivos por
meio de apontadores.
Sintaxe para declarar apontador FILE:
FILE *p;
Da mesma forma que uma variável pode ser associada a uma região da
memória RAM, um descritor de arquivo pode ser associado a uma região da
memória de massa.
As operações sobre arquivos são abertura, leitura, escrita e fechamento.
Depois que um arquivo é aberto, é possível trocar informações entre ele e seu
programa por meio do seu descritor, que pode apontar para qualquer posição do
arquivo, incluindo o seu fim, a posição em que se encontra o EOF.
a) Abrir arquivos para leitura ou anexar requer que ele exista antes de ser aberto
b) Ao abrir um arquivo para escrita, se ele existir então será recriado senão ele será
criado
c) Abre um arquivo para leitura/escrita ou anexar, se ele a escrita será feita ao seu final
(preservando o conteúdo previamente existente) senão será criado
Estas funções escreve/lê buffer do/no arquivo binário apontado por p; buffer é a
região de memória a ser escrita/lida os dados; tamanho é o número de bytes da
unidade a ser escrita/lida e n é o número de unidades a serem escritas/lidas.
Elas retornam um valor size_t cujo valor é n em caso de sucesso e um valor
menor do que n em caso de erro.
A leitura/escrita de strings e caracteres em arquivo-texto estão descritas na
Tabela 4.27.
Em stdio.h estão as funções para manipular arquivos. Seguem as mais comuns:
Programação Básica com Linguagem C 189
}
void ler( char *fn ){
char c;
int i;
long l;
float f;
double d;
FILE *fe = fopen( fn, "rb" );
if( fe == NULL){ puts("erro fopen"); exit(1); }
puts( "Lendo valores" );
fread( fn, sizeof(char) , sizeof(fn), fe );
fread( &c , sizeof(char) , 1 , fe );
fread( &i , sizeof(int) , 1 , fe );
fread( &l , sizeof(long) , 1 , fe );
fread( &f , sizeof(float) , 1 , fe );
fread( &d , sizeof(double), 1 , fe );
fclose(fe);
}
int main(void){
char fn[32] = "dados.bin";
escrever(fn);
ler(fn);
return 0;
}
Foram usadas funções para ler e escrever valores dos tipos string, char, int, long,
float e double, um de cada, em um arquivo dados.bin.
LerBinario(bin,V,N);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
struct Aluno{
char nome[20];
char disciplina[20];
float nota[3];
float media;
};
void EscreveTela( struct Aluno X ){
printf("\nNome: %-s", X.nome );
printf("\n---------------------------------------" );
printf("\nDisciplina: %-s" , X.disciplina );
printf("\nNota 1 : %.1f", X.nota[0] );
printf("\nNota 2 : %.1f", X.nota[1] );
printf("\nNota 3 : %.1f", X.nota[2] );
printf("\nMedia : %.1f", X.media );
printf("\n---------------------------------------" );
}
void EscreverTexto( char *fn, struct Aluno X ){
FILE *fs = fopen( fn, "w" );
if( fs == NULL){ puts("erro fopen"); exit(1); }
puts( "\nEscrevendo valores em arquivo texto" );
fprintf(fs,"%s\n", X.nome );
fprintf(fs,"%s\n", X.disciplina );
fprintf(fs,"%f\n", X.nota[0]-0.5);
fprintf(fs,"%f\n", X.nota[1]-0.5);
fprintf(fs,"%f\n", X.nota[2]-0.5);
fprintf(fs,"%f\n", X.media -0.5);
fclose(fs);
}
void LerTexto( char *fn, struct Aluno X ){
FILE *fe = fopen( fn, "r" );
if( fe == NULL){ puts("erro fopen"); exit(1); }
puts( "\nLendo valores em arquivo texto" );
fscanf(fe,"%s\n", &X.nome );
fscanf(fe,"%s\n", &X.disciplina );
fscanf(fe,"%f\n", &X.nota[0] );
fscanf(fe,"%f\n", &X.nota[1] );
fscanf(fe,"%f\n", &X.nota[2] );
Programação Básica com Linguagem C 195
fscanf(fe,"%f\n", &X.media );
EscreveTela(Pedro);
EscreverTexto (txt,Pedro);
LerTexto (txt,Pedro);
Pedro.media = 6.5; // testando escrita e leitura
EscreverBinario(bin,Pedro);
LerBinario (bin,Pedro);
return 0;
Programação Básica com Linguagem C 196
A entrada padrão é via teclado, enquanto a saída padrão e erro padrão são
impressos na saída de vídeo.
a) perror - exibe a string que o programador passa para ela, dois pontos e espaço,
seguida da representação textual do valor atual do erro
Programação Básica com Linguagem C 197
Exemplo 4.107 Este código mostra o uso de errno e das funções perror e strerror.
#include <stdio.h>
#include <errno.h>
#include <string.h>
Exemplo 4.108 Este código mostra o uso das funções feof e getc.
#include <stdio.h>
#include <stdlib.h>
int main( void )
char ch;
FILE *fe = fopen("texto.txt","w"); // não testa fe == NULL
while( !feof(fe) ){
ch = getc(fe);
putchar( ch );
}
fclose(fe);
return 0;
}
Exemplo 4.109 Este código mostra o uso das funções ferror, fwrite e fread.
#include<stdio.h>
#include<stdlib.h>
Programação Básica com Linguagem C 198
#define MAX 12
int main( void ){
int l;
float v[MAX], w[MAX];
fclose(f);
return 0;
}
4.11.6. Resumo
Programação Básica com Linguagem C 199
4.11.7. Exercícios
Seja N o número de bytes de uma memória RAM, logo os bytes desta memória
são numerados de 0 a N–1. Hoje em dia o valor de N é muito grande e tende a
aumentar com o passar dos anos.
Os endereços de memória são numerados a partir de zero, utilizando números
inteiros sem sinal. Normalmente, para expressar o tamanho da memória, utiliza-se
os tipos unsigned int ou unsigned long int. O tamanho da memória é muito
grande, dado em GB – Giga Byte, TB – Tera Byte ou PB – Peta Byte.
Cada uma das variáveis de um programa de computador ocupa um número de
bytes consecutivos na memória do computador. Uma variável do tipo char ocupa 1
B. Uma variável do tipo int ocupa 4 B e um double ocupa 8 B em muitos
computadores – estes valores dependem da arquitetura do hardware.
Programação Básica com Linguagem C 201
Exemplo 5.2 Imprimir formatado o número exato de bytes de variáveis dos tipos
utilizando o operador sizeof.
#include <stdio.h>
int main( void ){
printf("\n ----------------------");
printf("\n x sizeof(x) ");
printf("\n ----------------------");
printf("\n char %2d", sizeof( char) );
printf("\n int %2d", sizeof( int) );
printf("\n long %2d", sizeof( long) );
printf("\n float %2d", sizeof( float) );
printf("\n double %2d", sizeof( double) );
printf("\n long double %2d", sizeof( long double) );
printf("\n ----------------------");
printf("\n\n\n");
return 0;
}
A região Heap pode ser usada dinamicamente pelo programa executável, por
meio de apontadores, e sem a interferência do Sistema Operacional. A memória
que não é gerenciada automaticamente, o programa em execução deve alocar e
liberar toda memória que usar. Deixar de liberar a memória ao terminar de usá-la é
um erro conhecido como vazamento de memória – memória que não é usada pelo
programa que a alocou e não fica disponível para outros processos. O tamanho do
Heap está limitado ao tamanho da memória física disponível na máquina.
Resumo do Heap:
• malloc() - usada para alocar um novo bloco de memória para uso exclusivo do
programa executável. Pode ocorrer falha na alocação, escrever fora do bloco alocado
• calloc() - usada para alocar um novo bloco de memória para uso exclusivo do
programa executável, como malloc porém escreve 0 em todos os bits alocados.
• realloc() - usada para realocar um bloco de memória previamente alocado por malloc
ou calloc. Pode ocorrer falha na realocação.
• free() - libera a memória previamente alocada ou realocada. Pode ocorrer falha na
liberação da memória e, como consequência, o Sistema Operacional perde o controle
da memória alocada ao fim do programa executável
• é gerenciada pelo SO, não pode ser modificada pelo programa em execução
• as variáveis nela alocadas pelo SO são liberadas automaticamente
• ela não é ilimitada, possui um limite superior
• ela aumenta e diminui conforme as variáveis são criadas e destruídas
• suas variáveis existem enquanto a função que as declarou existir
• seu mau uso pode causar estouro de pilha
18 O tipo size_t é um inteiro sem sinal, usado para endereços da memória principal ou endereços de hardware.
Programação Básica com Linguagem C 205
Exercício 5.1 Refaça o Exemplo 5.3 usando função realloc para dobrar o tamanho
da memória por p.
Exercício 5.2 Refaça o Exemplo 5.3 usando os tipos long e double.
int *x[10];
Algoritmo 1
============================================
#include <stdio.h>
#include <stdlib.h>
#define L 1000
int main( void ){
double A[L][L];
printf("Tamanho de A é %ld bytes", L*L*sizeof(double) );
return 0;
}
Algoritmo 2
============================================
#include <stdio.h>
#include <stdlib.h>
#define L 1000
double **Criar( void ){
int l;
double **X;
X = (double**) malloc( L*sizeof(double*) );
for( l = 0; l < L; l++ )
X[l] = (double*) malloc( L* sizeof(double) );
return X;
}
void Destruir( double **X ){
int l;
Programação Básica com Linguagem C 208
Matriz e Apontador
Exemplo 5.8 Programa em C para multiplicar duas matrizes C=AB, para quaisquer
valores de m, n e p, sem variáveis globais, com menor número de funções
possível, sem blocos de comandos repetidos, com valores das matrizes gerados
aleatoriamente e com a main "menor" possível.
#include <stdio.h>
#define Nl 3
#define Nc 4
printf("Imprimindo A " );
for( l = 0; l < Nl; l++ ){
printf("\n");
Programação Básica com Linguagem C 209
Exemplo 5.9 Programa em C para multiplicar duas matrizes C=AB, para quaisquer
valores de m, n e p, sem variáveis globais, com menor número de funções
possível, sem blocos de comandos repetidos, com valores das matrizes gerados
aleatoriamente e com a main "menor" possível.
#include <stdio.h>
#define M 3
#define N 4
#define P 3
double **Criar( int Lin, int Col ){
int i;
double **X;
X = (double**) malloc( Lin*sizeof(double*) );
for( i = 0; i < Lin; i++ )
X[i] = (double*) malloc( Col* sizeof(double) );
if( X == NULL ){ puts("erro de alocacao"); exit(1);}
return X;
}
void Destruir( double **X, int Lin ){
int i;
for( i = 0; i < Lin; i++ )
free(X[i]);
free(X);
}
void Ler( char c, double **V, int Lin, int Col ){
int i, j;
printf( "\n\n\n Leitura de %c ", c );
for( i = 0; i < Lin; i++ )
for( j = 0; j < Col; j++ ){
printf(" De o valor de %c[%d][%d]: ", c, i, j );
scanf("%lf", &V[i][j] );
Programação Básica com Linguagem C 210
}
}
void Calculo( double **A, double **B, double **C ){
int i, j, r;
printf("\n\n\n Calculando C = AB … " );
for( i = 0; i < M; i++ )
for( j = 0; j < P; j++ ){
C[i][j] = 0.0;
for( r = 0; r < N; r++ )
C[i][j] = A[i][r]*B[r][j];
}
}
void Escrever( char c, double **X, int Lin, int Col ){
int i, j;
printf("\n\n\n Imprimindo %c ", c );
for( i = 0; i < Lin; i++ ){
printf("\n");
for( j = 0; j < Col; j++ )
printf(" %lf ", X[i][j] );
}
}
int main( void ){
double **A, **B, **C;
A = Criar(M,N);
B = Criar(N,P);
C = Criar(M,P);
Ler('A',A,M,N);
Ler('B',B,N,P);
Escrever('A',A,M,N);
Escrever('B',B,N,P);
Calculo(A,B,C);
Escrever('C',C,M,P);
Destruir(A,M);
Destruir(B,N);
Destruir(C,P);
return 0;
}
Struct e Apontador
Programação Básica com Linguagem C 211
Exemplo 5.10 Programa de vetor de struct com alocação dinâmica. Compare este
exemplo com o anterior, identifique e explique as diferenças.
# include <stdio.h>
# define TAM 3
struct Aluno{
char nome[12];
char disciplina[12];
float nota[3];
float media;
};
struct Aluno *Criar( void ){
struct Aluno *A;
A = (struct Aluno*) malloc( TAM*sizeof(struct Aluno) );
if( A == NULL ){
puts("Erro ao criar Aluno");
abort();
}
return A;
}
void Ler( struct Aluno *T ){
printf("\n Nome:" ); scanf("%s", T->nome );
printf("\n Disciplina:" ); scanf("%s", T->disciplina );
printf("\n Primeira nota:" ); scanf("%f", T->nota );
printf("\n Segunda nota:" ); scanf("%f", T->nota+1 );
printf("\n Terceira nota:" ); scanf("%f", T->nota+2 );
T->media = ( T->nota[0]+T->nota[1]+T->nota[2] )/3.0;
}
int main(void){
int c;
struct Aluno *Turma;
Turma = Criar();
for( c = 0; c < TAM; c++ ){
printf("\n Aluno: %d", c+1 );
Ler(Turma+c);
}
printf( "\n================================================");
printf( "\n No Nome Disciplina Nota 1 Nota 2 Nota 3 Media ");
printf( "\n------------------------------------------------");
for( c = 0; c < TAM; c++ ){
printf("\n");
printf(" %2d", c+1 );
printf(" %-12s", Turma[c].nome );
Programação Básica com Linguagem C 212
DeAloca(M,nl);
return 0;
}
5.6. Resumo
6. Biblioteca Padrão C
7. Aplicações
b = m;
}
printf(" mdc( %u, %u ) = %u", a, b, mdc(a,b) );
return 0;
}
Para saber se um número é primo, dividimos esse número pelos números primos
2, 3, 5, 7, 11, etc, até que tenhamos:
• ou uma divisão com resto zero (e neste caso o número não é primo),
• ou uma divisão com quociente menor que o divisor e o resto diferente de zero, neste
caso o número é primo
#include<stdbool.h>
typedef unsigned int uint;
bool primo( uint N ){
uint i, div = 0;
for( i = 1; i <= N; i++ )
if( N % i == 0 ) div++;
if( div == 2 ) return 1;
else return 0;
}
int main( void ){
uint N = 17;
if( primo(N) ) printf( " N = %d e primo", N );
else printf( " N = %d não e primo", N );
return 0;
}
Há muitos algoritmos sobre números primos, este é apenas um deles, embora
didático é ineficiente.
1 2 3 4 5
∞
n
1. =1+ x + x + x + x + x +⋯=∑ x para |x| < 1.
1−x n=0
n
π = (−1) =1− 1 + 1 − 1 +⋯
∞
2. ∑
4 n=1 2 n+1 3 5 7
∞
1
3. e=∑
n=0 n !
∞
xn
4. e x =∑
n=0 n!
∞
(−1)n 2 n +1
5. sen ( x)=∑ x
n=0 (2 n+1)!
∞ n
(−1) 2 n
6. cos( x)=∑ x
n=0 (2n) !
∞
A fórmula geral de uma série é S=∑ ui , ou seja, S=u 0+ u1+ u2+ u3 +u4 +⋯ .
i=0
1 ∞
1 1 1 1
Considere obter a série S=∑ 2i
, ou seja, S=1+ 2 + 4 + 6 + 8 +⋯ . Esta soma é
i=0 x x x x x
infinita e não tem como calcular seu valor exato por meio de algoritmo. Como foi
Programação Básica com Linguagem C 221
Observe que diferença entre as somas ΔSi = Si – Si-1 = ui. Pode-se usar ui como
critério de parada do algoritmo.
2 i+1 3 5 7
∞
x x x x
Considere obter a série S=∑ (−1)i , ou seja, S=x− − + +⋯ . No
i=0 2 i+ 1 3 5 7
quadro abaixo, pode-se ver os valores de, i, ui, (-1) x /(2i+1) e S, para x= 0,7.
i 2i+1
i ui (-1)ix2i+1/(2i+1) S
0 u0 0,7000000 0,7000000
1 u1 -0,1143333 0,5856667
2 u2 0,0336140 0,6192807
3 u3 -0,0117649 0,6075158
4 u4 0,0044837 0,6119995
5 u5 -0,0017976 0,6102019
6 u6 0,0007453 0,6109472
7 u7 -0,0003165 0,6106307
8 u8 0,0001368 0,6107676
9 u9 -0,0000600 0,6107076
10 u10 0,0000266 0,6107342
11 u11 -0,0000119 0,6107223
12 u12 0,0000054 0,6107276
13 u13 -0,0000024 0,6107252
14 u14 0,0000011 0,6107263
15 u15 -0,0000005 0,6107258
16 u16 0,0000002 0,6107260
17 u17 -0,0000001 0,6107259
18 u18 0,0000001 0,6107260
Programação Básica com Linguagem C 222
S = 0
calcular u inicial // é o valor de u0
while( |u| > PRECISAO ){
S = S + u
calcular u // é o valor do termo geral ui
}
imprimir S
i = 0 ;
x = 0.5;
u = 1.0;
S = 0.0;
2 i+1
∞
i x
Exemplo 7.4 Programa C para calcular S=∑ (−1) , para x = 0.7.
i=0 2 i+ 1
#include <stdio.h>
#define PRECISAO 1.0E-6
int main( void ){
int i;
float x, u, S;
i = 0 ;
x = 0.7;
u = x ;
Programação Básica com Linguagem C 224
S = 0.0;
while( fabs(u) > PRECISAO ){
S = S + u;
i = i + 1;
u = pow(-1.0, i)* pow(x, 2*i+1) / (2*i + 1);
}
printf("\n S = %f ", S );
return 0;
}
7.4. Exercícios
Faça um programa em C para calcular valores aproximados das séries:
∞
2i
1. S=∑ , para x = 0.5
i=1 x2i
i
∞
x
2. S=∑ , para x = 0.1
i=0 i!
2 i+ 1
∞
x i
3. S=∑ (−1) , para x = 0.75
i=0 (2i +1)!
2i
∞
i x
4. S=∑ (−1) , para x = 0.75
i=0 (2i )!
∞
ix i
5. S=∑ i
, para x = 0.5
i=0 3
∞
xi +1
6. S=∑ , para x = 1.5
i=0 (i +1)2
∞
i
7. S=∑ i! x , para x = 1.5
i=0
i=0
i ui ui ui
0 u0 1 1
1 u1 x u0x = x
2 u2 x2 u1x = x2
3 u3 x3 u2x = x3
4 u4 x4 u3x = x4
... ... ... ...
i uI xi ui = ui-1x
... ... ... ...
9 u9 x9 u8x = x9
Pode-se gerar esta série a partir do seu termo geral xi, para i variando de 1 a 9.
Observe que há um padrão que pode ser usado para gerar esta série. O termo u 0 =
1, os demais termos são u1 = x, u2 = x2, u3 = x3, u4 = x4, e assim por diante.
Observe que pode-se escrever u1 = 1x, u2 = xx, u3 = x2x, u4 = x3x, e assim por
diante.
O padrão desta série é: fazendo u0 = 1, o próximo termo é igual ao termo anterior
multiplicado por x, ou seja, ui = ui-1x, para i variando de 1 a 9.
Este padrão não se aplica ao primeiro termo ( u0 ), que é usado como valor inicial.
Em termos de algoritmo, usando este padrão, pode-se escrever:
leia x
u = 1
S = 1
para i = 1 até i < 10 faça
u = u*x
S = S + u
fim para
escreva S
Em termos de algoritmo, sem usar este padrão, pode-se escrever:
leia x
S = 1
para i = 1 até i < 10 faça
u = xi
S = S + u
fim para
escreva Soma
O primeiro algoritmo calcula u por meio de multiplicação, já o segundo utiliza
potência. Por isso o primeiro algoritmo, em geral, é mais eficiente do que o
segundo.
A exemplo abaixo apresenta uma recorrência para resolver séries que requerem
fatorial.
Programação Básica com Linguagem C 226
7.6. Exercícios
Encontre a fórmula de recorrência das séries abaixo e proponha algoritmos para
obter seus valores aproximados:
∞
1
1. S=∑
i=0 i!
i
∞
i
2. S=∑
i=0 i !
Programação Básica com Linguagem C 227
∞
2i
3. S=∑ 2i
, para x = 0.5
i=0 x
∞ i
x
4. S=∑ , para x = 0.1
i=0 i!
∞ 2 i+1
i x
5. S=∑ (−1) , para x = 0.75
i=0 (2 i+ 1)!
∞
x2 i
6. S=∑ (−1)i , para x = 0.75
i=0 (2 i) !
∞
ixi
7. S=∑ i
, para x = 0.5
i=0 3
∞ i+ 1
x
8. S=∑ , para x = 1.5
i=0 (i+1)2
∞
i
9. S=∑ i ! x , para x = 1.5
i=0
8. Preprocessamento
#include <stdio.h>
Figura 9.1 IDE Dev-Cpp versão 5.11 com o GNU GCC 4.9.2 32-bit.
a IDE Dev-Cpp
Comando Atalho Descrição
Executar→Compilar F9 compila o arquivo-fonte em foco e, se não houver erros, gera o
executável
Executar→Executar F10 executa o programa previamente compilado
Executar→Compilar & F11 compila o arquivo-fonte em foco e, se não houver erros, gera o
Executar executável e o executa
Executar→Recompilar F12 compila novamente todos os arquivo-fonte abertos e, se não
Tudo houver erros, gera o executável
Pode-se ver o resultado do processo de compilação na parte de baixo da IDE,
como pode ser visto na Figura 9.1.
No caso de haver erro no programa-fonte, este é indicado no texto e descrito na
parte de baixo da IDE. Na Figura 9.2 pode-se observar um erro na linha 9 e sua
descrição. Veja que não é tão simples, o erro refere-se à falta de ponto e vírgula
deve ser corrigido na linha 7.
Exemplo 9.3 Digite o programa abaixo na IDE Dev-Cpp e salve-o como ESDados.c,
em seguida compile-o, corrija os erros se houver e execute-o.
#include <stdio.h>
Exemplo 9.4 Digite o programa abaixo na IDE Dev-Cpp e salve-o como Soma.c, em
seguida compile-o, corrija os erros se houver e execute-o.
#include <stdio.h>
int main( void ){
int a, b, soma;
a = 3;
b = 4;
soma = a + b;
printf( "A soma é %d", soma );
return 0;
}
Em que:
$./programa
11. Makefile
<assignment-operator> ::= =
| *=
| /=
| %=
| +=
Programação Básica com Linguagem C 237
| -=
| <<=
| >>=
| &=
| ^=
| |=
This grammar was adapted from Section A13 of The C programming language, 2nd edition, by Brian W. Kernighan and Dennis M.
Ritchie,Prentice Hall, 1988.
Programação Básica com Linguagem C 238
Fonte: https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm
Programação Básica com Linguagem C 239
Os conceitos abaixo buscam definir os termos mas não orienta como construir
algoritmos ou mesmo programa de computador.
Algoritmo é uma sequência finita de instruções.
Programa de computador é um conjunto de instruções que descrevem uma
tarefa a ser realizada por um computador.
Dada uma tarefa, como construir a sequência de instruções capaz de resolvê-la
por computador?
A resposta é: analisar a tarefa e buscar um padrão e, a partir dele, identificar a
sequência de instruções capaz de resolvê-la por computador.
Verifique que foi necessário definir escada como um conjunto de degraus, que
possui início e fim. Também foi necessário estabelecer a ação de subir um degrau.
Por fim, foi criado um método para identificar o fim da escada.
Embora estas "coisas" não estejam na pergunta, elas tiveram que ser criadas: são
Programação Básica com Linguagem C 240
Exemplo 13.3 Pode-se criar um algoritmo para contar todos os números inteiros
compreendidos entre 10 e 20?
Sim, uma possibilidade é o algoritmo:
Note que a solução deste problema é estranha para o pensamento humano: Como
eu começo com 11 e testo se é menor do que 20 logo em seguida? Não é
esquisito?
Observe que os passos 3 a 6 formam um bloco que se repete várias vezes. Os
itens 1 e 2 são executados uma única vez. Ao executar o bloco 3-6 pela segunda
vez, pela terceira vez e assim por diante, é que fica claro o algoritmo.
Este é o padrão para qualquer contagem de inteiros que tenha início e fim bem
definidos.
Note a diferença entre solução para seres humanos e para máquinas: máquinas
funcionam a partir de rotinas repetitivas, seres humanos não.
Verifique que pode existir mais de um algoritmo para resolver um problema, o
melhor dentre eles é chamado algoritmo otimizado.
Normalmente, começa-se com um algoritmo que resolve o problema e vai
melhorando-o até que ele fique otimizado.
Vale a Regra de Ouro: o que conta é o resultado.
Não confunda a Regra de Ouro com a vida em sociedade, pois a relação entre
seres humanos envolve ética e moral, onde resultados requer o uso de meios
aceitos pelo grupo.
Exemplo 13.4 Pode-se criar um algoritmo para somar todos os números inteiros
compreendidos entre a e b?
Sim, uma possibilidade é o algoritmo:
Veja que foi generalizado o padrão do exemplo anterior, para qualquer intervalo
inteiro (a,b).
Exemplo 13.5 Pode-se criar um algoritmo para contar todos os números reais
compreendidos entre 10 e 20?
No problema colocado, embora seja possível definir o início e o fim do conjunto de
números reais, existem infinitos números reais entre 10 e 20. Desta forma não tem
como definir o número de repetições para o padrão de contagem. O algoritmo não
Programação Básica com Linguagem C 242
teria fim.
Não, não há algoritmo para contar todos os números reais por computador no
intervalo indicado (ou para qualquer outro intervalo finito).
Pode-se afirmar, por outro lado, que há algoritmo para contagem aproximada de
números reais por computador de dado intervalo finito.
esperado para alguma entrada. Neste caso, dizemos que o programa contem erros
de lógica que, ao contrário dos erros de sintaxe, que são detectados pelo
compilador, são por vezes de difícil detecção.
Para aprender a programar em C e necessário que se aprenda suas
instruções (para que se conheça o que o processador e capaz de fazer), a sintaxe
de cada um destas instruções e as suas semânticas. Aliado a isto, deve-se ter um
bom desenvolvimento de lógica de programação para que escolha as instruções
necessárias e a sequência segundo a qual estas instruções devem ser escritas,
para que o programa, ao ser executado, execute a tarefa pretendida.
Felizmente ou infelizmente, para cada tarefa que se pretende, não existe apenas
uma sequência de instruções que a realize. Ou seja, dado um problema não existe
apenas um programa que o resolva.
Devemos procurar fazer o melhor programa, entendendo-se como melhor
programa um programa que tenha boa legibilidade, cuja execução demande o
menor tempo possível e que necessite, para sua execução, a utilização mínima da
memória de máquina. O melhor programa depende da experiência, habilidade e
criatividade de quem o produz.
14. Anexos
Tabela 14.1 Caracteres do código ASCII de 0 a 127, com seus valores decimais (D),
binários (B) e seus símbolos (S)
D B S D B S D B S D B S
0 00000000 NUL 32 00100000 64 01000000 @ 96 01100000 `
1 00000001 SOH 33 00100001 ! 65 01000001 A 97 01100001 a
2 00000010 STX 34 00100010 " 66 01000010 B 98 01100010 b
3 00000011 ETX 35 00100011 # 67 01000011 C 99 01100011 c
4 00000100 EOT 36 00100100 $ 68 01000100 D 100 01100100 d
5 00000101 ENQ 37 00100101 % 69 01000101 E 101 01100101 e
6 00000110 ACK 38 00100110 & 70 01000110 F 102 01100110 f
7 00000111 BEL 39 00100111 ' 71 01000111 G 103 01100111 g
8 00001000 BS 40 00101000 ( 72 01001000 H 104 01101000 h
9 00001001 HT 41 00101001 ) 73 01001001 I 105 01101001 i
10 00001010 LF 42 00101010 * 74 01001010 J 106 01101010 j
11 00001011 VT 43 00101011 + 75 01001011 K 107 01101011 k
12 00001100 FF 44 00101100 , 76 01001100 L 108 01101100 l
13 00001101 CR 45 00101101 – 77 01001101 M 109 01101101 m
14 00001110 SO 46 00101110 . 78 01001110 N 110 01101110 n
15 00001111 SI 47 00101111 / 79 01001111 O 111 01101111 o
16 00010000 DLE 48 00110000 0 80 01010000 P 112 01110000 p
17 00010001 DC1 49 00110001 1 81 01010001 Q 113 01110001 q
18 00010010 DC2 50 00110010 2 82 01010010 R 114 01110010 r
19 00010011 DC3 51 00110011 3 83 01010011 S 115 01110011 s
20 00010100 DC4 52 00110100 4 84 01010100 T 116 01110100 t
21 00010101 NAK 53 00110101 5 85 01010101 U 117 01110101 u
22 00010110 SYN 54 00110110 6 86 01010110 V 118 01110110 v
23 00010111 ETB 55 00110111 7 87 01010111 W 119 01110111 w
24 00011000 CAN 56 00111000 8 88 01011000 X 120 01111000 x
Programação Básica com Linguagem C 248
D B S D B S D B S D B S
25 00011001 EM 57 00111001 9 89 01011001 Y 121 01111001 y
26 00011010 SUB 58 00111010 : 90 01011010 Z 122 01111010 z
27 00011011 ESC 59 00111011 ; 91 01011011 [ 123 01111011 {
28 00011100 FS 60 00111100 < 92 01011100 \ 124 01111100 |
29 00011101 GS 61 00111101 = 93 01011101 ] 125 01111101 }
30 00011110 RS 62 00111110 > 94 01011110 ^ 126 01111110 ~
31 00011111 US 63 00111111 ? 95 01011111 _ 127 01111111 DEL
Tabela 14.2 Caracteres do código ASCII de 128 a 255, com seus valores decimais
(D), binários (B) e seus símbolos (S)
D B S D B S D B S D B S
128 10000000 Ç 160 10100000 á 192 11000000 └ 224 11100000 Ó
129 10000001 ü 161 10100001 í 193 11000001 ┴ 225 11100001 ß
130 10000010 é 162 10100010 ó 194 11000010 ┬ 226 11100010 Ô
131 10000011 â 163 10100011 ú 195 11000011 ├ 227 11100011 Ò
132 10000100 ä 164 10100100 ñ 196 11000100 ─ 228 11100100 õ
133 10000101 à 165 10100101 Ñ 197 11000101 ┼ 229 11100101 Õ
134 10000110 å 166 10100110 ª 198 11000110 ã 230 11100110 µ
135 10000111 ç 167 10100111 º 199 11000111 Ã 231 11100111 þ
136 10001000 ê 168 10101000 ¿ 200 11001000 ╚ 232 11101000 Þ
137 10001001 ë 169 10101001 ® 201 11001001 ╔ 233 11101001 Ú
138 10001010 è 170 10101010 ¬ 202 11001010 ╩ 234 11101010 Û
139 10001011 ï 171 10101011 ½ 203 11001011 ╦ 235 11101011 Ù
140 10001100 î 172 10101100 ¼ 204 11001100 ╠ 236 11101100 ý
141 10001101 ì 173 10101101 ¡ 205 11001101 ═ 237 11101101 Ý
142 10001110 Ä 174 10101110 « 206 11001110 ╬ 238 11101110 ¯
143 10001111 Å 175 10101111 » 207 11001111 ¤ 239 11101111 ´
144 10010000 É 176 10110000 ░ 208 11010000 ð 240 11110000 ≡
145 10010001 æ 177 10110001 ▒ 209 11010001 Ð 241 11110001 ±
146 10010010 Æ 178 10110010 ▓ 210 11010010 Ê 242 11110010 ‗
147 10010011 ô 179 10110011 │ 211 11010011 Ë 243 11110011 ¾
148 10010100 ö 180 10110100 ┤ 212 11010100 È 244 11110100 ¶
149 10010101 ò 181 10110101 Á 213 11010101 ı 245 11110101 §
150 10010110 û 182 10110110 Â 214 11010110 Í 246 11110110 ÷
151 10010111 ù 183 10110111 À 215 11010111 Î 247 11110111 ¸
152 10011000 ÿ 184 10111000 © 216 11011000 Ï 248 11111000 °
153 10011001 Ö 185 10111001 ╣ 217 11011001 ┘ 249 11111001 ¨
154 10011010 Ü 186 10111010 ║ 218 11011010 ┌ 250 11111010 ·
155 10011011 ø 187 10111011 ╗ 219 11011011 █ 251 11111011 ¹
156 10011100 £ 188 10111100 ╝ 220 11011100 ▄ 252 11111100 ³
157 10011101 Ø 189 10111101 ¢ 221 11011101 ¦ 253 11111101 ²
158 10011110 × 190 10111110 ¥ 222 11011110 Ì 254 11111110 ■
Programação Básica com Linguagem C 249
D B S D B S D B S D B S
159 10011111 ƒ 191 10111111 ┐ 223 11011111 ▀ 255 11111111 nbsp
14.2. Pseudocódigo
Pseudocódigo é uma forma genérica de escrever algoritmos, nele é utilizado
uma linguagem simples sem necessidade de conhecer a sintaxe de nenhuma
linguagem de programação. Um exemplo de pseudocódigo é o Portugol, que utiliza
o compilador Visualg (https://sourceforge.net/projects/visualg30/).
Algoritmo <nome_do_algoritmo>
<declaração de variáveis>
<subalgoritmos>
Início
<corpo do algoritmo>
Fim.
Para estudar os comandos do Portugol, consulte o Manual do Visualg 3.0,
disponível em http://visualg3.com.br/.
14.3. Fluxograma
Fluxogramas representam gráfica e sequencialmente os comandos que
compõem um algoritmo. Seus principais objetivos:
Em que:
Programação Básica com Linguagem C 252
Tabela 14.8 Componente formato do formato de E/S, seus tipos e sua descrição
Formato Tipo Descrição
d inteiro inteiro sinalizado
i inteiro inteiro sinalizado
o inteiro octal não sinalizado
u inteiro inteiro não sinalizado
x inteiro hexadecimal, com letras minúsculas
X inteiro hexadecimal, com letras maiúsculas
f ponto flutuante valor sinalizado de ponto flutuante
e ponto flutuante valor sinalizado de ponto flutuante em notação científica
g ponto flutuante alterna para f ou e, dependendo da formatação
E ponto flutuante valor sinalizado de ponto flutuante em notação científica
G ponto flutuante idem de g para e
c caractere um simples caractere
s string imprime uma cadeira de caracteres até que se encontre o
caractere "NULL"
% imprime o caractere %
n ponteiro para int armazena (no local apontado pelo argumento de entrada) a
quantidade de caracteres escritos desde então
p ponteiro imprime o argumento de entrada como um ponteiro
Exemplo 14.3 Dado o circuito lógico abaixo, faça um programa em C para calcular
a saída s em função das suas entradas.
#include <stdio.h>
int main( void ){
int a, b, c, pa, pb, s;
pa = !a;
pb = pa || b;
s = pb && c;
printf("Pino s = %d", s );
return 0;
}
Há outras maneiras de modelar problemas de circuito lógico, estes é um deles.
Exemplo 14.4 Dado o circuito lógico abaixo, faça um programa em C para calcular
a saída s em função das suas entradas.
#include <stdio.h>
int main( void ){
int a, b, c, pa, pb, s;
pa = a == 1 ? 0 : 1;
pb = (pa == 1) || (b == 1) ? 1 : 0;
s = (pb == 1) && (c == 1) ? 1 : 0;
printf("Pino s = %d", s );
return 0;
}
Esta solução usa o comando ternário.
Exemplo 14.5 Dado o circuito lógico abaixo, faça um programa em C para calcular
a saída s em função das suas entradas.
#include <stdio.h>
int main( void ){
bool a, b, c, pa, pb, s;
pa = !a;
pb = pa || b;
s = pb && c;
Programação Básica com Linguagem C 257
printf("Pino s = %d", s );
return 0;
}
Esta solução usa o tipo de dado bool.
Exercício 14.1 Faça um programa em C com uma função para calcular a saída de
cada um dos circuitos lógicos abaixo:
a)
b)
c)
d)
e)
f)
Programação Básica com Linguagem C 258
g)
h)
i)
j)
[
A= a1,0
⋮
a1,1
⋮
a1,2
⋮
am−1,0 am −1,1 am −1,2
⋯ a1 ,n−1
⋱ ⋮
⋯ a m−1 ,n−1
Estes padrões são úteis para criar algoritmos para operações com matrizes, por
exemplo:
[
a1,0
A= ⋮
al ,0
⋮
a1,1
⋮
al ,1
⋮
a1,2
⋮
al ,2
⋮
am −1,0 am −1,1 am −1,2
⋯ a1 ,c
⋮ ⋮
⋯ al , c
⋮ ⋮
⋯ a m−1 ,c
⋯ a1 , n−1
⋮ ⋮
⋯ al , n−1
⋮ ⋯
⋯ am−1 ,n−1
]
Dentre as operações com matrizes, destacam-se a soma, subtração e
multiplicação por número real.
Dadas as matrizes A e B:
[
A= a1,0
⋮
a1,1
⋮
a1,2
⋮
am−1,0 am −1,1 am −1,2
⋯ a1 ,n−1
⋱ ⋮
⋯ a m−1 ,n−1
[
C= a 1,0 +b1,0
⋮
a1,1 + b1,1
⋮
a1,2 +b1,2
⋮
a m−1,0 +bm−1,0 am −1,1 + bm−1,1 am−1,2 +bm −1,2
[
S= a1,0 −b1,0
⋮
a1,1 −b1,1
⋮
a1,2 −b1,2
⋮
am−1,0 −bm−1,0 am−1,1 −bm −1,1 am−1,2 −bm−1,2
⋯
⋱
a 1, n−1−b1 , n−1
⋮
⋯ a m−1, n−1−b m−1, n−1
O produto de um número real k pela matriz A é uma outra matriz P, dada por:
]
k×a0,0 k×a 0,1 k ×a 0,2 ⋯ k ×a 0 ,n−1
[
P=kA= k×a1,0
⋮
k×a1,1
⋮
k ×a 1,2
⋮
k ×am −1,0 k ×am−1,1 k×am−1,2
⋯ k×a 1 ,n−1
⋱ ⋮
⋯ k ×am−1 , n−1 ]
2 1 0 0 1 3
Exemplo 14.7 Sejam
5A-3B.
[ ] [ ]
A= 5 3 0
1 2 1
e B= 1 2 2
2 0 2
, calcule C = A+B, S = A-B, P =
[
C= 5+1 3+2 0+2 = 6 5 2
1+1 2+0 1+2 2 2 3 ][ ]
Programação Básica com Linguagem C 261
Palavra Uso
Tipos e afins
auto classe de armazenamento de variável
char tipo de dados utilizado para armazenar caracteres
const cria variável atribuindo um valor que não pode ser modificado
double tipo de dado numérico de ponto flutuante - precisão dupla
enum tipo de dados definido pelo programador
extern indica que a variável foi declarada em outro arquivo
float tipo de dado de ponto flutuante com precisão simples
int tipo de dado numérico para armazenar valores inteiros
long modificador de tipo de dado int e double
register classe de armazenamento de variável
short modificador de tipo de dado int
sizeof função que retorna o tamanho do argumento
signed modificador de tipo de dado int e char
static classe de armazenamento de variável
struct cria estruturas
typedef cria novo nome para tipos de dados
union cria unions
unsigned modificador de tipo de dado int e char
void19 tipo de dado que indica ausência de parâmetro ou argumento
volatile classe de armazenamento de variável
Controle e afins
1. Alocar – destinar uma região da memória principal a uma variável ou constante para
uso exclusivo do programa de computador que a criou.
2. Arquivo Executável – arquivo no formato binário e pode ser executado por um
processador - CPU.
3. ASCII – American Standard Code for Information Interchange, é uma codificação de
caracteres de oito bits baseada no alfabeto inglês, utilizado para representar textos
em computadores, equipamentos de comunicação, entre outros dispositivos que
trabalham com texto.
4. Biblioteca Padrão – conjunto de funções que dão suporte a Programas C. Estas
funções incluem todas as operações de Entrada/Saída, bem como outras rotinas
úteis.
5. Bit – {0,1}, sinal elétrico ou magnético baixo (0) ou alto (1). Qualquer coisa que seja
dual, duplo, polarizado e que pode ser transformado em tecnologia.
6. Bloco – região do código delimitado por chaves, seu início começa com a chave
abrindo ({) e seu fim é definido pela chave fechando (}).
7. Booleano – valor lógico {false, true}.
8. Byte – conjunto de oito bits, octeto binário.
9. Classe de armazenamento – refere-se ao tempo de vida de uma variável (temporário
ou permanente)
10.Código Fonte – arquivo no formato de texto, escrito em uma linguagem de
programação.
11.Código Objeto – código gerado após a compilação do código fonte, código
intermediário pois deve ser processado pelo linker para gerar o arquivo executável
ou a biblioteca.
12.Condição – expressão booleana das estruturas condicional e de repetição.
13.Escopo – região que contém declarações, cada declaração adiciona um nome ao
escopo, estes nomes são visíveis apenas nesta região, fora dela são invisíveis. Para o
escopo local temos que a região é um bloco e no escopo global a região é o
programa ou um arquivo do programa.
14.Estrutura –
15.Flag - em programação são interruptores, podendo assumir os valores lógicos {false,
true}. São utilizados, em geral, em estruturas condicional e de repetição.
Programação Básica com Linguagem C 264
16. Bibliografia