0% acharam este documento útil (0 voto)
103 visualizações226 páginas

12 AiB Algoritmia+LingC

Este documento apresenta os conceitos fundamentais da programação e da linguagem C. Aborda tópicos como algoritmia, fluxogramas, sintaxe, semântica e tipos de dados em C, e fornece exemplos de como resolver problemas através da programação.

Enviado por

Pedro Fernandes
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
103 visualizações226 páginas

12 AiB Algoritmia+LingC

Este documento apresenta os conceitos fundamentais da programação e da linguagem C. Aborda tópicos como algoritmia, fluxogramas, sintaxe, semântica e tipos de dados em C, e fornece exemplos de como resolver problemas através da programação.

Enviado por

Pedro Fernandes
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 226

AI-B

Aplicações Informáticas B

Introdução à programação
(Algoritmia + Linguagem C)
Atualizado em 21/09/2022

Escola Secundária de Barcelos


Curso Científico-Humanístico de Ciências e Tecnologias
Tópico

“Todas as pessoas deveriam


aprender a programar, pois
ensina a pensar”
Steve Jobs, fundador da Apple

2 25/09/2022
Conteúdos e objetivos
 Conceitos de Linguagem, Sintaxe, Semântica, Gramática e
Expressão.
 Conceito de algoritmo: compreender a noção de algoritmo.
 Elaborar algoritmos simples através de pseudocódigo,
fluxogramas e linguagem natural.
 Distinção e identificação de linguagens naturais e linguagens
formais.
 Utilizar de uma linguagem de programação imperativa
codificada para elaborar programas simples, em ambiente de
consola.
 Identificar e utilizar diferentes tipos de dados em programas.
 Reconhecer diferentes operadores aritméticos, lógicos,
3 relacionais e respetivas regras de prioridade. 25/09/2022
Conteúdos e objetivos
 Desenvolver programas que incluam estruturas de controlo
de seleção e estruturas repetitivas com vista à resolução de
problemas de baixa complexidade.
 Utilizar funções em programas.
 Distinguir diferentes formas de passagem de parâmetros a
funções.
 Executar operações básicas com arrays.
 Estudo e utilização de um ambiente integrado de
desenvolvimento de programas para edição, compilação e
teste de programas.
 Implementar Algoritmos de complexidade crescente.

4 25/09/2022
Ferramentas/recursos a utilizar
 Algoritmia (Análise de problemas e pseudocódigo)
Notepad (Bloco de Notas do Windows ou equivalente)
 Dia (desenho de Fluxogramas)
https://projects.gnome.org/dia/
 Codeblocks (Ambiente de desenvolvimento C/C++)
http://www.codeblocks.org/
 Outras ferramentas alternativas e/ou complementares
 Notepad++ (Editor de Linguagens de programação)
http://notepad-plus-plus.org/
 CygWin – Ferramentas GNU e Open Source similar a uma distribuição
Linux (Linha de comandos, Compilador C/C++, etc.) integrável no
Codeblocks
https://cygwin.com/
5 25/09/2022
Definição de Linguagem
 Linguagem é o sistema através do qual o homem comunica as
suas ideias e sentimentos, seja pela fala, escrita ou outros
meios convencionais.
 As linguagens artificiais (criadas para um fim específico, tal
como, a lógica matemática ou a informática) também são
designadas por linguagens formais.
 A linguagem de programação de computadores é uma
linguagem formal que consiste em códigos e regras
específicas que correspondem a instruções para
computadores.

6 25/09/2022
Sintaxe
 Sintaxe é a forma como as instruções de uma linguagem são
escritas, mas sem atender ao seu significado.
 Na sintaxe de uma linguagem de programação existem
descrições formais, que são chamadas de lexemas. Os
lexemas de uma LP incluem os seus identificadores, palavras
reservadas, literais e operadores.
 Um símbolo de uma linguagem é uma categoria de lexemas e
é denominado token.
 As gramáticas descrevem naturalmente a estrutura sintática
hierárquica das linguagens que definem. Estas estruturas são
designadas por árvores de análise.

7 25/09/2022
Semântica
 A Semântica é complementar a sintaxe. Corresponde à
descrição do significado das instruções válidas de uma
linguagem.
 Por exemplo, a sintaxe da instrução if da linguagem C é:
if () {}
e sua semântica é:
“se o valor da expressão for verdadeiro, as instruções
incorporadas serão executadas pelo programa”.
 É através da semântica que se consegue utilizar melhor e
validar uma linguagem.

8 25/09/2022
Algoritmia e Fluxogramas
 Um algoritmo é uma sequência finita de instruções bem definidas
e não ambíguas, cada uma das quais pode ser executada
mecanicamente num período de tempo finito e com uma
quantidade de esforço finita.
 O conceito de algoritmo é frequentemente ilustrado pelo
exemplo de uma receita culinária, embora muitos algoritmos
sejam mais complexos.
 Eles podem repetir passos (fazer iterações) ou necessitar de
decisões (tais como comparações ou lógica) até que a tarefa seja
completada.
 Um algoritmo corretamente executado não irá resolver um
problema se estiver implementado incorretamente ou se não for
apropriado ao problema.

9 25/09/2022
Algoritmo
 Um algoritmo não representa, necessariamente, um programa de
computador, mas sim os passos necessários para realizar uma tarefa.
 A sua implementação pode ser feita por um computador, por outro tipo
de autómato ou mesmo por um ser humano.
 Diferentes algoritmos podem realizar a mesma tarefa usando um
conjunto diferenciado de instruções em mais ou menos tempo, espaço
ou esforço do que outros.
 Tal diferença pode ser reflexo da complexidade computacional aplicada,
que depende de estruturas de dados adequadas ao algoritmo.
 Por exemplo, um algoritmo para vestir pode especificar que se vista
primeiro as meias e os sapatos antes de vestir as calças enquanto outro
algoritmo especifica que se deve primeiro vestir as calças e depois as
meias e os sapatos.
 É claro que o primeiro algoritmo é mais difícil de executar que o
segundo apesar de ambos conduzirem ao mesmo resultado.

10 25/09/2022
Outros exemplos algorítmicos
1. Preparar um bolo
2. Trocar um pneu de um automóvel
3. Apertar os atacadores dos sapatos
4. Andar de bicicleta
5. Levantar dinheiro numa caixa Multibanco
6. Etc..

11 25/09/2022
Programa de computador
 Um programa de computador é essencialmente um algoritmo que
diz ao computador os passos específicos e em que ordem eles
devem ser executados, como por exemplo, os passos a serem
tomados para calcular as notas que serão impressas nos boletins
dos alunos de uma escola.
 Logo, o algoritmo pode ser considerado uma sequência de
operações que podem ser simuladas por uma máquina de Turing
completa.
 Quando os procedimentos de um algoritmo envolvem o
processamento de dados, a informação é lida de uma fonte de
entrada, processada e retornada sob novo valor após
processamento, o que geralmente é realizado com o auxílio de
uma ou mais estrutura de dados.

12 25/09/2022
Implementação
 A maioria dos algoritmos é desenvolvida para ser implementada
em um programa de computador.
 Apesar disso eles também podem ser implementados por outros
modos tais como
 uma rede neural biológica (tal como no cérebro quando
efetuamos operações aritméticas)
 em circuitos elétricos ou
 até mesmo em dispositivos mecânicos.
 Para programas de computador existe uma grande variedade de
linguagens de programação, cada uma com características
específicas que podem facilitar a implementação de determinados
algoritmos ou atender a propósitos mais gerais.

13 25/09/2022
Conceito de Fluxograma
 A maneira mais simples de se pensar um algoritmo é como
uma lista de procedimentos bem definida, na qual as
instruções são executadas passo a passo a partir do começo da
lista.
 Esta ideia que pode ser facilmente visualizada através de um
fluxograma.
 Fluxograma é um tipo de diagrama que pode ser entendido
como uma representação esquemática de um processo,
muitas vezes feito através de gráficos que ilustram de forma
simplificada a transição de informações entre os elementos
que o compõem.

14 25/09/2022
Fluxograma algorítmico simples

15 25/09/2022
Fluxograma para troca de meias

16 25/09/2022
Símbolos de um fluxograma
Iniciador Ponto de conexão
Terminador
Linha

Entrada e/ou
saída de dados
Seta

Processo Conexão unidirecional


em ângulos retos

Decisão Conexão em
ângulos retos

17 25/09/2022
Como abordar um problema
 Um meio de exibir um algoritmo é através da implementação
por pseudocódigo em português estruturado.
 Os passos a dar para obter a sequência de ações para executar
uma tarefa:
1. Determinar qual deve ser a saída.
2. Identificar os dados, ou entrada, necessária para obter a saída.
3. Determinar como processar a entrada para obter a saída
desejada.
 Representação esquemática:

Entrada de Saída de
Processamento
dados dados
18 25/09/2022
Exemplo: fazer um bolo de maçã
 Saída
bolo de maçã
 Entrada
ingredientes e respetivas quantidades que são
determinados por aquilo que se quer fazer
 Processamento
a receita indica os passos a dar, ou seja, como se deve
proceder para preparar o bolo (misturar os ingredientes
na quantidade certa e na ordem correta, levar ao forno
a uma dada temperatura durante um determinado
período de tempo)

19 25/09/2022
Exemplo prático: Problema
 Considere-se o seguinte problema:
 Dados 2 números inteiros, calcular a sua soma.
 Resultados pretendidos no problema
 1 número inteiro que seja a soma dos 2 números dados
 Dados de entrada do problema
 2 números inteiros (por exemplo, o numA e o numB)
 Ação pretendida
 Somar os dois números: “soma  numA + numB”
 A expressão “soma  numA + numB” significa:
a variável soma toma o valor da adição do valor da variável
numA com o valor da variável numB
20 25/09/2022
Exemplo prático: Análise do problema

Entrada de Saída de
Processamento
dados dados

numA
numB

soma  numA + numB

soma

21 25/09/2022
Exemplo prático: Fluxograma
Na passagem da análise do
problema para o fluxograma
terão que ser
lidos valores para as
variáveis de entrada e
no final
escrever os valores das
variáveis de saída.

22 25/09/2022
Exemplo prático: Pseudocódigo
Algoritmo Soma2Inteiros
Variáveis
soma,numA,numB: Inteiro
Inicio
Ler(numA)
Ler(numB)
soma  numA + numB Na passagem do fluxograma
para o pseudocódigo as
Escrever(soma)
variáveis terão de
Fim ser declaradas.

23 25/09/2022
Exemplo prático: Linguagem C
#include <stdio.h>
int numA, numB, soma;
int main()
{
Na passagem do printf("Digite um numero: ");
pseudocódigo para o scanf("%i", &numA);
código C deverão ser
adicionadas printf("Digite outro numero: ");
mensagens de scanf("%i", &numB);
comunicação soma = numA + numB;
com o utilizador
do programa. printf("A soma e’ %i", soma);
return 0;
}
24 25/09/2022
Exercício 1
 Cada aluno deverá recorrer às ferramentas indicadas no início para
editar a solução do problema atrás apresentado de modo a treinar
a utilização destas ferramentas. O aluno deverá:
1. Abrir um documento no Bloco de Notas (ou Notepad++),
denominado “Algoritmo.txt” onde deverá registar o enunciado do
problema e efetuar a respetiva análise.
2. Criar um documento com a aplicação Dia, denominado
“Fluxograma.dia”, onde deverá desenhar o fluxograma do
problema referido.
3. Acrescentar ao documento “Algoritmo.txt” o pseudocódigo da
resolução do problema.
4. Criar um projeto em Codeblocks, denominado “Soma2Numeros”,
onde deverá implementar a solução do problema em linguagem C.

25 25/09/2022
Exercício 2
 Criar um programa que dado um número inteiro
calcule o seu dobro.
a) Análise do problema:
Entrada → Processamento → Saída
b) Fluxograma
c) Pseudocódigo
d) Código em Linguagem C
 Nota: A multiplicação representa-se
 em pseudocódigo por x (letra xis)
 e em linguagem C por * (asterisco)

26 25/09/2022
Pseudocódigo: atribuição
 Quando escrevemos código em português também
utilizamos símbolos na forma de pontuação e caracteres
especiais.
 Sem estes seria difícil representar tudo o que é necessário
numa linguagem de programação.
 Por exemplo, para representar a atribuição de valores a
variáveis, tal como foi visto anteriormente, usam-se símbolos
tais como ←, << ou <-, designados como operadores de
atribuição.
soma <- numA + numB

