programação c -...
TRANSCRIPT
Italo Valcy Programação em C
Programação C
Italo Valcy <[email protected]>
www.ieee.org/ufba
Módulo 02 – Controle de fluxo, Vetores e Matrizes
Italo Valcy Programação em C 2 / 59
Todo o material aqui disponível pode, posteriormente, ser utilizado sobre os termos da:
Creative Commons License: Atribuição - Uso não comercial - Permanência da Licença
http://creativecommons.org/licenses/by-nc-sa/3.0/
Licença de uso e distribuição
Este curso foi baseado no curso “Algoritmos e Programação deComputadores” do prof. Centoducatte, da UNICAMP, disponívelem <http://www.ic.unicamp.br/~ducatte/mc102/mc102.html>, e nas aulas de prof. Arnaldo V. Moura e Daniel F. Feber.
Italo Valcy Programação em C 3 / 59
Controle de fluxo
Italo Valcy Programação em C 4 / 59
Controle de fluxo
É possível controlar o fluxo de execução de um programa em C, baseado no valor de uma expressão lógica/relacional.
Exemplo: imposto de renda
Condicionais
if (salario_mensal <= 1499.15) {isento();
} else {calcula_ir(salario_mensal);
}
Italo Valcy Programação em C 5 / 59
Controle de fluxo
Forma geral:
<condicao> é resultado de uma operação relacional ou lógica:
(a > b)
C % 5 != 0 || c == 25
<condicao> pode ser expressão complexa:
a > b+3 && (c % 5 != 0 || c == 25)
(c = getchar()) != '.'
Condicionais
if (<condicao>) {// Fluxo a executar caso <condicao> seja verdadeira
} else {// Fluxo a executar caso <condicao> seja falsa
}
Italo Valcy Programação em C 6 / 59
Controle de fluxoOperadores Relacionais e lógicos
Operadores relacionais
Maior: >
Maior ou igual: >=
Menor: <
Menor ou igual: <=
Igual: ==
Diferente: !=
Operadores lógicos:
AND: &&
OR: ||
NOT: !
Italo Valcy Programação em C 7 / 59
Controle de fluxoOperadores Relacionais e lógicos
Exemplos
((2 > 1) || (3 < 7)) : resultado VERDADEIRO
((3 < 2) && (2 == 2)) : resultado FALSO
((5 ==0) || (1 < 2)) : resultado VERDADEIRO
!(2 > 1): resultado VERDADEIRO
!(1 < 0): resultado FALSO
C realiza o processamento otimizado: o 2o elemento do II só é processo se o 1o for falso; da mesma forma que o 2o elemento do && só é processado se o primeiro for verdadeiro. Ex:
if (i < MAX_VET && vet[i] > 0) {
calcula(vet[i]);
}
Italo Valcy Programação em C 8 / 59
Controle de fluxo
Um ano é bissexto se for divisível por 4 mas não por 100, exceto quando for divisível por 400. Faça um programa que leia o ano e diga se ele é bissexto ou não.
Exemplo:
2000 => Ano bissexto
2200 => Ano nao e bissexto
Exemplo: cálculo do ano bissexto
Italo Valcy Programação em C 9 / 59
Controle de fluxo
Um ano é bissexto se for divisível por 4 mas não por 100, exceto quando for divisível por 400. Faça um programa que leia o ano e diga se ele é bissexto ou não.
Exemplo: cálculo do ano bissexto
/* Verifica ano bissexto: bissexto.c */#include <stdio.h>
int main() {int ano;
printf(“Digite o ano: ”);scanf(“%d”,&ano);if (ano % 4 == 0 && ano % 100 != 0 || ano % 400 == 0) {
printf(“Ano bissexto\n”);} else {
printf(“Ano nao e bissexto\n”);}
}
Italo Valcy Programação em C 10 / 59
Controle de fluxoEstrutura if-else-if
Para testar várias opções é possível usar a seguinte construção:
if (condição_1) declaração_1;else if (condição_2) declaração_2;else if (condição_3) declaração_3;...else if (condição_n) declaração_n;else declaração_default;
Italo Valcy Programação em C 11 / 59
Controle de fluxoEstrutura if-else-if (exemplo)
/* adivinhar o numero (apenas uma tentativa)*/#include <stdio.h>#include <stdlib.h>#include <time.h>int main () { int num, secret;
// inicializa e gera um num aleatorio srand( time(NULL) ); secret = rand() % 10 + 1;
printf ("Adivinhe o numero (1 a 10): "); scanf ("%d",&num);
if (num==secret) { printf ("Parabens, voce acertou!\n"); printf ("Numero secreto: %d, tentativas: %d.\n", num, 1); } else if (num>secret) { printf ("Tente um numero menor.\n"); } else if (num<secret) printf ("Tente um numero maior.\n");
return(0);}
Italo Valcy Programação em C 12 / 59
Controle de fluxoif's aninhados
O if aninhado é simplesmente um if dentro da declaração de um outro if externo
Cuidado: a qual if um determinado else está ligado?
if (condicao_1) acao_1();else if (condicao_2) acao_2();else acao_3();
A indentaçãoestá correta?
Italo Valcy Programação em C 13 / 59
Controle de fluxoif's aninhados
O else está ligado sempre ao último if
if (condicao_1) acao_1();else if (condicao_2) acao_2(); else acao_3();
Italo Valcy Programação em C 14 / 59
Controle de fluxoOperador ?
A seguinte operação:
pode ser simplificada com operador ?, assim:
if (a>0) b=150;else b=150;
b = a>0 ? 150 : 150;
Italo Valcy Programação em C 15 / 59
Controle de fluxoOperador ?
De forma geral, expressões do tipo:
Podem ser substituídas por:
Cuidado: o operador ? não atende a uma gama de casos, mas pode simplificar expressões complicadas
if (condição) expressão_1;else expressão_2;
condição ? expressão_1 : expressão_2;
Italo Valcy Programação em C 16 / 59
Controle de fluxoComando switch
Um outro comando de tomada de decisão
Não tão poderoso quanto o if, mas com aplicações valiosas (e.g., menu de opções)
Código limpo e de fácil entendimentoswitch ( <variable> ) {case thisvalue: // acao para thisvalue break;case thatvalue: // acao para thatvalue break;//...default: // acao padrão break;}
Italo Valcy Programação em C 17 / 59
Controle de fluxoComando switch (exemplo)
int main() { int input; printf("1. Play game\n"); printf("2. Load game\n"); printf("3. Exit\n\n"); printf("Selection: "); scanf(“%d”,&input);
switch ( input ) { case 1: playgame(); break; case 2: loadgame(); break; case 3: printf("Thank you for playing!\n"); break; default: printf("Error, bad input, quitting\n"); break; } return 0;}
Italo Valcy Programação em C 18 / 59
Controle de fluxo
O laço while é usado quando queremos que um bloco de instruções seja executado ENQUANTO uma condição for verdadeira (true).
Ex.: imprimir números naturais pares menores que 10:
Laço de repetição while
#include <stdio.h>
int main() {int x = 0;
printf(“%d\n”,x);x = x + 2;printf(“%d\n”,x);x = x + 2;printf(“%d\n”,x);x = x + 2;printf(“%d\n”,x);x = x + 2;printf(“%d\n”,x);
}
Italo Valcy Programação em C 19 / 59
Controle de fluxoLaço de repetição while
E se fosse até 1000?
E se o cálculo intermediário fosse mais complexo?
Forma mais elegante:
#include <stdio.h>
int main() {int x = 0;
while (x < 10) {printf(“%d\n”, x);x = x + 2;
}}
Italo Valcy Programação em C 20 / 59
Controle de fluxoLaço de repetição while
Forma geral:
Parecido com o comando if:
Dica de boa prática:
Nunca use goto...
while (<condicao>) {// declaracoes...
}
if (<condicao>) {// declaracoes...// volte para o comando if (goto)
}
Italo Valcy Programação em C 21 / 59
Controle de fluxoExemplo: fatorial
#include <stdio.h>
int main() { int n, contador, fat = 1;
printf("Digite um numero: "); scanf("%d", &n); contador = n; while (contador > 0) { fat = fat * contador; contador = contador 1; }
printf("O fatorial de %d e' %d\n",n,fat);}
Italo Valcy Programação em C 22 / 59
Controle de fluxo
Exercício: Fazer um programa para imprimir uma tabela com os primeiros 300 graus Fahrenheit e seus correspondentes graus Celsius (de 20 em 20), usando a fórmula:
C=(5/9)(F-32)
Saída:
0 F => -17.8 C20 F => -6.7 C40 F => 4.4 C60 F => 15.6 C… …260 F => 126.7 C280 F => 137.8 C300 F => 148.9 C
Italo Valcy Programação em C 23 / 59
Controle de fluxo
/* Programa para conversao de Fahrenheit * para Celsius: fahr2celsius.c */#include <stdio.h>
int main() {int inicio, fim, incr;float fahr, celsius;
inicio = 0;fim = 300;incr = 20;
fahr = inicio;while (fahr <= fim) {
celsius = (5.0/9.0) * (fahr – 32.0);printf(“%4.0f => %6.1f\n”, fahr, celsius);fahr = fahr + incr;
}}
Italo Valcy Programação em C 24 / 59
Controle de fluxoLaço de repetição for
Forma geral:
<inicializacao>: responsável pela seção de inicialização das variáveis de iteração do laço
<condicao>: deve conter a condição de parada, que deve ser verdadeira em algum momento.
<incremento>: comandos para incremento das variáveis de iteração do laço
for (<inicializacao>; <condicao>; <incremento>) {// comandos...
}
Italo Valcy Programação em C 25 / 59
Controle de fluxoLaço de repetição for
Exemplo: fahr2celsius-v2.c
Italo Valcy Programação em C 26 / 59
Controle de fluxoLaço de repetição for
Exemplo: fahr2celsius-v2.c
/* Programa para conversao de Fahrenheit * para Celsius: fahr2celsiusv2.c */#include <stdio.h>
int main() {float fahr, celsius;
for (fahr=0.0; fahr <= 300.0; fahr=fahr+20.0) {celsius = (5.0/9.0) * (fahr – 32.0);printf(“%4.0f => %6.1f\n”, fahr, celsius);
}}
Italo Valcy Programação em C 27 / 59
Controle de fluxoLoop infinito com for
O loop infinito tem a forma:
“Infinito” pois não existe condição (ou ela nunca assume valor falso)
A menos que seja interrompido (e.g., via break)
for (inicialização; ;incremento) declaração;
int main() { int i; char c; for(i=0; ;i++) { c = getchar(); // problema de buffer! if (c == 'q') break; printf(“Caractere %d foi %c\n”,i,c); }}
Italo Valcy Programação em C 28 / 59
Controle de fluxoLaço de repetição do-while
Bastante parecido com while, porém primeiro executa a declaração para depois o teste:
Vamos a um exemplo:
do { declaração;} while (condição);
Italo Valcy Programação em C 29 / 59
Controle de fluxoLaço de repetição do-while
int main() { int input; do { printf("1. Play game\n"); printf("2. Load game\n"); printf("3. Exit\n\n"); printf("Selection: "); scanf(“%d”,&input);
switch ( input ) { case 1: playgame(); break; case 2: loadgame(); break; case 3: printf("Thank you for playing! Quitting...\n"); break; default: printf("Error, bad input, try again\n"); break; } } while (input != 3); return 0;}
Italo Valcy Programação em C 30 / 59
Controle de fluxo
Exercício: Editar o programa de adivinhar número para repetir o bloco de interação com usuário até que o usuário acerte o número. Deve-se ainda imprimir o número de tentativas do usuário.
Extra: atualmente o programa aceita números de 1 a 10, deixe genérico para um número MAX, definido no começo do programa.
Laço de repetição do-while
Italo Valcy Programação em C 31 / 59
Controle de fluxo
Comandos usados para influenciar a sequência de um loop:
break: força a saída do loop imediatamente
continue: pula o resto do corpo do loop e passa para a próxima iteração
Geralmente usados após uma condicional
Comandos break e continue
Italo Valcy Programação em C 32 / 59
Controle de fluxo
Exemplo: validação com break:
Comandos break e continue
#define MAXLINHA 1000
main() { int n; char linha[MAXLINHA];
while ((n = lelinha(linha, MAXLINHA)) > 0) { while (n >= 0) if (linha[n]!=' ' && linha[n]!='\t' && linha[n]!='\n') break; linha[n+1] = '\0'; printf("|%s|\n",linha); }}
Italo Valcy Programação em C 33 / 59
Controle de fluxo
Exemplo: validação com continue:
Comandos break e continue
do { printf(“Opcao desejada [5 para sair]: ”); scanf(“%d”, &key); if (key < 1 || key > 5) continue; // processa opcoes} while (key != 5);
Italo Valcy Programação em C 34 / 59
Vetores e Matrizes
Italo Valcy Programação em C 35 / 59
Vetores
Conjunto de elementos consecutivos, do mesmo tipo, que podem ser acessados individualmente a partir de um único nome.
Vetores == Arranjos unidimensionais
Declaração:
tipo nome_variavel [quantidade]
4.8 5.0 4.5 5.6 6.7 3.2 2.9
(0) (1) (2) (3) (4) (5) (6)
Notas
Italo Valcy Programação em C 36 / 59
Vetores
Exemplo de declaração:
int numero_matricula[20];
float notas[20];
Os índices do vetor de tamanho n variam de 0 à n-1. Ex:
float notas[4];
notas[0] = 6.4; // primeiro elemento
notas[3] = 5.3; // ultimo elemento
Italo Valcy Programação em C 37 / 59
Vetores
Dicas de inicialização de vetores:
int v[3] = {1,2,3};
int v[5] = {5,4}; // igual a {5,4,0,0,0}
int v[] = {6,7,8,9};
Incorreto:
int v[];
Italo Valcy Programação em C 38 / 59
Vetores
#include <stdio.h>
#define N 10
main() { float alunos[N], avg; int i;
// leitura de dados for (i=0; i < N; i++) { printf("nota do aluno %d: ", i+1); scanf("%f",&alunos[i]); }
// processamento for (i=0; i < N; i++) avg += alunos[i]; avg = avg / N;
printf("media da turma: %.2f\n", avg);}
Exemplo
Italo Valcy Programação em C 39 / 59
Strings
Strings são cadeias de caracteres: palavras, frases, textos, etc.
Na prática: vetor de char
Forma geral:
char nome_da_string [tamanho]
m a r i a \0
nome
Italo Valcy Programação em C 40 / 59
Strings
Operações com strings não são triviais:
str1 = str2; // cópia não funciona assim
str1 = str1 + str2 // nem concatenação
str1 == str2 // nem comparação
…
A biblioteca padrão do C possui várias funções para manipular strings:
#include <string.h>
Italo Valcy Programação em C 41 / 59
Strings
char* strcpy(char* destino, const char* origem);
Copia a string C em origem para destino
destino deve ter tamanho maior ou igual a origem
Funções da biblioteca string.h
/* strcpy example */#include <stdio.h>#include <string.h>
int main () { char str1[]="Sample string"; char str2[40]; char str3[40]; strcpy(str2,str1); strcpy(str3,"copy successful"); printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3); return 0;}
str1: Sample stringstr2: Sample stringstr3: copy successful
Saída:
Italo Valcy Programação em C 42 / 59
Strings
char* strcat(char* destino, const char* origem);
Anexa a string C em origem para destino
A string de origem permanecerá inalterada e será anexada ao fim da string de destino
Funções da biblioteca string.h
/* strcat example */#include <stdio.h>#include <string.h>
int main (){ char str[80]; strcpy (str,"these "); strcat (str,"strings "); strcat (str,"are "); strcat (str,"concatenated."); puts (str); return 0;}
these strings are concatenated.
Saída:
Italo Valcy Programação em C 43 / 59
Strings
size_t strlen(const char* str);
A função strlen() retorna o comprimento da string fornecida
O tamanho é determinado pelo terminador nulo de string ('\0), porém não é contado
Funções da biblioteca string.h
j u s t t e s t i n g \0
=> strleng() = 12
Italo Valcy Programação em C 44 / 59
Strings
size_t strlen(const char* str);
Exemplo:
Saída
Funções da biblioteca string.h
/* strlen example */#include <stdio.h>#include <string.h>
int main () { char szInput[256]; printf ("Enter a sentence: "); gets (szInput); printf ("The sentence entered is %d " "characters long.\n",strlen(szInput)); return 0;}
Enter sentence: just testingThe sentence entered is 12 characters long.
Italo Valcy Programação em C 45 / 59
Strings
int strcmp(const char* str1, const char* str2);
A função strcmp() compara a string 1 com a string 2 e retorna:
0 se as strings forem iguais
> 0 se str1 é maior que str2
< 0 se str1 é menor que str2
Funções da biblioteca string.h
Italo Valcy Programação em C 46 / 59
Strings
int strcmp(const char* str1, const char* str2);
Exemplo:
Saída:
Funções da biblioteca string.h
#include <stdio.h>#include <string.h>
int main() { printf("beatriz <=> beatriz : %d\n", strcmp("beatriz", "beatriz")); printf("beatriz <=> bete : %d\n", strcmp("beatriz", "bete")); printf("beatriz <=> beata : %d\n", strcmp("beatriz", "beata")); return 0;}
beatriz <=> beatriz : 0beatriz <=> bete : 1beatriz <=> beata : 1
Italo Valcy Programação em C 47 / 59
Strings
Para leitura de strings temos em geral três opções:
scanf(“%s”, &str);
gets(str);
while ((c = getchar())!='\n') { … }
Leitura de string
Italo Valcy Programação em C 48 / 59
Strings
scanf exemplo:
Problema: termina no primeiro separador (' ')
Leitura de string
#include <stdio.h>
int main() { char nome[80]; printf("Digite seu nome: "); scanf("%s", &nome); printf("Ola %s!\n", nome);}
Digite seu nome: maria joaoOla maria!
Italo Valcy Programação em C 49 / 59
Strings
scanf exemplo (medida de contorno):
scanf suporta regex!
Leitura de string
#include <stdio.h>
int main() { char nome[80]; printf("Digite seu nome: "); scanf("%[^\n]", &nome); printf("Ola %s!\n", nome);}
Italo Valcy Programação em C 50 / 59
Strings
gets exemplo:
Leitura de string
#include <stdio.h>
int main() { char nome[80]; printf("Digite seu nome: "); gets(nome); printf("Ola %s!\n", nome);}
Italo Valcy Programação em C 51 / 59
Strings
As funções gets e scanf para leitura de string apresentam um grave problema: elas estão sujeitas a estouro de pilha
Leitura de string
#include <stdio.h>
int main() { char nome[10]; printf("Digite seu nome: "); scanf("%[^\n]", &nome); printf("Ola %s!\n", nome);}
Digite seu nome: maria joao da silva pintoOla maria joao da silva pinto!Falha de segmentação
Saída (falha):
Italo Valcy Programação em C 52 / 59
Strings
As funções gets e scanf para leitura de string apresentam um grave problema: elas estão sujeitas a estouro de pilha
Contra medidas:
char str_target[100];
Para gets:
fgets(str_target, 100, stdin);
Para scanf:
scanf(“%100[^\n]”, &str_target);
Leitura de string
Italo Valcy Programação em C 53 / 59
Strings
Um outro problema comum é de sujeira de buffer
Leitura de string
#include <stdio.h>
int main() { char pais[3], cidade[10];
printf("Digite o codigo do pais: "); scanf("%2s", &pais); printf("Digite a cidade: "); scanf("%10[^\n]", &cidade); printf("Local: %s, %s\n", cidade, pais);}
Digite o codigo do pais: brasilDigite a cidade: Local: asil, br
Saída (falha):
Italo Valcy Programação em C 54 / 59
Strings
Um outro problema comum é de sujeira de buffer
Contra medidas:
Usando fflush(stdin)
Problema: não portável (não funciona em Linux)
Solução mais portável: int c;
while ((c = getchar()) != '\n' && c != EOF);
Leitura de string
Italo Valcy Programação em C 55 / 59
Strings
“Limpando” o buffer:
Leitura de string
#include <stdio.h>
int main() { char pais[3], cidade[10]; int c;
printf("Digite o codigo do pais: "); scanf("%2s", &pais); while ((c = getchar()) != '\n' && c != EOF); printf("Digite a cidade: "); scanf("%10[^\n]", &cidade); printf("Local: %s, %s\n", cidade, pais);}
Italo Valcy Programação em C 56 / 59
Matrizes
Em C podemos ter arranjos
multidimensionais (2d, 3d, 4d),
para indexação mais seletiva
2d => matrizes
Formato geral
tipo nome [linhas][colunas]
tipo nome [tam1][tam2]...[tamN]
Italo Valcy Programação em C 57 / 59
Matrizes
Atenção: não confundir as dimensões com células de armazenamento!
As dimensões servem apenas para índice
Os arranjos de qualquer dimensão terão apenas uma célula de armazenamento!
aij
i
j
Italo Valcy Programação em C 58 / 59
Matrizes
#include <stdio.h>
main() { int tab_dia[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31}, // ano normal {0,31,29,31,30,31,30,31,31,30,31,30,31}, // ano bissexto }; int ano, dia; int mes, bissexto;
printf("Digite o ano e diadoano: "); scanf("%d %d", &ano, &dia);
bissexto = ano%4==0 && ano%100!=0 || ano%400==0; for (mes=1; dia > tab_dia[bissexto][mes]; mes++) dia = tab_dia[bissexto][mes];
printf("Data (dd/mm/aaaa): %02d/%02d/%d\n", dia, mes, ano);}
Exemplo
Italo Valcy Programação em C 59 / 59
Exercício
Fazer um programa que leia uma matriz de inteiros A (3x3) e calcule uma matriz B, resultado da soma de A com sua transposta. Imprimir a matriz A, sua transposta e a matriz B.
Italo Valcy Programação em C 60 / 59
Referências
KERNIGHAN, B.W. C and RITCHIE, D.M.: A linguagem de programação. Tradução de: The C Programming Language. Edisa, 1986.
Curso de C, UFMG. Disponível em: http://www.mtm.ufsc.br/~azeredo/cursoC/
Curso de C, UNICAMP. Disponível em: http://www.ic.unicamp.br/~ducatte/mc102/mc102.html
C Library Reference. Disponível em: http://www.cplusplus.com/reference/clibrary/
Italo Valcy Programação em C 61 / 59
Dúvidas