27 25/09/2022
Pseudocódigo: palavras reservadas
 Há um conjunto de palavras chave que podem ser utilizadas em
pseudocódigo tal como são usadas em linguagens de programação.
 Estas podem indicar operações de entrada ou saída de dados, ou
ainda operações de processamento.
 Também são utilizadas para nomear variáveis e respetivos tipos de
dados.
 Por exemplo, a palavra “Ler” pode ser utilizada para representar o
ato de ler alguma informação a partir do teclado do computador
ou a partir de um ficheiro alojado nalgum tipo de dispositivo de
armazenamento de informação (disco, rede, etc.):
Ler(numA)

28 25/09/2022
Pseudocódigo: tipos de dados
 O tipo de dados pretende dizer ao programa de computador como
se pretende que determinado dado seja tratado.
 Por exemplo, o dado “21032020” pode ser
 um número de Cartão de Cidadão (identifica um cidadão e pode ser
usado para pesquisa ou ordenação),
 uma data (21 de março de 2020)
 ou um valor numérico sobre o qual se podem realizar cálculos.
 É de máxima importância dizer ao programa como se pretende que
os dados sejam tratados por isso se deve especificar os tipos de dados
a utilizar.
 Dados numéricos do tipo inteiro, declaram-se:
Inteiro numA, numB, soma
ou
numA, numB, soma: Inteiro
29 25/09/2022
Exercício 3 (total com IVA)
 Dado o preço unitário de um produto e a respetiva
quantidade, calcular o total a pagar considerando que o IVA é
23%.
 Algumas notas ao problema:
 23%  23 / 100 = 0,23
 Valores monetários são do tipo real, pelo que as variáveis devem
ser declaradas:
Pseudocódigo Linguagem C
preço: Real float preco;

 IVA é um valor constante pelo que se deve declarar como tal:


Pseudocódigo Linguagem C
Constantes #define IVA 0.23
30 IVA = 0.23 const float IVA = 0.23; 25/09/2022
Exercício 3 (distância percorrida)
 Dada a velocidade (Km/h) a que um veículo se desloca e o
tempo (segundos) que demora no percurso, qual é a distância
percorrida (metros).
 Algumas notas ao problema:
 É necessário proceder a conversão de unidades.
 Pelo menos a distância é do tipo real, pelo que as variáveis
devem ser declaradas:
Pseudocódigo Linguagem C
distancia: Real float distancia;

 O fator de conversão de m/s para Km/h é 3600/1000 (3,6)


Pseudocódigo Linguagem C
Constantes #define FATOR 3.6
31 FATOR = 3.6 const float FATOR = 3.6; 25/09/2022
A linguagem C
 O C é uma linguagem de programação compilada de propósito geral, estruturada,
imperativa, procedimental, padronizada pela ISO, criada em 1972, por Dennis
Ritchie, no AT&T Bell Labs, para desenvolver o sistema operativo Unix (que foi
originalmente escrito em Assembly).
 O C é uma das linguagens de programação mais populares de todos os tempos.
 Existem poucas arquiteturas de computadores para as quais não existem
compiladores de C.
 O C tem influenciado, direta ou indiretamente, muitas outras linguagens de
programação, tais como, o C#, o Java, o JavaScript, o Perl, o PHP, o Python e, em
particular, o C++, que originalmente começou por ser uma extensão para C.
 Em 1989 foi publicado o primeiro padrão da Linguagem C pelo ANSI (American
National Standards Institute), geralmente denominado “ANSI C” ou “C89”, tendo
sido no ano seguinte aprovado pela ISO (International Organization for
Standardization).
 Na década de 1990 foram corrigidos alguns detalhes sendo publicado em 1999 o
padrão C99 (ISSO/IEC 9899:1999).
 Após algumas revisões da ISO, a última ocorreu em dezembro de 2011 e
denomina-se “C11”.
32 25/09/2022
Sintaxe e convenções léxicas
 A linguagem C possui uma gramática formal especificada pelo
padrão C.
 Ao contrário de outras linguagens, o código fonte C tem forma
livre, ou seja, permite a utilização livre de espaços para
formatar o código em vez de ser baseada em restrições de
posicionamento em colunas ou em linhas.
 Comentários podem ser incluídos entre os delimitadores /* e
*/ (desde o padrão C99 também o resto da linha a seguir a //).
 Diferencia maiúsculas e minúsculas.
 As instruções terminam com ponto-e-vírgula (;).

33 25/09/2022
Conjunto de caracteres
 Letras: a-z, A-Z, _
 Dígitos: 0-9
 Pontuação:
~ ! # % ^ & ( ) - + = : < > , . ? | / | { } [ ]
 Caracteres de espaço: espaço, tabulação horizontal, tabulação vertical, form
feed, newline.
 Newline indica o fim de uma linha de texto; não precisa de corresponder a
um simples carácter, todavia, por conveniência o C trata-o como tal.
 Caracteres de espaço são ignorados a não ser como separadores de
palavras.
 Podem ser usados caracteres multibyte (por exemplo, Unicode
introduzido com o último padrão C11) apesar de esta característica ainda
não estar largamente implementada.

34 25/09/2022
Designação de caracteres
Caracter Designação em português Designação em inglês
" Aspa Quotation mark/quotes
' Plica/Aspa simples Apostrophe/Single quote
& E (i) comercial Ampersand
# Cardinal Number sign
$ Cifrão Dollar sign
@ Arroba At sign
; Ponto-e-vírgula Semicolon
_ Hífen Underscore
| Barra vertical Vertical bar
\ Barra de escape Backslash
/ Barra de diretório Slash

35 25/09/2022
Palavras reservadas
 O padrão C89 possui 32 palavras reservadas com significado
especial:
auto continue enum if short switch volatile
break default extern int signed typedef while
case do float long sizeof union char double for
register static unsigned const else goto return
struct void
 O padrão C99 adicionou mais 5 palavras reservadas:
_Bool _Complex _Imaginary inline restrict
 padrão C11 adicionou mais 7 palavras reservadas:
_Alignas _Alignof _Atomic _Generic _Noreturn
_Static_assert _Thread_local

36 25/09/2022
Elementos da linguagem
 Identificadores
 é uma sequência de letras, dígitos e underscores (_).
 O primeiro carácter não pode ser um dígito.
 Não podem ser usadas palavras reservadas.
 Constantes
 Inteiras (decimal, octal, hexadecimal)
 Reais (parte inteira, ponto decimal, parte fracional)
 Caracteres
 um carácter é apresentado entre plicas, tal como 'x'.
 um carácter corresponde a um inteiro (tabela de caracteres).
 Strings
 Em C, uma string é uma sequência de caracteres (array) e representa-se entre
“aspas”.
37 25/09/2022
Caracteres especiais em strings
Sequência com \ Descrição
\n Nova linha, mudança de linha (newline)
\t Tabulação horizontal
\\ Barra inclinada à esquerda (backslash)
\' Plica
\" Aspas
\? Interrogação
\a Campainha ou aviso sonoro (bell)
\0 Carácter nulo

Existem outras sequências de escape que podem não funcionar em


todos os compiladores, por isso não são aqui referenciadas.
38 25/09/2022
Primeiro programa (olá mundo!)

Linha 1 - Inclusão de código pré construído e existente em bibliotecas de código.


Linha 3 - Declaração da função principal do programa (main), por onde o sistema começa a
executar o código.
Linhas 4 e 8 - As chavetas indicam o início e fim de um bloco de instruções C.
Linha 5 - Comando que consiste na chamada à função printf, definida na biblioteca stdio.h, a
qual permite enviar texto para o ecrã/consola do sistema.
Linha 7 - Chamada ao comando return que termina a função atual (main) retornando ao
sistema o valor inteiro zero.
39 25/09/2022
Compilação separada e ligação (link)

A compilação em linha de comandos faz-se com o comando gcc no


caso do compilador da Gnu (Gnu C Compiler):
gcc –o nomePrograma nomePrograma.c

40 25/09/2022
A função printf (saída de dados)
 A função printf (que significa print formatado) escreve na saída
padrão (ecrã) uma sequência de dados formatados.
 O formato geral da função printf é:

int printf (stringDeControlo, listaDeArgumentos);

onde a stringDeControlo é uma string (sequência entre aspas) e


a listaDeArgumentos é uma sequência de expressões separadas
por vírgula.

41 25/09/2022
Especificadores de formato %
Código Significado
%c Exibe um dado carácter no ecrã
%i Exibe um inteiro no ecrã
%f Exibe um ponto flutuante em formato decimal
%s Exibe uma string (array de caracteres com terminador nulo)
%% Exibe um sinal de %
%d Exibe um inteiro em formato decimal (equivalente a %i)

printf ("%i, %f, %c, %s", 5, 2.45, 'A', "Ola mundo!");

%i → 5
%f → 2.45
%c → 'A'
%s → "Ola mundo!"
42 25/09/2022
Dicas de formatação em printf

43 25/09/2022
A função scanf (entrada de dados)
 A função scanf (que significa scan formatado) lê da entrada
padrão (teclado) uma sequência de dados formatados.
 O formato geral da função scanf é:

int scanf (stringDeControlo, listaDeArgumentos);

onde a stringDeControlo é uma string (sequência entre aspas) e


a listaDeArgumentos é uma sequência de expressões separadas
por vírgula que representam endereços de memória. A forma
mais comum destes é representarem um endereço de uma dada
variável recorrendo ao operador &. Por exemplo,
scanf ("%i", &numero);
44 25/09/2022
Especificadores de formato %
Código Significado
%c Lê um carácter do teclado
%i Lê um inteiro do teclado
%f Lê um ponto flutuante em formato decimal
%s Lê uma string (array de caracteres com terminador nulo)
%% Lê um sinal de %
%d Lê um inteiro em formato decimal (equivalente a %i)

scanf ("%i, %f, %c, %s", &a, &x, &c, str);

%i → coloca inteiro lido no endereço de a


%f → coloca real lido no endereço de x
%c → coloca carácter lido no endereço de c
%s → coloca string lida (sem espaços) em str (é endereço)
45 25/09/2022
Dicas de formatação em scanf

46 25/09/2022
Tipos de dados básicos
 char
é geralmente usado para conter valores definidos pelo conjunto de caracteres
ASCII. Valores fora desta gama podem ser manuseados de modo diferente por
diferentes compiladores.
 int
usado para conter números inteiros, negativos ou positivos. A gama de valores
permitida por este tipo pode variar entre compiladores, sendo em geral, 32 bits.
 float
usado para conter números reais no formato de vírgula flutuante, na notação
normal.
 double
usado para conter números reais no formato de vírgula flutuante, na notação
científica, ou seja, com expoente base 10.
 void
usado essencialmente em dois tipos de casos: declaração de funções que não
retornam qualquer valor (procedimento) ou para representar apontadores
genéricos, ou seja, que apontam para qualquer tipo de dados.

47 25/09/2022
Tipos de dados numéricos
Tipo de Tamanho Especi-
Descrição (precisão)
dados (bytes) -ficador
char 1 %c|%d|%i Inteiro ou caracter
short 2 %d|%i Inteiro curto
int 4 %d|%i Inteiro
long 4 ou 8 %ld Inteiro longo
long long 8 %lld Inteiro extra longo
float 4 %f Número real em vírgula-flutuante (6)
double 8 %f Número real em vírgula-flutuante longo (10)
long double 8 ou 16 %Lf Número real em vírgula-flutuante extra longo (10)

No caso dos tipos reais: float, double e long double, pode-se usar o
especificador %g ou %G para que o número seja exibido em notação
científica: 1234.56 será exibido como 1.234560E+003 25/09/2022
48
Inteiros com sinal
 Por defeito todos os tipos inteiros em linguagem C são com
sinal (valores negativos e positivos)
 Tal pode ser explicitamente especificado recorrendo à palavra
chave signed:
signed char sc; // -128 … +128
signed short ss; // -32768 … +32767
signed int si; // -2^31 … 2^31-1
signed long sl; // -2^31 … 2^31-1
signed long long sll; // -2^63 … 2^63-1
 Pelo que o uso da palavra reservada signed é opcional, não
sendo habitualmente usada.

49 25/09/2022
Inteiros sem sinal
 Se só é necessário guardar valores inteiros positivos, os tipos
inteiros podem ser declarados como unsigned (sem sinal),
permitindo assim duplicar a gama de valores permitidos:
unsigned char uc; // 0 … +255
unsigned short us; // 0 … +65535
unsigned int ui; // 0 … 2^32-1
unsigned long ul; // 0 … 2^32-1
unsigned long long ull; // 0 … 2^64-1
 Os especificadores a utilizar nas funções printf e scanf são,
respetivamente:
Tipo de dados Especificador
unsigned char, short ou int %u
unsigned long %lu
50 unsigned long long %llu 25/09/2022
Variáveis em C
 Uma variável uma localização em memória a que se atribui
um nome e que é usada para armazenar um valor que pode
ser modificado pelo programa.
 Todas as variáveis devem ser declaradas antes de poderem ser
usadas.
 A forma geral de uma declaração é:
tipo lista_de_variáveis;
onde tipo deve ser um tipo válido eventualmente combinado
com modificadores, e a lista_de_variáveis pode consistir num
ou mais nomes identificadores, separados por vírgula.

51 25/09/2022
Declaração de variáveis
 Alguns exemplos de declarações:
int i, j, k;
short int si;
unsigned int ui;
double custo, lucro, perda;
 Na declaração de variáveis pode-se fazer simultaneamente a
respetiva inicialização:
tipo nomeDaVariável = valor;
 Alguns exemplos:
char c = 'a';
int primeiro = 0;
float custo = 132.25;

52 25/09/2022
Nomes das variáveis
 Os nomes das variáveis não têm nada a ver com o seu tipo.
 Devem ser descritivos do seu conteúdo.
 Deve-se ter em conta que os nomes de variáveis:
 só se podem usar letras, números e o underscore;
 só podem começar por uma letra ou underscore;
 maiúsculas e minúsculas são diferentes.
 Por exemplo,
 nome1, menorCusto e _letra são nomes válidos
 maior-custo, 2nome e digito? não são nomes válidos

53 25/09/2022
Constantes em linguagem C
 A primeira consiste no recurso ao pré-compilador, o qual, procede a
substituições de código antes de este ser compilado.
 Para declarar a variável PI com o valor 3.14, fica:
#define PI 3.14
 Sempre que em qualquer parte do programa for referido o nome da
constante (PI), o pré-compilador faz em cada um desses locais uma
substituição da palavra PI pelo valor respetivo.
 Alternativamente, pode-se definir uma constante recorrendo à
palavra reservada const (introduzida com o padrão C89), que é um
modificador de acesso, a qual é processada pelo compilador e não
pelo pré-compilador.
 Para fazer uma declaração equivalente à anterior, ficaria:
const float PI = 3.14;
que é a declaração de uma variável cujo valor inicial não pode ser
54 alterado. 25/09/2022
Constantes: nota importante
 A declaração de uma constante no pré-compilador, sendo a
forma inicial de declarar constantes, tem a vantagem de não
consumir recursos de memória, pelo que é vantajosa em
sistemas com recursos limitados (por exemplo,
microcontroladores).
 A declaração recorrendo a alocação de memória para a
constante não permite a utilização da constante em declaração
de variáveis globais, só podendo ser utilizada dentro de funções,
incluindo a função main.
const int MAX = 100;
int lista[MAX]; //error: variably modified 'lista' at file scope

55 25/09/2022
Resumo
Pseudocódigo Linguagem C
Algoritmo Título #include <stdio.h>
Constantes #define NOMEC valor
NOMEC = valor
Variáveis tipo nomeV;
nomeV: Tipo
Início int main()
Instruções {
Fim Instruções;
}
56 25/09/2022
Expressões em C
 As expressões em C, são substancialmente mais gerais e mais
poderosas do que na maioria das outras linguagens de
programação.
 As expressões são formadas a partir dos elementos atómicos:
dados e operadores.
 Os dados podem ser representados por variáveis ou por
constantes.
 Quanto aos operadores, o C possui também uma rica coleção
que será apresentada em seguida, onde se apresentarão
exemplos diversos, ilustrativos de como se constroem as
expressões em C.

57 25/09/2022
Operadores em C
 Aritméticos
+, -, *, /, %
 Atribuição
=, +=, -=, *=, /=, %=
 Incremento/decremento
++, --
 Comparação
==,!=, <, >, <=, >=
 Lógicos
!, &&, ||
 de Bits
&, |, ~, ^, <<, >>
58 25/09/2022
Operadores aritméticos
Operador Descrição Exemplo
- Negação (simétrico de um número) res = -a
+ Adição (soma de dois números) res = a + b
- Subtração (diferença entre dois números) res = a - b
* Multiplicação (produto de dois números) res = a * b
/ Divisão (quociente da divisão inteira) res = a / b
% Resto da divisão inteira (módulo) res = a % b

59 25/09/2022
Operadores aritméticos: notas
 A divisão em linguagem C pode ser inteira:
5 / 2 = 2 (5 % 2 = 1)
 Ou pode ser real:
5.0 / 2 = 2.5
 A diferença entre uma e outra está no tipo de dados dos seus
operandos:
 se os dois são inteiros (5 e 2) realiza-se uma divisão inteira
(podendo obter-se também o resto da divisão recorrendo ao
operador %.
 Se pelo menos um dos operandos é real (5.0 e/ou 2.0), realiza-se
uma divisão real (neste caso o resto da divisão deixa de fazer
sentido).

60 25/09/2022
Outros operadores de atribuição

Operador Descrição Exemplo


= Atribuição simples num = num + 2;
+= Atribuição com soma num += 2;
-= Atribuição com subtração num -= 2;
*= Atribuição com multiplicação num *= 2;
/= Atribuição com divisão num /= 2;
%= Atribuição com módulo num %= 2;

61 25/09/2022
Operadores de atribuição: notas
 A variável do lado esquerdo do operador de atribuição,
quando este for composto (+=, -=, *=, /= ou %=, etc.),
recebe como valor o seu atual valor operacionado com todo o
lado direito da expressão. Por exemplo:
x += a + b / 2;
é equivalente a
x = x + (a + b / 2);
não esquecendo de reparar na utilização do parênteses.
 Aconteceria exatamente o mesmo com qualquer outro
operador que fosse emparelhado com a atribuição.

62 25/09/2022
Resumo
Pseudocódigo Linguagem C
Atribuição ← ou <- =, +=, -=, *=, /=, %=
Operador adição + +
Operador subtração - -
Operador multiplicação x *
Operador divisão inteira DIV /
Operador resto da divisão MOD %
Operador divisão real / /

Notas:
5 DIV 2 = 2
5 MOD 2 = 1
5 / 2 = 2.5
Em C, a divisão só é real se pelo menos um dos operandos é um número real.

63 25/09/2022
Resumo (continuação)
 Declaração de variáveis
Pseudocódigo Linguagem C
Variáveis // Variáveis
num, alturaMax: Inteiro int num, alturaMax;
custoUnitario, iva: Real float custoUnitario, iva;

 Declaração de constantes
Pseudocódigo Linguagem C
Constantes // Constantes
PI = 3.14 #define PI 3.14
TAMANHO = 100 #define TAMANHO 100
// Alternativamente
const float PI = 3.14;
const int TAMANHO = 100;

64 25/09/2022
Estruturas de controlo
 Um programa de computador é um conjunto de instruções
sequenciais, que define as ações a serem executadas e a
ordem pela qual essas ações devem ser executadas.
 Essas ações incluem o que se chama transferência de
controlo, que permite que a instrução a ser executada não
seja a imediatamente a seguir, passando o controlo para outra
instrução ou bloco de instruções escrito noutra parte do
programa.
 A transferência de controlo permite a ramificação dos
programas, representando sequências possíveis de instruções
que o computador haverá de executar, dependendo da
satisfação ou não das condições requeridas.

65 25/09/2022
Tipos de estruturas de controlo
 Estruturas de sequência
 as ações são executadas, uma de cada vez, de forma encadeada,
na ordem definida no algoritmo/programa (ver exemplo da
soma de 2 números inteiros)
 Estruturas de seleção
 a partir da verificação de uma condição, o programa realiza ou
não uma ação e volta à sequência normal do
algoritmo/programa.
 Estruturas de repetição
 um bloco de ações é repetido um número de vezes conforme se
deseje, e em seguida o controlo volta à sequência normal do
algoritmo/programa.

66 25/09/2022
Estrutura de controlo de sequência
 As instruções/ações sucedem-se numa determinada sequência

instrução1;
instrução2;
...
...
...
instruçãoN;

67 25/09/2022
Exemplo (estrutura sequencial)
 Enunciado:
Dados 2 números apresentar a sua soma.
 Análise do problema:

numA
soma  numA + numB soma
numB

68 25/09/2022
Fluxograma

69 25/09/2022
Pseudocódigo
Algoritmo Soma2Inteiros
Variáveis
numA, numB, soma: Inteiro

Inicio
Ler (numA)
Ler (numB)
soma  numA + numB
Escrever (soma)
Fim

70 25/09/2022
Código em linguagem C
#include <stdio.h>
// Declaração de variáveis
int numA, numB, soma;
void main()
{
// Entrada de dados
printf ("Indique um número inteiro: ");
scanf ("%i", &numA);
printf ("Indique outro número inteiro: ");
scanf ("%i", &numB);
// Processamento
soma = numA + numB;
// Saída de resultados
printf ("%i + %i = %i", numA, numB, soma);
}
71 25/09/2022
Estruturas de controlo de seleção (if)
 Esta estrutura permite realizar diferentes ações dependendo
de uma condição ser verdadeira ou falsa.
 Uma condição é uma expressão cuja valor pode ser um valor
boleano (verdadeiro/falso).
 Exemplos da linguagem comum:
 “Se ainda houver bilhetes, vou ao cinema.”
 “Se hoje chover, levo guarda-chuva; se não chover levo chapéu
de sol.”
 “Se chegar em primeiro lugar, ganho a medalha de ouro; senão
se chegar em segundo lugar, ganho a medalha de prata; senão se
chegar em terceiro lugar, ganho a medalha de bronze; senão não
ganho nada”.

72 25/09/2022
Seleção simples (if)
 A instrução/ação só se realiza se se verificar uma determinada
condição.

Se condição Então if (condição)


instruções {
FimSe instruções;
}

73 25/09/2022
Seleção (if - else)
 A instrução1/ação1 só se realiza se se verificar uma determinada
condição, caso contrário, realiza-se a outra (instrução2/ação2).
if (condição)
Se condição Então {
instruções1 instruções1;
Senão }
instruções2 else
FimSe {
instruções2;
}

74 25/09/2022
Seleção múltipla (if - else if - else)
 A instrução1/ação1 só se realiza se se verificar a condição1, caso
contrário, se a condição2 se verifica, realiza-se a instrução2/ação2,
senão realiza-se a instrução3/ação3.
if (condição1)
Se condição1 Então {
instruções1 instruções1;
Senão Se condição2 Então }
instruções2 else if (condição2)
Senão {
instruções3 instruções2;
FimSe }
else
{
instruções3;
}

75 25/09/2022
Seleção múltipla (if - else if - else)

 Novas condições podem ser encadeadas de modo semelhante


num número só limitado pela lógica do problema a resolver.
76 25/09/2022
Exemplo (estrutura Se-Então-Senão)
 Enunciado:
Dados 2 números inteiros calcular qual é o maior dos dois.
 Análise do problema:

Se num1 > num2 Então


maior  num1
num1
Senão maior
num2
maior  num2
FimSe

77 25/09/2022
Fluxograma

78 25/09/2022
Pseudocódigo
Algoritmo MaiorDe2Inteiros
Variáveis
num1, num2, maior: Inteiro

Inicio
Ler (num1)
Ler (num2)
Se num1 > num2 Então
maior  num1
Senão
maior  num2
FimSe
Escrever (maior)
Fim

79 25/09/2022
Código em linguagem C
#include <stdio.h>
int num1, num2, maior;

void main()
{
printf ("Indique um número inteiro: ");
scanf ("%i", &num1);
printf ("Indique outro número inteiro: ");
scanf ("%i", &num2);
if (num1 > num2)
maior = num1;
else
maior = num2;
printf("O maior de %i e %i e' %i.\n", num1, num2,
maior);
}
80 25/09/2022
Notar que…
 Quando temos uma única instrução, a estrutura if não precisa
de chavetas
if (num1 > num2)
maior = num1;
else
maior = num2;
 Quando há mais que 1 instrução é obrigatório usar chavetas:
if (num1 > num2)
{
maior = num1;
menor = num2;
}
else
...
81 25/09/2022
Operadores relacionais (de comparação)
Operador Descrição Exemplo
== Igual a a == b
!= Diferente de a != b
< Menor que a < b
> Maior que a > b
<= Menor ou igual a a <= b
>= Maior ou igual a a >= b

82 25/09/2022
Operadores relacionais: notas
 Alguns exemplos de avaliação de expressões com operadores
relacionais:
Expressão Leitura Valor lógico
5 == 6 5 igual a 6 Falso
5 != 6 5 diferente de 6 Verdadeiro
5 < 6 5 menor que 6 Verdadeiro
5 > 6 5 maior que 6 Falso
5 <= 6 5 menor ou igual a 6 Verdadeiro
5 >= 6 5 maior ou igual a 6 Falso

83 25/09/2022
Operadores lógicos
Considerar as variáveis
int a = 1; // verdadeiro
int b = 0; // falso
int res; // resultado

Operador Descrição Exemplo


! Negação res = !a; //falso
&& E lógico (AND) res = a && b; //falso
|| Ou lógico (OR) res = a || b; //verdadeiro

Tabela de ! Tabela de && Tabela de ||


!V = F V && V = V V || V = V
!F = V V && F = F V || F = V
F && V = F F || V = V
F && F = F F || F = F
84 25/09/2022
Operadores lógicos: notas
 Os operadores lógicos são utilizados em geral em
combinação com os operadores relacionais, apesar de
poderem ser utilizados sozinhos. Alguns exemplos:
Expressão Leitura Valor lógico
5 == 6 || 5 != 6 5 igual a 6 OU 5 diferente de 6 Verdadeiro
5 == 6 && 5 != 6 5 igual a 6 E 5 diferente de 6 Falso
!(5 == 6) 5 NÃO é igual a 6 Verdadeiro
!(5 < 6) 5 NÃO é menor que 6 Falso

85 25/09/2022
Tipo Booleano em linguagem C
 A linguagem C não possuía inicialmente um tipo de dados
lógico/booleano, ou seja, não possui um tipo de dados que assuma
só 2 valores: Verdadeiro ou Falso.
 Em C, o valor inteiro 0 e todos os equivalentes são considerados
logicamente falsos (0, 0.0, '\0').
 Todos os valores diferentes de zero são considerados logicamente
verdadeiros.
 Ex:
 A variável x é verdadeira se x != 0 (x diferente de 0)
 -3 é verdadeiro
 0.0 é falso
 ′\0′ (carácter nulo) é falso

86 25/09/2022
Como criar o tipo booleano em C
 A linguagem C é tão flexível que permite simular a existência
de um tipo booleano.
 Para isso basta:
// Usar diretiva define do pré-processador de C
#define bool int
#define TRUE 1 // equivalente a: const int TRUE=1;
#define FALSE 0 // equivalente a: const int FALSE=0;

// Definição de variáveis booleanas


bool ligado = FALSE;
bool ePrimo = TRUE;

if( !ligado) ligado = TRUE; // se não está ligado, liga


if( ePrimo) printf("É Primo.");

87 25/09/2022
O tipo bool
 O padrão C99 introduziu o tipo booleano para aumentar a
compatibilidade com o C++.
 As variáveis deste tipo podem armazenar um valor booleano
cujo valor pode ser só 1 (true) ou 0 (false).
 O tipo booleano é obtido usando a palavra reservada bool
definida na biblioteca stdbool.h:
#include <stdbool.h>
bool b = true;
 Esta biblioteca também define true e false como sendo 1 e
0, respetivamente.

88 25/09/2022
Condições/expressões lógicas
 Em C podemos construir expressões lógicas ou booleanas
recorrendo a praticamente tudo;
 Todavia, os operadores relacionais e os operadores lógicos são
os principais elementos para a construção de expressões
lógicas.
 Operadores relacionais:
==, !=, <, >, <=, >=  =, ≠, <, >, ≤, ≥
 Operadores lógicos
!, &&, ||  NOT, AND, OR
 Operador (A XOR B) é equivalente a
(A || B) && !(A && B)

89 25/09/2022
Condições: exemplos
 if (x>0 && x<100) printf("%i", x);
//só imprime valores que estejam entre 1 e 99
 if (x<0 || x>100) printf("%i", x);
//só imprime valores abaixo de 0 ou acima de 100
 if (!(x<0 || x>100)) printf("%i", x);
//só imprime valores entre 0 e 100
 if (!(x<0)) printf("%i", x);
//só imprime valores positivos não nulos
 if (!(x<0) && !(x>0)) printf("%i", x);
//só imprime valores nulos

90 25/09/2022
Resumo
Operadores Relacionais Pseudocódigo Linguagem C
Igualdade = ==
Diferença <> !=
Menor < <
Maior > >
Menor ou igual <= <=
Maior ou igual >= >=

Operadores Lógicos Pseudocódigo Linguagem C


Negação (NÃO lógico) NÃO !
Conjunção (E lógico) E &&
Disjunção (OU lógico) OU ||

91 25/09/2022
Exercício (se-então-senão)
 Dado um número inteiro, se este for par, apresentar a sua
metade como resultado, senão, se este for ímpar, apresentar
o seu dobro.

Nota: um número é par se a sua divisão por 2 der resto zero.

92 25/09/2022
Exercícios extra
1. Dado um número inteiro, dizer se este é ou não par.
Número: 5
Não é par
2. Dados 3 números inteiros, calcular qual é o menor, o
médio e o maior dos 3.
3. Dado um número inteiro positivo com um máximo de 3
dígitos, dizer se este está na ordem das unidades, das
dezenas ou das centenas.
4. Dados 3 números inteiros, calcular o maior produto dois a
dois. Por exemplo,
Números: 4 2 5
Maior produto = 4 x 5 = 20

93 25/09/2022
Estruturas de controlo de seleção (switch)
 Existe ainda uma estrutura de controlo de seleção
múltipla (switch) onde:
 a estrutura verifica se o valor da variável
critério é igual a cada uma das N possibilidades
dadas por possibilidade1, possibilidade2, ... ,
possibilidadeN, e executa o bloco de instruções
correspondente;
 caso o critério seja diferente de todas as
possibilidades, o bloco de instruções alternativo
94
é executado. 25/09/2022
Estruturas de controlo de seleção (switch)

switch(critério)
{
Caso critério Seja case posibilidade1:
possibilidade1: instruções1;
instruções1 break;
possibilidade2: case possibilidade2:
instruções2 instruções2;
... break;
possibilidadeN: ...
instruçõesN case possibilidadeN:
Senão: instruçõesN;
instruçõesAlternativas break;
FimCaso default:
instruçõesAlternativas;
}

95 25/09/2022
Estruturas de controlo de seleção (switch)

96 25/09/2022
Exemplo (Estrutura Caso Seja)
 Em linguagem C só são permitidos valores de seleção inteiros ou
carateres.
 Exemplo com inteiros

Variáveis
posição: Inteiro
Início
Caso posição Seja
1: Escrever ("Ouro")
2: Escrever ("Prata")
3: Escrever ("Bronze")
Senão: Escrever ("Tente outra vez")
FimCaso
Fim

97 25/09/2022
Exemplo (Estrutura switch-case)
#include <stdio.h>
int posicao;
int main()
{
printf("Indique a posicao: ");
scanf("%i", &posicao);
switch(posicao)
{
case 1: printf("Ouro\n"); break;
case 2: printf("Prata\n"); break;
case 3: printf("Bronze\n"); break;
default: printf("Tente outra vez\n");
}
return 0;
}

98 25/09/2022
Nota
 Cada case, na estrutura switch-case, deverá seguir a seguinte
regra:
...
switch(posicao)
{
case 1:
printf("Ouro\n");
break;
case 2:
printf("Prata\n");
break;
case 3:
printf("Bronze\n");
break;
default:
printf("Tente outra vez\n");
}
...
99 25/09/2022
Exemplo (Estrutura Caso Seja)
 Exemplo com carateres:

Variáveis
letra: Caráter
Início
Caso letra Seja
′O′: Escrever ("Ouro")
′P′: Escrever ("Prata")
′B′: Escrever ("Bronze")
Senão: Escrever (“Letra inválida")
FimCaso
Fim

100 25/09/2022
Exemplo (Estrutura switch-case)
#include <stdio.h>
char letra;
int main()
{
printf("Indique uma letra: ");
scanf("%c", &letra);
switch( letra)
{
case 'o': case 'O': printf("Ouro\n"); break;
case 'p': case 'P': printf("Prata\n"); break;
case 'b': case 'B': printf(“Bronze\n"); break;
default: printf("Letra inválida\n");
}

return 0;
}

101 25/09/2022
Exercício: calculadora
 Enunciado:
Dados 2 números inteiros e 1 operador (+, -, × ou ÷) apresente o
resultado da operação que envolve os 2 números e o operador.
 Análise do problema:

Caso operador Seja


′+′: res  num1 + num2
num1 ′-′: res  num1 - num2
num2 ′x′: res  num1 x num2 res
oper ′/′: res  num1 / num2
FimCaso

102 25/09/2022
Exercício (fluxograma)

103 25/09/2022
Exercício (pseudocódigo)
Variáveis
num1, num2, res: Inteiro
operador: Caráter
Início
Ler (num1)
Ler (num2)
Ler (operador)
Caso operador Seja
′+′ :
res  num1 + num2
′-′ :
res  num1 - num2
′x′ :
res  num1 x num2
′/′ :
res  num1 / num2
FimCaso
Escrever (res)
104 Fim 25/09/2022
Exercício (código C)
#include <stdio.h>
int num1, num2, res;
char operador;

int main()
{
printf("Introduza uma expressao (a+b,a-b,axb,a/b): ");
scanf("%i%c%i", &num1, &operador, &num2);
switch (operador)
{
case '+': res = num1 + num2; break;
case '-': res = num1 - num2; break;
case 'x': res = num1 * num2; break;
case '/': res = num1 / num2; break;
}
printf("%i %c %i = %i", num1, operador, num2, res);
return 0;
}
105 25/09/2022
Exercício (instrução system)
 Criar um programa em C que apresente um Menu com
diferentes opções para execução de aplicações do sistema.
 Por defeito deve executar a Linha de comandos: “cmd.exe”.
 Para executar uma aplicação externa ao programa, a
linguagem C utiliza a função “system” que tem a seguinte
definição:
system(“nome_do_ficheiro_da_função_do_sistema");

106 25/09/2022
Exercício (continuação)
#include <stdio.h>
#include <stdlib.h> // Contem definicao da funcao "system"
char opcao;
int main()
{
printf("---------- MENU APLICACOES ----------\n");
printf("| B - Bloco de Notas (notepad.exe) |\n");
printf("| P - Microsoft Paint (mspaint.exe)|\n");
printf("| C - Calculadora (calc.exe) |\n");
printf("| ----------------------------------|\n");
printf("Opcao: "); scanf("%c", &opcao);
switch(opcao)
{
case 'b’: case 'B’: system("notepad.exe"); break;
case 'p': case 'P’: system("mspaint.exe"); break;
case 'c': case 'C': system("calc.exe"); break;
default: system("cmd.exe");
}
return 0;
}
107 25/09/2022
Resumo
 Representação literal de um carácter faz-se colocando-o
entre plicas ('). Por exemplo, o carácter 'A'.
 Tipo carácter
 Declaração em Pseudocódigo
nomeVar: Carácter
 Declaração em linguagem C
char nomeVar;
 A função system em linguagem C permite executar dentro
de um programa outros programas externos. Por exemplo,
system("cmd.exe");
executa o programa linha de comandos do Windows.

108 25/09/2022
Estruturas de controlo de repetição
 Enquanto (while) - o algoritmo/programa verifica a condição e,
se for verdadeira, executa a ação do bloco de instruções, após o
que torna a verificar a condição.
 A execução do bloco de instruções é repetida até que a condição se
torne falsa.
 Nesse caso, o controlo do programa segue para a primeira instrução
após a estrutura.
 Fazer-Enquanto (do-while) - o algoritmo/programa primeiro
executa a ação definida pelo bloco de instruções e testa a condição
depois.
 Se for verdadeira, o bloco de instruções é repetido e a condição é
novamente testada.
 Se for falsa, o programa segue para a primeira instrução após a
estrutura.

109 25/09/2022
Estruturas de controlo de repetição
(while)
Enquanto-Fazer (while)
 As instruções/ações repetem-se enquanto uma determinada
condição se verificar.

Enquanto condição Fazer while (condição)


instruções {
FimEnquanto instruções;
}

110 25/09/2022
Exemplo
 Mostrar todos os números entre 1 e 99.

n  1 n = 1;
Enquanto n < 100 Fazer while (n < 100)
Escrever(n) {
n <- n + 1 printf("%i\n", n);
FimEnquanto n = n + 1
}

 Mostrar todos os números entre 100 e 1.

n  100 n = 100;
Enquanto n >= 1 Fazer while (n >= 1)
Escrever(n) {
n  n - 1 printf("%i\n", n);
FimEnquanto n = n – 1;
}
111 25/09/2022
Exercício Enquanto-Fazer (while)
 Enunciado:
Dado um número inteiro positivo, apresentar o seu fatorial.
Notar que, por exemplo,
fatorial(0) = 1
fatorial(1) = 1
fatorial(5) = 5 x 4 x 3 x 2 x 1 = 120.
 Análise do problema:

fatorial  1
Enquanto num > 0 Fazer
num fatorial  fatorial x num fatorial
num  num – 1
FimEnquanto

112 25/09/2022
Exercício (fluxograma)

113 25/09/2022
Exercício (pseudocódigo)
Algoritmo Fatorial
Variáveis
num, fatorial: Inteiro
Início
Ler (num)
fatorial  1
Enquanto num > 0 Fazer
fatorial  fatorial x num
num  num – 1
FimEnquanto
Escrever (fatorial)
114 Fim 25/09/2022
Exercício (código C)
#include <stdio.h>
int num;
unsigned long fatorial; // Inteiro longo sem sinal

int main()
{
printf("Numero inteiro: ");
scanf("%i", &num);
//Processamento
fatorial = 1;
while(num > 0)
{
fatorial = fatorial * num;
num = num - 1;
}
// %lu significa long unsigned
printf("Fatorial = %lu\n", fatorial);
return 0;
115 } 25/09/2022
Estruturas de controlo de repetição
(do-while)
Fazer-Enquanto (do-while)
 As instruções/ações realizam-se uma vez e depois repetem-se
enquanto uma determinada condição se verificar.

Fazer do
instruções {
Enquanto condição instruções;
}while (condição);

116 25/09/2022
Exercício do-while (problema)
 Enunciado:
Dado um número natural, calcular o número dos seus divisores, sabendo
que um número natural é um inteiro positivo não nulo.
Nota: Os divisores de um número são todos os números pelos quais o
número dado é divisível, ou seja, todos os números que ao dividir o
número dado por eles obtém-se resto zero. Por exemplo:
- Os divisores de 12 são 12, 6, 4, 3, 2 e 1;
- Os divisores de 13 são 13 e 1;
- Os divisores de 21 são 21, 7, 3 e 1.
 Análise do problema:
contador  0
divisor  num
Fazer
Se num MOD divisor = 0 Então
num contador
contador  contador + 1
FimSe
divisor  divisor - 1
117 Enquanto divisor > 0 25/09/2022
Exercício do-while (Fluxograma)

118 25/09/2022
Exercício do-while (Pseudocódigo)
Algoritmo ContaDivisores
Variáveis
num, contador, divisor: Inteiro
Início
Ler (num)
contador  0
divisor  num
Fazer
Se num MOD divisor = 0 Então
contador  contador + 1
FimSe
divisor  divisor - 1
Enquanto divisor > 0
Escrever(contador)
119 Fim 25/09/2022
Exercício do-while (Código C)
#include <stdio.h>
unsigned int num, contador;
int main()
{
unsigned int divisor; // Variável auxiliar para a contagem
printf("Indique um numero natural: ");
scanf("%u", &num); // %u <=> inteiro sem sinal (unsigned)
contador = 0;
divisor = num;
do
{
if(num % divisor == 0)
contador++; //o mesmo que “contador = contador + 1”
divisor--; //o mesmo que “divisor = divisor – 1”
} while(divisor > 0);
printf("O numero %u tem %u divisores.\n", num, contador);
return 0;
}
120 25/09/2022
Operadores Incremento/Decremento
 Incremento/Decremento (só funciona com inteiros)
x++;  ++x;  aumentar o valor da variável x em 1
x--;  --x;  diminuir o valor da variável x em 1
x=3; y=++x*2;  pré-incremento (x=4, y=8)
x=3; y=x++*2;  pós-incremento (x=4, y=6)
x=3; y=--x*2;  pré-decremento (x=2, y=4)
x=3; y=x--*2;  pós-decremento (x=2, y=6)
Expressão com Inc/Dec Equivalência
x = x + 1;
y = ++x * 2;
y = x * 2;
y = x * 2;
y = x++ * 2;
x = x + 1; 25/09/2022
121
Utilização particular do-while
#include <stdio.h>
int opcao, num;
int main() {
printf("Indique um numero inteiro positivo: "); scanf("%i", &num);
do {
printf(" --------- MENU --------- \n");
printf("| 1 - Metade |\n");
printf("| 2 - Dobro |\n");
printf("| 0 - Sair |\n");
printf(" ------------------------ \n");
printf("Opcao: "); scanf("%i", &opcao);
switch(opcao) {
case 1: printf(“Metade = %i\n", num / 2); break;
case 2: printf(“Dobro = %i\n", num * 2); break;
case 0: printf("Adeus!\n"); break;
default: printf("Opcao invalida.\n");
}
} while (opcao != 0);
return 0;
122 } 25/09/2022
Estruturas de controlo de repetição (for)
 Para (for)
o algoritmo/programa usa um iterador para contar o número
de iterações.
 O iterador é iniciado com um valor inicial;
 É testada a condição de permanência e se esta é verdadeira,
executa-se o conjunto de instruções;
 O iterador avança para o valor seguinte e volta-se a testar a
condição de permanência.
 O ciclo termina quando a condição não se verificar.
 O ciclo for tem a seguinte estrutura:
for (inicialização; condição; alteração) instruções;

123 25/09/2022
Estruturas de controlo de repetição (for)
 O algoritmo/programa repete-se um determinado número de vezes
recorrendo a um iterador (i) que varia entre Início e Fim em
saltos dados pelo valor do Passo que pode ser negativo ou
positivo.

Para i  Início Até Fim [Passo valor] Fazer


instruções
FimPara

for (i = Início; i <= Fim; i = i + valor)


{
instruções;
}

124 25/09/2022
Estruturas de controlo de repetição (for)

125 25/09/2022
Exemplo ciclo for
 Imprimir todos os números entre 1 e 100
1. Em pseudocódigo
Para n  1 Até 100 Fazer
Escrever(n)
FimPara
2. Em código C
for( int n=1; n<=100; n++)
{
printf("%i\n", n);
}

126 25/09/2022
Exemplo ciclo for
 Imprimir todos os números pares entre 100 e 0
1. Em pseudocódigo
Para n  100 Até 0 Passo -2 Fazer
Escrever(n)
FimPara
2. Em código C
for( int n=100; n>=0; n-=2)
{
printf("%i\n", n);
}

127 25/09/2022
Exercício for (Problema)
 Enunciado:
Dado um número natural, dizer se este é ou não primo.
 Nota: Um número primo só é divisível por ele próprio e por
1. Por exemplo: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37…
 Análise do problema:
nDivisores  0
Para divisor  1 Até num Fazer
Se num MOD divisor = 0 Então
nDivisores  nDivisores + 1
FimSe
num FimPara éPrimo
Se nDivisores > 2 Então
éPrimo  FALSO
Senão
éPrimo  VERDADEIRO
128 FimSe 25/09/2022
Exercício for (Fluxograma)

129 25/09/2022
Exercício for (Pseudocódigo)
Algoritmo PrimoOuNao
Variáveis
num, nDivisores, divisor: Inteiro
éPrimo: Booleano
Início
Ler (num)
nDivisores  0
Para divisor  1 Até num Fazer
Se num MOD divisor = 0 Então
nDivisores  nDivisores + 1
FimSe
FimPara
Se nDivisores > 2 Então
éPrimo  FALSO
Senão
éPrimo  VERDADEIRO
FimSe
Escrever(éPrimo)
130 25/09/2022
Fim
Exercício for (Código C)
#include <stdio.h>
#include <stdbool.h>
int num;
bool ePrimo; // ePrimo sera tratado como variável booleana 0=false; 1=true
int main()
{
int nDivisores, divisor; // Variáveis auxiliares
printf("Indique um numero natural: ");
scanf("%i", &num);
nDivisores = 0;
for(divisor = 1; divisor <= num; divisor++)
if(num % divisor == 0)
nDivisores++;
if(nDivisores > 2) ePrimo = false;
else ePrimo = true;
if(ePrimo) printf("O numero %i e primo.", num);
else printf("O numero %i nao e primo.", num);
return 0;
}
131 25/09/2022
Instruções de salto
 return
termina a execução de uma função e retorna o controlo à função que
a chamou.
 break
termina a execução do ciclo do, for, while ou a instrução switch mais
próximo e que o contém no seu corpo.
 continue
passa o controlo para a próxima iteração do ciclo do, for, ou while
mais próximo que o contém, não executando quaisquer instruções
que restem até ao fim do corpo do ciclo.
 goto
transfere o controlo para um dada etiqueta (label). A etiqueta deve
estar na mesma função, antes ou depois da instrução goto.
132 25/09/2022
Instrução break
 Para além da sua utilização na estrutura switch-case também pode ser
usada em estruturas de repetição para quebrar o ciclo repetitivo.
 No exemplo são apresentados valores inteiros até que n fique com o
valor 0.

int n; scanf("%i", &n);


while(1)
{
if(n == 0) break; // Se n é nulo
printf("%i", n);
if(n % 2 == 0) // Se n é par
{
n = n / 2;
} else { // Se n é ímpar
n = n - 1;
}
133 } 25/09/2022
Instrução continue
 Em estruturas repetitivas permite saltar iterações.
 O exemplo que se segue só imprime os números ímpares
visto que salta os pares.

int n;
for( n = 1; n < 100; n++)
{
if(n % 2 == 0) continue; // Se n é par
printf("%i", n); // Se n é ímpar
}

134 25/09/2022
Instrução goto
 A instrução goto é “proibida” em programação estruturada
apesar de existir na maioria das linguagens por motivos
históricos, visto que esta instrução é essencial na
programação de baixo nível (Assembly).
 Em C, por exemplo, pode listar todos os números entre 10 e
1 do seguinte modo:
int n = 10;
Inicio: // Etiqueta para salto
printf("%i ", n);
n = n - 1;
if(n>0) goto Inicio; // Salta para a etiqueta

135 25/09/2022
Notas sobre números aleatórios
 Para a geração de números aleatórios fazer:
 Incluir bibliotecas <stdlib.h> e <time.h>
 Usar funções srand(time(NULL)); como semente
geradora de números aleatórios
 Usar num = rand(); para obter um número entre 0 e
MAXINT
 Exemplo para gerar números entre 1 e 5:
srand(time(NULL));
num = rand() % 5 + 1;

136 25/09/2022
Operadores bit-a-bit (bitwise)
Considerar as variáveis
int a = 5; // em binário: 101
int b = 3; // em binário: 010
Operador Designação Utilização
~ NOT bit-a-bit res = ~a; // -6
& AND bit-a-bit res = a & b; // 1
| OR bit-a-bit res = a | b; // 7
^ XOR bit-a-bit res = a ^ b; // 6
<< Deslocamento para a esquerda res = a << b; // 40
>> Deslocamento para a direita res = a >> 2; // 1

a << b significa deslocar a, b bits para a esquerda o que equivale a


multiplicar por 23, ou seja, 8.
101 << 3 → 101000
137 101 >> 1 → 010 25/09/2022
Outros operadores
Operador Descrição Exemplo
++ Pré e pós incremento ++a; a++;
-- Pré e pós decremento --a; a--;
& Referência (endereço de uma variável) b = &a;
, Separador de argumentos e elementos de res = max(a,b);
listas
?: Ternário (condicão?valorSeTrue:valorSeFalse) res = (a>b)?a:b;
[] Aceder a elementos de um array e = lista[3];
() Permite alterar as regras de precedência x = 2 * (3 + 1);

138 25/09/2022
Operações com carateres
 A biblioteca stdio.h disponibiliza um conjunto de funções para
leitura/escrita de valores do tipo caráter.
char c; // declaração de una variável
 A inicialização de uma variável do tipo char usa-
se o símbolo ′ (plica)
c = ′X′;
 Não esquecer que em linguagem C o tipo char também pode
ser tratado como inteiro (código ASCII do caráter).
 Algumas dessas funções são:
int getchar(void); // Lê caráter do teclado
void putchar(int); // Envia caráter para o ecrã

139 25/09/2022
Operações com carateres
 A biblioteca ctype.h disponibiliza um conjunto de funções
para manuseamento de valores do tipo caráter.
char c;
 Algumas dessas funções são:
int isalnum(int c); // verifica se é alfanumérico
int isalpha(int c); // verifica se é alfabético
int iscntrl(int c); // verifica se é de controlo
int isdigit(int c); // verifica se é um dígito
int islower(int c); // verifica se é letra minúscula
int ispunct(int c); // verifica se é pontuação
int isspace(int c); // verifica se é espaço
int isupper(int c); // verifica se é maiúscula
int tolower(int c); // converte para minúscula
int toupper(int c); // converte para maiúscula
140 25/09/2022
Notas sobre leitura de caráteres
 A leitura recorrendo a certas funções, tais como, a função
scanf, não fazem a leitura do '\n' final quando é feita uma
entrada de dados.
 Assim sendo, na leitura seguinte é lido o '\n' que ficou no
buffer em vez de esperar pela entrada do utilizador do
programa.
 Para resolver este problema, aconselha-se:
1. Limpar sempre o buffer depois de uma leitura que deixe o '\n'
para trás, recorrendo a getchar:
scanf("%f", &x); getchar();
2. Colocar um espaço antes de %c sempre que for feita a leitura de
caráteres com scanf de modo a limpar os '\n':
scanf(" %f", &x);
141 25/09/2022
Conjuntos de carateres
 Dígitos
0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
 Dígitos Hexadecimais
0 1 2 3 4 5 6 7 8 9A B C D E F a b c d e f
 Letras minúsculas
abcdefghijklmnopqrstuvwxyz
 Letras maiúsculas
A B C D E F G H I J K L M N O P Q R S T U V W XY Z
 Carateres de pontuação
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
 Carateres espaço
tab, newline, vertical tab, form feed, carriage return, e espaço
142 25/09/2022
Notas sobre leitura de caracteres
 As funções scanf ou getchar não fazem a leitura dos carateres
de controlo a menos que estes sejam introduzidos na forma:
Ctrl+Letra
 Para isso, em compiladores Windows, pode-se usar a função
getch (sem mostrar) ou getche (mostra caráter - echo) que
estão disponíveis na biblioteca <conio.h>:
int getch(void)
int getche(void)
 Estas funções fazem a leitura imediata de qualquer tecla que
seja pressionada.
 Todavia não são funções padrão da linguagem C pelo que
devem ser evitadas.

143 25/09/2022
Exercício de aplicação
 Fazer a leitura validada (só aceita caracteres válidos) de
números inteiros entre 1 e 9.
 Se o número inserido for válido, apresentá-lo por extenso.
Por exemplo,
 1 → Um
 2 → Dois
…
 9 → Nove
 Se não for válido, apresentar a frase
 “Número Inválido”

144 25/09/2022
Conversão de tipos de dados
 Conversão de tipo numa atribuição
o valor do lado direito da instrução (expressão) é convertido
para o tipo do lado esquerdo (variável destino)
int x :
char c ;
float f ;
c = x; //c recebe 8 bits mais baixos de x
x = f; //x recebe a parte inteira de f
f = c; //f recebe valor de c em vírgula flutuante
f = x; //f recebe valor de x em vírgula flutuante

145 25/09/2022
Conversão implícita de tipos

146 25/09/2022
Conversão forçada de tipos
 Este método, que permite converter uma expressão para um
tipo específico, é denominado cast e a sua forma geral é
(tipo) expressão;
os parênteses são obrigatórios.
 Por exemplo, para assegurar que uma divisão dá resultado do
tipo float escreve-se
int x = 3;
printf("%d/2=%f\n" , x,(float) x/2);
onde sem o cast só uma divisão inteira seria realizada.
O cast assegura que a parte decimal da resposta é exibida.

147 25/09/2022
Conversão explícita de tipos

148 25/09/2022
Funções de conversão <stdlib.h>
 A biblioteca stdlib.h disponibiliza funções de conversão
entre tipos de dados.
Função Descrição
Converte a string str para um
double atof(const char *str)
número real (tipo double)
Converte a string str para um
int atoi(const char *str)
número inteiro (tipo int)
Converte a string str para um
long int atol(const char *str)
número inteiro longo (long int)
int abs(int x) Retorna o valor absoluto de x

149 25/09/2022
Exemplos
 Conversão para inteiro:
int i = atoi("12"); // i  12
int i = atoi("12a"); // i  12
int i = atoi("a12"); // i  0 (erro)
 Conversão para real
double f = atof("12"); // f  12.000000
double f = atof("12.25"); // f  12.250000
double f = atof("2E-3"); // f  0.002000
double f = atof("2.1e3"); // f  2100.000000

150 25/09/2022
Exemplo de aplicação
 Leitura e validação de um número inteiro positivo entre 1 e 100:
#include <stdio.h>
#include <stdlib.h
int main()
{
char leitura[8]; // Declaração de string
int num;
do
{
printf(″Numero inteiro positivo: ″);
scanf(″%s″, leitura);
num = atoi(leitura);
} while( num < 1 || num > 100);
printf(″Foi lido o numero %i.\n″, num);
return 0;
151
} 25/09/2022
Funções em linguagem C
 As funções são os blocos de construção da linguagem C e o
lugar onde toda a atividade do programa ocorre.
 Em termos gerais, é um módulo independente de código,
que tem um nome e executa uma determinada tarefa
específica.
 O nome da função deve ser único em todo o programa.
 Praticamente todas as linguagens de programação possuem
algo equivalente às funções.
 Estas podem aparecer com nomes alternativos tais como
subrotinas ou procedimentos.

152 25/09/2022
Funcionamento das funções
 Algumas linguagens distinguem entre funções que retornam variáveis
e as que não retornam.
 O C assume que qualquer função retorna um valor.
 Se o programador deseja um valor de retorno deve usar a instrução
return.
 Se não deseja qualquer valor, nada deve ser usado quando a função é
chamada.
 Na programação estruturada, cada problema é dividido em
subproblemas, de modo a que cada um corresponda a tarefa simples
e pequena.
 A cada tarefa deve corresponder um módulo independente de
código.
 O código de uma função é privado, logo não pode ser acedido por
qualquer instrução em qualquer outra função a não ser através de
uma chamada à própria função.
153 25/09/2022
Estrutura de uma função
tipoDeRetorno nomeDaFunção (listaDeParâmetros)
{
corpoDaFunção
}

 O tipoDeRetorno especifica o tipo de dados que a função retorna.


 Uma função pode retornar qualquer tipo de dados exceto um array.
 A listaDeParâmetros é uma lista de nomes de variáveis e os
respetivos tipos, separados por vírgulas, que recebem os valores dos
argumentos da função quando esta é chamada.

154 25/09/2022
Parâmetros de uma função
 Uma função pode não ter parâmetros, ou seja, a respetiva lista é
vazia.
 Todavia, mesmo que não haja parâmetros, os parênteses são
obrigatórios e é boa prática colocar entre parênteses a palavra
void de modo a significar objetivamente que a função não tem
parâmetros.
 Todos os parâmetros de uma função devem ser declarados
individualmente mesmo que sejam do mesmo tipo, ou seja,

função( tipo var1, tipo var2, ..., tipo varN)

155 25/09/2022
O corpo da função
 O corpoDaFunção inclui, normalmente, duas partes, que
são a zona de declarações locais e as instruções da função,
entre as quais aparece normalmente a instrução return.
 Uma função termina automaticamente quando atinge o fim
do corpo da função, a não ser que antes disso encontre a
instrução return.
 As variáveis declaradas como parâmetros da função e aquelas
que forem declaradas no interior da função são denominadas
variáveis locais da função, sendo só reconhecidas dentro
desta (corpo da função).

156 25/09/2022
Chamada/invocação de funções

 Argumentos - são a lista de variáveis, constantes ou


expressões colocada entre os parênteses da função aquando
da chamada desta.
 Parâmetros - é a lista de declarações de variáveis aquando
da definição da função.
157 25/09/2022
Procedimento (função sem retorno)

158 25/09/2022
Exemplo: função maior

159 25/09/2022
Função divisores de um número
A função recebe como parâmetro um número
inteiro e calcula o número de divisores desse
número.

160 25/09/2022
Função é par

161 25/09/2022
Alternativa melhorada

162 25/09/2022
Função potência de um número

163 25/09/2022
Alternativa melhorada

164 25/09/2022
Funções num programa
Declaração de constante

Declaração de função

Declaração de variável

Chamada de função

Definição de função

165 25/09/2022
Estrutura de um programa

166 25/09/2022
Recursividade em funções
 Uma função recursiva é aquela que dentro do seu corpo faz
uma ou mais chamadas/invocações a si própria.
 Exemplo: função fatorial
1, 𝑛=0
𝑓𝑎𝑡 𝑛 = ቊ
𝑛 × 𝑓𝑎𝑡(𝑛 − 1), 𝑛>0
Chamada
recursiva à
função fat

167 25/09/2022
Arrays: sequências de dados
 Em programação de computadores, array, variável indexada ou
arranjo (as duas últimas denominações são mais preferíveis),
também conhecido como vetor (para arrays unidimensionais) ou
matriz (para arrays bidimensionais), é uma das mais simples
estruturas de dados.
 Os arrays mantêm uma série de elementos de dados, geralmente do
mesmo tamanho e tipo de dados.
 Elementos individuais são acedidos pela sua posição no array.
 A posição é dada por um índice, também chamado de subscrição. O
índice geralmente utiliza uma sequência de números inteiros.
 Apesar de haver arrays multidimensionais, os arrays uni e
bidimensionais são os mais comuns.
168 25/09/2022
O que é um array em linguagem C
 É uma coleção de elementos do mesmo tipo que são
guardados sob um mesmo nome.
 Um array pode ser visualizado com uma linha de uma tabela
em que cada célula pode ser visto como bytes de memória
que contêm um elemento.
 Por exemplo, um array de 5 elementos:

elem1 elem2 elem3 elem4 elem5

 O espaço ocupado em memória por um array depende do


que ocupa cada elemento individual e do número destes.

169 25/09/2022
Acesso aos elementos do array
 O acesso aos elementos de um array faz-se através do
respetivo índice:
lista 5 3 7 2 1
0 1 2 3 4
índice

 Usa-se o nome do array (neste caso é “lista”) seguido do índice


entre parenteses retos ([índice]):
num = lista[2]; // num toma o valor 7
lista[0] = 4; // o primeiro valor da lista é 4
 O acesso a cada elemento faz-se:
nomeArray[índiceElemento]

170 25/09/2022
Declaração e inicialização de arrays
 Em C, os arrays são declarados, definindo primeiro o seu
tipo, em seguida o seu nome e por fim a sua dimensão:
tipo nome[numDeElementos];
 Exemplos:
int entrada[10];
char letra[26];
float despesa[7];
 Declaração com iniciação:
int entrada[] = {4,5,2,7,9,0,1,3,8,6};
char letra[] = {'a','b','c','d',…,'z'};
float despesa[] = {20.5, 12.0,…,17.4};

171 25/09/2022
Exemplo: ordenação de array

172 25/09/2022
Exemplo completo

173 25/09/2022
Arrays: resumo
 Declaração de um array
tipoDoArray nomeDoArray [ dimensãoDoArray ] ;
 Acesso ao elemento do array índice cinco:
tipoDoArray nomeVar = nomeDoArray[5];
 Alteração do valor do elemento índice três do´array:
nomeDoArray[3] = valor;
 Acesso a todos os elementos do array, um a um:
for( int ind=0; ind <dimensãoDoArray; ind++)
fazerAlgo ( nomeDoArray[ind] );

174 25/09/2022
Arrays como parâmetros de funções
 Ao contrário de uma variável simples, no caso de um array, o
nome da variável não representa os valores dos elementos do
array (são mais que 1) mas sim um endereço da zona de
memória onde o array está armazenado. Por exemplo,
int nomeArray[NUMELEMENTOS]
nomeArray é um endereço e não um valor.
 Assim sendo, quando passamos um array a uma função,
estamos na verdade a passar o endereço do array e não
qualquer valor, como acontece nas variáveis simples.
void nomeFuncao( int nomeArray[]);
 Diz-se que estamos a passar à função um parâmetro por
referência e não por valor como acontece com variáveis
simples.
175 25/09/2022
Exemplo: função de leitura
void lerSequencia(int seq[], int nElems)
{
int i;

for( i=0; i< nElems; i++)


{
printf("Elemento N.%i: ", i+1);
scanf("%i", &seq[i]);
}
}

Nota: Reparar que o iterador i do ciclo for corresponde ao índice do array seq

176 25/09/2022
Exemplo: função de escrita
void escreverSequencia(int seq[], int nElems)
{
int i;

for( i=0; i< nElems; i++)


{
printf("|%i", seq[i]);
}
printf("|\n"); // fecha sequência
}

Nota: Reparar que os números são separados por |.

177 25/09/2022
Exemplo: função de ordenação
void ordenarSequencia(int seq[], int nElems)
{
int i, j, aux;
for( i=0; i< nElems-1; i++)
{
for( j=i+1; j<nElems; j++)
{
if( seq[i] > seq[j])
{
aux = seq[i];
seq[i] = seq[j];
seq[j] = aux;
}
}
}
}
178 25/09/2022
Exercício de aplicação
Alterar exemplo anterior de modo a que o array
contenha números reais em vez de números inteiros:
1. Criar um array de números reais
2. Fazer a leitura de 10 números reais.
3. Mostrar lista de números desordenada.
4. Ordenar a lista de números existente no array.
5. Mostrar lista ordenada.

179 25/09/2022
Arrays bidimensionais
 Declaração de um array bidimensional (2 dimensões)
tipo nomeArray[NLINHAS][NCOLUNAS];
 Um array bidimensional é, em linguagem matemática,
designado por matriz. A respetiva inicialização inclui o
valor de todos os seus elementos.
int matriz[3][2] = {{1,2},{3,4},{5,6}};
 O primeiro índice refere-se ao número de linhas da matriz
e o segundo índice ao número de colunas.
1 2
3 4
5 6
180 25/09/2022
Exemplo: função de leitura
void lerMatriz(int mat[][], int nLins, int nCols)
{
int l, c;
for( l=0; l< nLins; l++)
{
for( c=0; c< nCols; c++)
{
printf(“Célula %i,%i: ", l+1, c+1);
scanf("%i", &mat[l][c]);
}
}
}

Nota: Reparar que os iteradores l e c dos ciclos for correspondem ao índice de


linha e de coluna do array mat
181 25/09/2022
Exemplo: função de escrita
void escreverMatriz(int mat[][] , int nLins, int nCols)
{
int l, c;
printf(“--------------\n”);
for( l=0; l<nLins; l++)
{
for( c=0; c<nCols; c++)
{
printf("|%4i\t", mat[l][c]);
}
}
printf("|\n--------------\n");
}

Nota: Reparar que a formatação %4i seguido de \t faz com que os números
ocupem sempre 4 espaços, ou seja, metade dos espaços da tabulação, ficando assim
centrado na célula da matriz.
182 25/09/2022
Exercício prático (Arrays)
 Escrever um programa em C que, dada uma sequência de
10 inteiros, faça o seguinte:
1. Apresente a sequência ordenada por ordem crescente;
2. Obtenha o menor valor da sequência;
3. Obtenha o maior valor da sequência;
4. Obtenha a mediana da sequência;
5. Obtenha a média da sequência.
 Deve ser criado um MENU para escolher a operação a
realizar, devendo este ser apresentado depois de cada
operação até que seja escolhida a opção nº 0 (zero).

183 25/09/2022
Strings em C
 Em C, uma string é um array de caracteres terminado com o
carácter nulo (‘\0’). A sua declaração é como a de um array:
char nome[MaxChars+1]; // +1 para o '\0’
 A inicialização de uma string é ligeiramente diferente:
char nome[] = {'X', 'i', 'c', 'o', '\0'};
 O carácter nulo é necessário como terminador para que se
possa manusear a string como um todo, o que não se pode fazer
com um array.
 É por isso que se pode inicializar uma string assim:
char nome[] = "Xico"; // tamanho do array será 4+1
 Aqui não é necessário separar explicitamente os caracteres que
constituem a string nem apresentar o carácter nulo.
184 25/09/2022
Strings: leitura e escrita
 Funções para leitura de strings a partir da entrada padrão
 Lê string para o endereço apontado por str. A leitura termina
quando lê espaço, newline ou eof (end-of-file)
int scanf("%s", str);
 Lê string para o endereço apontado por str. A leitura termina
quando lê newline ou eof (end-of-file)
char[] gets(char str[]) // char *gets(char *str)
 Envia string dada para a saída padrão
int printf("%s", str);
 Envia string para a saída padrão colocando newline no fim
int puts(const char str[]) // const char *str

185 25/09/2022
Problema com a função gets
 A função gets não tem qualquer informação sobre a
dimensão do buffer para onde lê, pelo que irá continuar a ler
para além do espaço de memória do buffer dado:
char buffer[10];
gets(buffer);
 Se introduzir mais de 10 carateres, os restantes irão ocupar
memória que não pertence ao buffer.
 Solução: usar fgets com stdin:
char buffer[10];
fgets(buffer, sizeof(buffer), stdin);
 Só lerá até que o buffer termine porque tem informação sobre
o tamanho do mesmo.
186 25/09/2022
Problema com a função fgets
 Ao contrário da função gets, a função fgets também lê o
ENTER final, ficando este no índice imediatamente anterior
ao índice do caracter nulo (fim da string).
 Para resolver isto, deve-se sempre puxar o caracter nulo uma
posição atrás, de modo a sobrepor-se ao caracter ENTER.
 Exemplo:
char buffer[10];
fgets(buffer, sizeof(buffer), stdin);
buffer[strlen(buffer)-1] = ˈ\0ˈ;
 Depois de ler a palavra “ola”,
buffer = {ˈoˈ, ˈlˈ, ˈaˈ, ˈ\nˈ, ˈ\0ˈ}
 Depois de puxar o caracter nulo atrás, fica
buffer = {ˈoˈ, ˈlˈ, ˈaˈ, ˈ\0ˈ, ˈ\0ˈ}
187 25/09/2022
Outro problema com a função fgets
 A função fgets também apresenta ainda um problema que é o
facto de que quando são inseridos caracteres em excesso para
além do tamanho especificado, esses caracteres ficam no buffer
e serão lidos nas leituras seguintes do programa, o que poderá
originar erros de funcionamento.
 A solução será implementar uma função que resolva todos
estes problemas de modo a poder ser utilizada em qualquer
aplicação em linguagem C padrão.
 Proposta de função:
void readstr(char str[], int n);
em que str é a string a ler e n o seu tamanho máximo.
188 25/09/2022
Solução para leitura de strings
void readstr(char str[], int n)
{
int i; // Índice do caracter lido na string/array
char c; // Caracter lido com getchar

i = 0;
while((c = getchar()) != '\n' && i < n)
{
str[i++] = c;
}
str[i] = '\0'; // Termina string com caracter nulo
/* Limpa caracteres extra no buffer de entrada,
incluindo '\n', quando existirem. */
if( i == n)
while( getchar() != '\n');
}

189 25/09/2022
Funções para operar strings
 Biblioteca
#include <string.h>
 Funções

Nome Declaração Descrição


strcat char[] strcat(char dest[], const char src[]) Junta 2 strings
strcmp int strcmp(const char str1[], const char str2[]) Compara 2 strings
strcpy char[] strcpy(char dest[], const char src[]) Copia 1 string para outra
strlen size_t strlen(const char str[]) Retorna o tamanho da string
strstr Char[] strstr(const char str[], const char seq[]) Procura seq na str

190 25/09/2022
Exemplo: funções gets e strlen

191 25/09/2022
Exemplo: função strcmp

192 25/09/2022
Exemplo: função strstr

 A função strstr retorna o endereço do primeiro caracter da palavra


encontrada ou NULL caso não encontre nada.
 Depois continua a procurar a partir do caracter seguinte ao fim da
palavra encontrada, até ao fim do texto. 25/09/2022
193
Caracteres e Strings

194 25/09/2022
Apontadores
 Como já se viu anteriormente, pode-se, dentro de um programa,
aceder aos valores guardados em memória.
 A ferramenta que permite aceder a estes valores são os denominados
apontadores (pointers).
 Os apontadores são uma das características mais poderosas da
linguagem C, mas também uma das mais perigosas.
 O tipo base do apontador define que tipo de variáveis podem sem
apontadas pelo apontador.
 Tecnicamente, qualquer tipo de apontador pode apontar para
qualquer zona
 de memória. Todavia, toda a aritmética de apontadores é realizada
relativamente ao seu
 tipo base, por isso é importante declarar corretamente os
195 apontadores. 25/09/2022
Apontadores e apontados
 Um apontador é um tipo de dados que armazena uma
referência para qualquer coisa, ou seja, guarda o endereço em
memória de uma determinada informação, seja uma variável,
uma função, ou outro tipo de dados.
 Uma variável que contém o endereço de outra, diz-se que a
primeira “aponta” para a segunda

 A forma geral de declaração de uma variável apontador é


tipo *nome;

196 25/09/2022
Atribuição de apontadores
 A atribuição de um apontador a outro faz com que ambos
fiquem a apontar para o mesmo apontado. Ou seja,
ap1 = ap2;
 faz com que ap2 fique a pontar para o mesmo apontado de ap1.
 A atribuição entre apontadores não mexe nos apontados.
 Esta só altera um dos apontadores de modo a que este fique
com a mesma referência do outro apontador.
 Depois de uma atribuição entre apontadores, diz-se que os dois
partilham o mesmo apontado.
 O operador & pode ser utilizado para obter o endereço de
uma variável:
int *ap, x=5;
ap = &x; 25/09/2022
197
Utilização de apontadores

 Quer na linha 8, quer na linha 10 é impresso o


valor 5 visto que ambos os apontadores apontam
para o mesmo endereço (o da variável x).
198 25/09/2022
Apontadores e arrays
 O identificador de um array é um apontador

Saída na consola
199 25/09/2022
Apontadores e strings
 Uma string, sendo um array, também o seu nome é um
apontador:

200
Saída na consola 25/09/2022
Apontadores em ciclos

Saída na consola 25/09/2022


201
Estruturas (struct)
 Uma estrutura é uma coleção de duas ou mais variáveis agrupadas
sob um mesmo nome.
 Cada variável dentro de uma estrutura é designada membro dessa
estrutura.
 Ao contrário dos vetores, os membros de uma estrutura podem ser
de tipos diferentes, mas a existência de uma relação entre eles faz
com que seja conveniente tratá-los conjuntamente.
 Para declarar uma estrutura usa-se a palavra reservada struct.
 A forma geral da declaração de uma estrutura é:
struct nomeDaEstrutura
{
declaraçõesDosMembros
};

202 25/09/2022
Declaração de estruturas e variáveis
 Estrutura para armazenar as classificações de um jogador num
jogo em que há vitórias, empates e derrotas:
struct jogador
{
char nome[16];
int vitorias;
int empates;
int derrotas;
};
 Notar que a declaração anterior não definiu quaisquer variável;
limitou-se a definir um novo tipo de dados, não lhe sendo,
portanto, reservado qualquer espaço em memória.
 A partir deste novo tipo podem-se definir variáveis de acordo com
as regras utilizadas anteriormente. Por exemplo,
struct jogador jogX, jogO;

203 25/09/2022
Utilização de estruturas
 Após declarar uma variável do tipo estrutura, para aceder aos
campos desta estrutura recorre-se ao operador ponto (.) da
seguinte forma:
nomeVarEstrutura.nomeMembro
 Por exemplo, considere-se a ficha referente ao jogador jogX:
struct jogador jogX;
 Para inicializar os dados do jogX, supondo que este se chama
Zacarias e tem 3 vitórias, 1 empate e 2 derrotas, ficaria:
strcpy( jogX.nome, "Zacarias");
jogX.vitorias = 3;
jogX.empates = 1;
jogX.derrotas = 2;

204 25/09/2022
printf e scanf com estruturas
 Se em vez de os dados serem obtidos de alguma posição em
memória, estes tivessem de ser lidos do teclado, ficaria:
gets(jogX.nome);
scanf("%i", &jogX.vitorias);
scanf("%i", &jogX.empates);
scanf("%i", &jogX.derrotas);
 Reparar que na função gets, sendo “nome” um array de
caracteres, o próprio nome do array já é um apontador para a
string.
 Para mostrar os dados no ecrã pode-se usar a função printf:
printf(“%s\t%i\t%i\t%i\n”, jogX.nome, \
jogX.vitorias, jogX.empates, jogX.derrotas);

205 25/09/2022
Estruturas e apontadores
 A linguagem C permite apontadores para estruturas tal como para
qualquer outro tipo de dados. Todavia, há alguns aspetos especiais
relativos a apontadores para estruturas que é importante saber.
 A declaração de apontadores para estruturas é semelhante a outros
tipos de dados.
 Usa-se o operador * antes do nome da variável de estrutura:
struct jogador *apj;
 Há duas utilizações primárias dos apontadores quando se trabalha
com estruturas, que são:
 passar uma estrutura por referência a uma função (permitindo assim
que a função possa alterar o valor dos seus elementos);
 criar listas ligadas e outras estruturas de dados dinâmicas.

206 25/09/2022
Estruturas em funções
 Supondo que se quer escrever uma função que faça a leitura
dos dados de qualquer jogador, a declaração da função seria:
void LerDados( struct jogador *);
 A definição da mesma função ficaria:

 Reparar que o acesso aos membros da estrutura usa o


operador -> em vez do operador .
207 25/09/2022
Estruturas e arrays
 Pode-se declarar variáveis como arrays de estruturas. Por
exemplo:
struct jogador score[10];
 A declaração anterior cria um array com 10 estruturas
jogador, ou seja, permite armazenar os dados relativos a 10
jogadores.
 O acesso aos membros da estrutura dentro do array faz-se do
seguinte modo:
int nVitorias = score[2].vitorias;
score[5].derrotas = 3;

208 25/09/2022
Exemplo de função

 Reparar que o código é mais simples relativamente a uma gestão


dos dados baseada só em tipos de dados simples e arrays
(unidimensionais e bidimensionais).
 O facto de o nome do array score já ser um apontador permite
aceder aos membros da estrutura com o operador . E não o
operador ->
209 25/09/2022
Criação de novos tipos com typedef
 Após a definição de uma estrutura (struct) esta passa a
funcionar como um novo tipo de dados composto:
struct jogador
{
char nome[TAM];
int vitorias, empates, derrotas;
};
 Declaração de variável do tipo da estrutura:
struct jogador jogX;
 Criação de tipo com typedef:
typedef struct jogador tipoJogador;
 Declaração de variável:
tipoJogador jogX;
210 25/09/2022
Ficheiros
 Os ficheiros são estruturas de dados próprias para armazenar
dados em dispositivos de memória secundária, tais como, discos
rígidos e outros.
 Um ficheiro é visto como uma sequência (stream) de bytes,
normalmente com uma marca que indica o fim do ficheiro, EOF
(end-of-file).
 Quando um programa trabalha com ficheiros, deve fazer a ligação
explícita do stream ao ficheiro.
 Este processo corresponde à abertura do ficheiro.
 Quando pretendido, o programa pode quebrar essa ligação,
fechando o ficheiro.
 A abertura de um ficheiro devolve um apontador para uma
estrutura FILE.

211 25/09/2022
Ficheiros padrão
 Três ficheiros são automaticamente abertos quando um programa é
iniciado:
 Standard input (entrada padrão),
 standard output (saída padrão) e
 standard error (erro padrão).
 A abertura de um ficheiro devolve um apontador para uma estrutura
FILE.
 Para os ficheiros padrão, acima indicados, os apontadores são,
respetivamente:
 stdin - entrada padrão (teclado)
 stdout - saída padrão (monitor)
 stderr - erro padrão (monitor)
 Estes apontadores estão definidos como macros na biblioteca stdio.h.
 A menos que sejam redirecionados, estão normalmente associados ao
terminal.
212 25/09/2022
Utilização de ficheiros padrão
 Para ler uma linha de texto a partir do ficheiro de entrada padrão:
char linha[MAX]; // buffer de entrada
fgets( linha, MAX, stdin);
 Para escrever linha de texto no saída padrão:
char linha[] = "texto a escrever";
fputs( linha, stdout);
 Para leitura formatada do tipo “1 – viagens -> 12.5” , fazer:
int a; char t[MAX]; float x;
fscanf( stdin, "%i - %s -> %f", &a, t, &x);
 Para escrita formatada do mesmo tipo, fazer:
int a; char t[MAX]; float x;
fprintf( stdout, "%i - %s -> %f", a, t, x);

213 25/09/2022
Outros aspetos sobre ficheiros
 Nomes de ficheiro
 Em qualquer sistema operativo, os ficheiros possuem nomes que
os identificam seguindo regras, para a sua constituição, específicas
de cada sistema.
 O nome do ficheiro é limitado a FILENAME_MAX caracteres (no
mínimo 1), sendo esta constante uma macro definida na biblioteca
stdio.h.
 Esta biblioteca disponibiliza um vasto conjunto de funções para
trabalhar com ficheiros.
 Tipos de ficheiros
 Ficheiros de texto (sequência de caracteres)
 Ficheiros binários (sequência de bits/bytes)
214 25/09/2022
Acesso a ficheiros
 Em C, consideram-se 3 tipos de acesso a ficheiro:
 Leitura
 Escrita
 Leitura/Escrita
 Para aceder a um ficheiro, começa-se por proceder à abertura
do mesmo recorrendo à função fopen.
 Esta função tem a seguinte definição:
FILE *fopen( const char *nomeFicheiro, const char *modoAbertura);

 Quando a abertura do ficheiro falhar é retornado o valor NULL.


 Exemplo de abertura de um ficheiro para escrita:
FILE *apf; // declaração de variável do tipo apontador para FILE
fopen( const char *nomeFicheiro, const char *modoAbertura);

215 25/09/2022
A estrutura FILE
 A estrutura FILE tem a seguinte definição:
typedef struct _iobuf
{
char* _ptr; // próximo caracter
int _cnt; // nº de cars disponíveis
char* _base; // endereço do ficheiro
int _flag; // modo do ficheiro (r,w)
int _file; // descritor do ficheiro
int _charbuf; // para permitir ungetc
int _bufsiz; // tamanho atual do ficheiro
char* _tmpfname; // nome do ficheiro
} FILE;

216 25/09/2022
Modos de abertura de ficheiros
Modo Descrição
"r" Abertura de um ficheiro de texto para leitura.
"w" Criar um ficheiro de texto para escrita. Se este já existir, o seu conteúdo é Apagado
"a" Abre ou cria um ficheiro de texto para adição no fim deste.
"r+" Abertura de ficheiro de texto para atualização, isto é, leitura e escrita.
"w+" Criar um ficheiro de texto para atualização. Se este existir, o seu conteúdo é eliminado.
"a+" Abre ou cria um ficheiro de texto para atualização, escrevendo no fim deste.

 Quando, em caso de insucesso, a função fopen retorna NULL,


significa que:
 foi utilizado um nome de ficheiro inválido;
 o ficheiro já está aberto;
 o caminho para o ficheiro é inválido;
217  o ficheiro a abrir em modo de leitura não existe. 25/09/2022
Fecho de ficheiros
 Logo que se termine o processamento sobre um ficheiro, deve-
se proceder ao seu fecho.
 Para isso, utiliza-se a função fclose, cuja declaração é a seguinte:
int fclose (FILE *apf);
 Esta função retorna 0 em caso de sucesso e -1 (EOF) em caso
de erro.
 A função desaloca a estrutura FILE para que o apontador apf
aponta.
 Quando um ficheiro é fechado com fclose, todos os dados em
buffer, à espera de serem escritos, serão escritos neste antes do
fecho propriamente dito.
218 25/09/2022
Exemplo: Testar existência de ficheiro
#include <stdio.h>
int main (void)
{
FILE *apf;
char nome[32];
printf ("Introduza o nome do ficheiro: ");
fgets (stdin, 32, nome);
if ((apf = fopen (nome, "r")) != NULL)
{
printf ("O ficheiro \"%s\" já existe!\n" , nome);
fclose (apf);
}
else
printf ("O ficheiro \"%s\" não existe!\n" , nome);
return 0;
}
219 25/09/2022
Funções de leitura/escrita em ficheiros
 Leitura/escrita formatada
 fscanf
 fprintf
 Leitura/escrita por carácter
 fgetc
 fputc
 Leitura/escrita por string
 fgets
 fputs
 Leitura/escrita em bloco
 fread
 fwrite
220 25/09/2022
Leitura/escrita formatada
 Supor que cada linha do ficheiro conterá a seguinte informação:
Nome, nºVitórias, nºEmpates, nºDerrotas
 Sendo a declaração da função fscanf a seguinte
int fscanf (FILE *apf, const char *formato, arg1, arg2, …);
 Ficará:
res = fscanf( apf, "%s\t%i,%i,%i", \
nome, &nVitorias, &nEmpates, &nDerrotas);
 Em caso de sucesso retornará o nº de itens lidos; em caso de erro retornará
0 (zero).
 A declaração da função fprintf é a seguinte
int fprintf (FILE *apf, const char *formato, arg1, arg2, …);
 Ficará:
res = fprintf( apf, "%s\t%i,%i,%i", \
nome, nVitorias, nEmpates, nDerrotas);

221 25/09/2022
Função de leitura de linhas
int LerFicheiro( const char fic[TAMNOME], char linhas[MAXLINHAS][TAMLINHA])
{
FILE *apf;
char linha[TAMLINHA];
int i, numLinhas;

if(( apf = fopen(fic, "r")) == NULL) { fclose( apf); return -1; }

numLinhas = 0;
// Carrega linhas do ficheiro
for( i=0; i<MAXLINHAS; i++) {
if( fgets( linha, TAMLINHA, apf) != NULL) {
strcpy(linhas[i], linha);
numLinhas++;
} else {// nao existe uma nova linha -> pergunta vazia
strcpy(linhas[i], "");
}
}
return numLinhas;
}
222 25/09/2022
Função de separação de linhas
int SepararLinha( char linha[TAMLINHA], char partes[NUMLINHAS][TAMLINHA])
{
char *parte; // apontador para a parte atual
int p = 0; // índice de cada parte no array partes

if((parte = strtok(linha, "|")) != NULL)


{
strcpy(partes[p++], parte);
while((parte = strtok(NULL, "|")) != NULL)
{
strcpy( partes[p++], parte);
}
return 1;
}
else
return 0;
}

223 25/09/2022
Leitura/escrita em bloco
 De cada vez será lido/escrito um bloco de dados, no exemplo dado
corresponde a uma estrutura do tipo struct jogador.
 A declaração da função fread é:
int fread(void *apt, int tamanho, int num, FILE *apf);
 Para ler uma estrutura ficaria:
res = fread (&jogadorX, sizeof( struct jogador), 1, apf);
 E para escrever, a declaração da função fwrite é:
int fwrite(void *apt, int tamanho, int num, FILE *apf);
 Para escrever uma estrutura ficaria:
fwrite(&jogadorX, sizeof( struct jogador), 1, apf);

224 25/09/2022
Função de leitura em bloco
int LerFicheiro( const char fic[TAMNOME], struct ficha fichas[MAXFICHAS])
{
FILE *apf;
int i, res, numFichas;
// Se ha erro ao aceder ao ficheiro retorn -1
if(( apf = fopen (fic , "r" ) ) == NULL) { fclose( apf); return -1; }
numFichas = 0;
// Carrega classificacoes de ficheiro
for( i=0; i<MAXFICHAS; i++) {
res = fread (&fichas[i] , sizeof( struct ficha), 1, apf);
if( res > 0) {
numFichas++;
} else {
// Inicializa todos os campos de ficha[i] a vazio/0
}
}
return numFichas; // retorna numero de fichas lidas do ficheiro
}

225 25/09/2022
Função de escrita de bloco
int EscreverFicheiro( const char fic[TAMNOME], struct ficha fichas[MAXFICHAS])
{
FILE *apf;
int i, numFichas;
// Se ha erro ao aceder ao ficheiro retorn -1
if(( apf = fopen (fic , "w" ) ) == NULL) { fclose( apf); return -1; }
numFichas = 0;
// Escreve fichas no ficheiro
for( i=0; i<MAXFICHAS; i++)
{
if( strcmp(fichas[i].nome, "") != 0) // fichas[i].numero != 0
{
fwrite(&fichas[i] , sizeof( struct ficha), 1, apf);
numFichas++;
}
}
return numFichas; // retorna numero de fichas gravadas no ficheiro
}

226 25/09/2022

Você também pode gostar