Upload
buikhue
View
231
Download
0
Embed Size (px)
Citation preview
PET ELÉTRICA - UFCG
Curso Introdutório à Linguagem C
v 1.0c
Autores:
Dinart Duarte Braga Nustenil Segundo de Moraes Lima Marinus
Colaborador:
Felipe Maia Másculo
Tutor: Prof. Dr. Edmar Candeia Gurjão
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
2
Índice
Introdução ao C
Como criar e compilar programas DEV C++
Tipos de variáveis
Incluindo bibliotecas
Funções de Entrada-Saída Padrões
o printf
o scanf
Operadores
o Aritméticos e de atribuição
o Relacionais e lógicos
o Exercícios de revisão
Estruturas de Controle de fluxo o if o if/else o switch o O operador ternário ‘?’ o Exercícios de revisão
Estruturas de Repetição o while o do while o for o Exercícios de revisão
Estrutura de dados
o Vetores
o Matrizes
o Exercícios de revisão
Números pseudo-aleatórios
o Visão geral
o Exercícios de revisão
Funções
o Visão geral
o Protótipo
o Função sem retorno
o Vetores como parâmetros de funções
o Recursividade
o Escopo de variáveis
o Exercícios de revisão
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
3
Exercícios complementares
Resolução dos exercícios complementares
Bibliografia
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
4
Introdução ao C
O objetivo desse curso é introduzir conceitos básicos da linguagem de
programação C, que une versatilidade e robustez, pois alia características de
linguagens de baixo nível com características de alto nível.
Criada por Denis Ritchie, em 1972, foi baseada na linguagem B, teve sua primeira
aplicação importante na reescrita do sistema operacional UNIX, que até então era
escrito na linguagem Assembly.
O C é uma linguagem de propósito geral, tendo como paradigma a programação
estruturada. É utilizada no desenvolvimento de navegadores, editores de texto, banco
de dados, sistemas operacionais, programas de comunicação e automação.
Estudaremos nesse curso a linguagem de programação C padronizada pela
organização ANSI.
Sugerimos que o aluno compile todos os programas exemplificados nessa
apostila e dados em sala de aula, altere-os, veja se ocorrem erros, caso sim, tente
corrigi-los, enfim, manipule o programa de modo que se possa extrair o máximo de
experiência possível de cada exemplo.
Como criar e compilar programas DEV C++
Durante o curso usaremos o IDE (Integrated Development Environment) Dev-
C++, desenvolvido pela Bloodshed, que pode ser usado tanto para desenvolvimento de
programas em C++ como em C. Listamos abaixo dois procedimentos básicos desse
programa:
Criando um novo código fonte
Clique em Arquivo > Novo > Arquivo Novo
Uma nova janela irá abrir-se, escreva o código do seu
programa nessa janela
Compilando o código fonte
Clique em Executar > Compilar
Escolha um nome e local para salvar o arquivo
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
5
O arquivo executável (.exe) será salvo na mesma pasta do
código fonte e com o mesmo nome
A maioria das dúvidas que porventura surgirem sobre algum procedimento
mais elaborado podem ser sanadas no arquivo de ajuda do programa, em Ajuda >
Ajuda sobre o Dev-C++.
Tipos de variáveis
Quase toda operação em C é realizada com auxílio de variáveis, que são uma
abstração de um local da memória onde se guarda informação, para utilizar uma
variável é preciso, antes de qualquer coisa, declará-la, procedimento que é realizado
utilizando a seguinte sintaxe:
\*sintaxe da declaração de uma variável*\
tipo nome;
Os nomes de variáveis devem ter duas condições satisfeitas:
1-Começar com letras ou _ (sublinhado).
2-Os caracteres seguintes serem letras, números ou _ (sublinhado).
Exemplos de nomes válidos: x, a, A, _b3, _Nome123, p3t e _1337
Exemplo de nomes inválidos: 3, 007, 1variavel, *oi, %pet e <eletrica>
Como vimos, ao declarar uma variável devemos especificar um tipo, esse tipo
especifica quais valores podem ser armazenados na região da memória associada a
essa variável, como esses valores são representados e quais operações envolvendo
essa variável são válidas.
Existem 5 tipos básicos em C, são eles: char, int, float, double e void.
char: Armazena um caractere.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
6
int : Armazena um número inteiro.
float: Armazena um número com precisão decimal limitada.
double: Armazena um número décimal com precisão maior que o float.
void: Não armazena dados, serve para definir funções que não retornam
valores.
/*Exemplo de declaração de variáveis*/
int num;
char l;
float _a;
OBS: Não se pode declarar uma variável do tipo void.
Incluindo bibliotecas
A maioria das funções utilizadas em um programa em C estão implementadas em
um arquivo separado, e para que alguma função esteja acessível no programa, é
necessário incluir esse arquivo da seguinte forma:
#include <nomedabiblioteca>
A sintaxe acima é válida para bibliotecas padrões do C. Uma biblioteca é um
arquivo onde várias funções, geralmente associadas a um tipo de processamento em
especifico, são guardadas.
Além das bibliotecas padrões, existem bibliotecas não-padronizadas onde outros
tipos de funções são armazenadas.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
7
Funções de Entrada-Saída Padrões
o printf
O printf é uma função de saída que permite escrever no dispositivo de saída
padrão, geralmente o monitor. Sua sintaxe é descrita abaixo:
/*sintaxe do printf*/
printf(“expressão de controle”, lista de argumentos);
A expressão de controle deve conter o texto que será exibido na tela, além disso,
devem ser incluídas nesse texto as variáveis que serão exibidas. Para tal se utiliza um
código de controle onde se deseja que apareça o valor da variável, o código informa ao
compilador como a variável deve ser apresentada; os códigos de controle usados mais
frequentemente estão listados abaixo:
Código Significado %d Inteiro %f Float %c Caractere %s String %H Inteiro Hexadecimal com letras maiúsculas %% Imprime um %
Vejamos alguns exemplos de printf:
printf ("Tudo bem? "); -> Tudo bem?
printf ("%f",3.1415); -> 3.1415
printf ("Um inteiro %d e uma letra %c.”,11,’a’); -> Um inteiro 11 e uma letra a.
printf ("%s composta”,"Frase"); -> Frase composta
printf ("%s%d%%","Taxa de ",5); -> Taxa de 5%
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
8
o scanf
Já para fazer leituras da entrada padrão, normalmente o teclado, usa-se a função
scanf. Sua sintaxe lembra a do printf:
/*sintaxe do scanf*/
scanf(“expressão de controle”, lista de argumentos);
A expressão de controle deve conter os códigos de controle na ordem em que os
dados devem ser lidos, já na lista de argumentos devem ser especificadas quais
variáveis vão receber os valores lidos.
Vejamos alguns exemplos do uso de scanf:
scanf(“%d”,&int1); -> Lê um número inteiro e salva na variável int1
scanf(“%c”,&char1); -> Lê um número inteiro e salva na variável char1
scanf(“%d%c”,&int1,&char1); -> Realiza a mesma operação dos exemplos acima,
mas em uma única linha de código
OBS: É importante colocar o operador & antes do nome da variável na lista de
argumentos, o motivo para esse procedimento será entendido mais adiante.
Agora que aprendemos a usar as funções printf e scanf, vejamos um exemplo de
programa que utiliza essas duas funções em conjunto:
/*Exemplo de programa utilizando scanf e printf*/
#include <stdio.h> // Biblioteca que contém as funções scanf printf
#include <stdlib.h> //Biblioteca que contém a função system
int main ()
{
int idade;
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
9
char letra;
printf("Digite a sua idade\n");
scanf("%d",&idade);
printf("Digite a primeira letra do seu nome\n");
scanf("%c",&letra);
printf("A sua idade eh %d, e a primeira letra do seu nome eh
%c\n",idade,letra);
system("pause"); /*Comando utilizado somente no Windows que pausa a
execução do programa, para que saída seja visualizada antes que a tela se feche.*/
return 0;
}
Operadores
o Aritméticos e de atribuição
Os operadores aritméticos são símbolos utilizados para realizar operações
matemáticas, eles podem ser unários ou binários, que agem sob uma ou duas
variáveis, respectivamente.
Vejamos uma lista dos operadores aritméticos:
Operador Ação Tipo + Soma variáveis Unário ou Binário - Subtrai variáveis Unário ou Binário * Multiplica variáveis Binário / Divide variáveis Binário % Retorna o resto da divisão inteira Binário ++ Incrementa uma variável Unário -- Decrementa uma variável Unário
Os cinco primeiros operadores da lista acima retornam o resultado de suas
operações sem alterar o valor das variáveis sobre as quais eles agem já os dois últimos
operadores, de incremento e decremento, além de retornar o valor da operação,
também alteram o valor da variável para o valor retornado.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
10
Os valores retornados por operações aritméticas podem ser guardados em outra
variável, desde que o tipo de dado retornado seja o mesmo do tipo de variável na qual
o dado será armazenado. Para realizar essa operação, a atribuição, usa-se o operador =
que guarda o valor da expressão da direita na variável da esquerda, vejamos sua
sintaxe:
/*Sintaxe do operador de atribuição*/
variável = expressão aritmética
Alguns exemplos podem deixar mais claro o uso dos operadores apresentados
acima:
a = 3;
b = (3 + 3.14)/5.;
c++;
d = ((132324%3)*3)--;
e = -a;
f=a++;
g=++a;
h = ((a++)+(--a))/2;
Relacionais e lógicos
Os operadores relacionais realizam comparação entre variáveis, vejamos uma
tabela com esses operadores:
Operador Significado > Maior >= Maior igual < Menor <= Menor igual == Igual != Diferente
A expressão utilizando esses operadores retorna 1 caso a expressão seja
verdadeira e 0 caso ela seja falsa. Vejamos alguns exemplos:
C = 3>2, (C=1)
D = 10==9 (D = 0)
E = (1<3)==1 (D =1 )
F = A>B
Já os operadores lógicos realizam três operações lógicas básicas, são elas:
Operador Significado && E (and) || OU (or) ! NÃO (not)
O operador && retorna 1 (verdadeiro) caso ambas as expressões a sua direita e a
esquerda sejam verdadeiras, o operador || retorna 1 (verdadeiro) caso uma das duas
seja verdadeira e o operador ! inverte o valor lógico da variável.
Vale lembrar que em C, qualquer valor diferente de 0 é interpretado logicamente
como verdadeiro e o número 0 é interpretado como falso.
Vejamos alguns exemplos de expressões utilizando operadores relacionais e
lógicos:
A = (5>3)&&(3<1) (A = 0)
B = (5>3)||(3<1) (A = 1)
C = !!5 (C = 1)
Exercícios de revisão
I.Escreva um programa que lê 4 números e calcula a média aritmética,
geométrica, a soma e o produto de todos os números e imprima o resultado na tela.
II.Escreva um programa que lê 2 números a e b e calcula a expressão (Não(a) E
Não(b)) e imprime o resultado na tela.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
12
Estruturas de Controle de fluxo
o if
A instrução if tem a seguinte forma geral:
/*Sintaxe da instrução de controle if */
if(condição)
{
comandos;
}
Quando o argumento da instrução if (condição) for verdadeiro (valores
diferentes de zero), o comando ou blocos de comandos é executado e quando é falso
(valor zero) o comando é “ignorado”.
Vale salientar que ao fim da instrução if não se usa ponto-e-vírgula( ; ).
Vejamos um exemplo do uso de if:
/*Comparação de duas variáveis */
if( variavel1 > variavel2)
printf(%d é maior que %d \n”, variavel1, variavel2);
if( variavel2 > variavel1)
printf(%d é maior que %d \n”, variavel2, variavel1);
o if/else
A instrução if-else tem a seguinte forma geral:
/*Sintaxe da instrução de controle if-else */
if(condição)
{
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
13
Comandos1;
}else{
Comandos2;
}
Quando o argumento da instrução if (condição) for verdadeiro (valores
diferentes de zero), o comando ou blocos de comandos dentro do bloco if (no caso da
sintaxe acima, comandos1) é executado e quando é falso (valor zero) o comando
dentro do if é “ignorado” (comandos1) e o comando ou blocos de comandos dentro de
bloco else é executado (no caso da sintaxe acima, comandos2).
Exemplo do uso de if-else:
/*Comparação de duas variáveis */
If( variavel1 > variavel2){
printf(%d é maior que %d \n”, variavel1, variavel2);
}else{
printf(%d é maior ou igual que %d \n”, variavel2, variavel1);
}
Podemos também fazer “cadeias” de if-else-if, como mostrado abaixo:
/*Sintaxe da cadeia if-else-if */
if (condição_1) comando_1;
else if (condição_2) comando _2;
else if (condição_3) comando _3;
[...]
else if (condição_n) comando _n;
else ultimocomando;
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
14
Vejamos um exemplo:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int numero;
printf ("Digite um numero: \n");
scanf ("%d",&numero);
if (numero>20)
printf ("\n O numero eh maior que 20");
else if (numero==20)
{
printf ("\n\nVoce acertou!\n");
printf ("O numero eh igual a 20.");
}
else if (numero<20)
printf ("\n\nO numero eh menor que 20");
system(“pause”);
return(0);
}
o switch
Outra instrução de controle bastante usada é o switch, sua forma geral é:
/*Sintaxe da instrução switch */
switch (variável)
{
case constante_1:
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
15
declaração_1;
break;
case constante_2:
declaração_2;
break;
[...]
case constante_n:
declaração_n;
break;
default
declaração_default;
}
A instrução switch é bastante usada para substituir várias condições, evitando
assim o uso excessivo da instrução if ou de cadeias if-else-if. A principal diferença do
switch é que a sua estrutura não aceita expressões, aceita apenas constantes. O
switch testa a variável e executa a declaração cujo case corresponda ao valor atual da
variável. A declaração default é opcional e será executada apenas se a variável, que
está sendo testada, não for igual a nenhuma das constantes. O comando break
interrompe a execução de um comando. No caso do switch, o comando break faz com
que o switch seja interrompido assim que a declaração seja executada. Se após a
execução da declaração não houver o comando break, o programa continuará
executando, testando todos os outros casos, ou seja, o uso do break não é obrigatório,
mas é bastante recomendado. Vejamos um exemplo:
/*Exemplo do uso de switch*/
switch (numero)
{
case 1:
printf ("\n\nO numero e igual a 1.\n");
break;
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
16
case 2:
printf ("\n\nO numero e igual a 2.\n");
break;
case 80:
printf ("\n\nO numero e igual a 80.\n");
break;
default:
printf ("\n\nO numero nao e nem 1 nem 2 nem 80.\n");
}
Rode esse programa sem usar break e veja o que acontece.
o operador ternário ‘?’
Este operador se torna útil para substituir instruções if-else, simplificando o
programa, a sua sintaxe é a seguinte:
/*Sintaxe do operador ternário*/
condição ? expressão_1:expressão_2;
Esta forma pode ser substituída por:
if(condição)
expressão_1;
else
expressão_2;
Assim, se a condição for verdadeira, o operador exibe apenas a expressão_1,
caso contrário, exibe a expressão_2.
Como exemplo, temos:
if( a < 0)
b = 2;
else
b = 3;
Que pode ser substituído por apenas uma linha:
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
17
b = a < 0 ? 2 : 3 ;
o Exercícios de revisão
I.Faça um programa que verifique se um número é divisível por 2.
II.Faça um programa que informe qual o menor divisor (entre 1 e 5) de um número
dado.
III.Faça um programa que informe o mês de acordo com o número informado pelo
usuário. (Exemplo: Entrada: 4. Saída: Abril.)
Estruturas de Repetição
o while
O while é útil para realizar operações repetidas submetidas a uma condição que
mudam com o tempo, sua sintaxe é:
/*Sintaxe do while*/
while (condição) {
comandos;
}
Enquanto a condição for verdadeira, os comandos serão executados, onde cada
iteração é comumente chamada de laço.
OBS: a condição é testada antes de ser executado o laço.
Uma analogia com a instrução if seria:
if (condição)
{
declaração;
"Volte para o comando if"
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
18
}
Essa é a “lógica” do comando while, vejamos um exemplo:
while (numero != 5){
printf(“Digite o numero 5: \n”)’;
scanf(“%d”, &numero);
}
O programa ficará preso ao laço até que o usuário digite o número 5, assim, a
variável “número” não será mais diferente de 5, sendo falsa a condição.
o do while
De ação bastante semelhante ao while, sua forma geral é:
/*Sintaxe do comando do while*/
do{
comandos;
}while(condição);
No comando do-while é realizada uma iteração antes de ser analisada a
condição, enquanto que no while é primeiro analisada a condição para depois começar
a iteração.
o for
O comando for é a terceira estrutura para se trabalhar com loops, com repetição,
sua forma geral é:
/*Sintaxe do for*/
for (inicialização;condição;incremento){
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
19
declaração;
}
Na estrutura do for temos a inicialização da variável do contador, um condição
de parada, geralmente relacionada ao contador, o incremento do contador e a
instrução propriamente dita.
A sua execução se dá inicialmente pela execução da inicialização, seguida pela
verificação da condição de parada, execução das instrução se a condição for
verdadeira e finalmente a execução do incremento.
Uma analogia interessante com a instrução if é:
inicialização;
if (condição){
declaração;
incremento;
"Volte para o comando if"
}
Vejamos um exemplo:
/* Programa que imprime números de 1 a 100 */
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int contador;
for (contador=1; contador<=100; contador++)
printf ("%d ",contador);
system(“pause”);
return(0);
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
20
o Exercícios de revisão
I.Multiplicar os 10 primeiros números naturais.
II.Calcule a soma dos 1000 termos da função harmônica. ( )
Estrutura de dados
o Vetores
Em C, vetores são matrizes unidimensionais de elementos do mesmo tipo. Esse
tipo de estrutura de dado tem uma aplicação bastante vasta, vejamos abaixo como se
declara um vetor:
/*declaração de um vetor*/
tipo nome_do_vetor[número _de_elementos];
Ao ler uma expressão como a de cima, o compilador reserva na memória espaço
suficiente para armazenar o número de elementos especificado na declaração,
vejamos um exemplo:
char nome[30];
No caso acima, um vetor com 30 elementos do tipo char é declarado e alocado
na memória do computador.
Para se referir a um elemento específico do vetor devemos usar o nome deste
vetor e um índice, os índices válidos começam em 0 e vão até
(número_de_elementos)-1. Além de se poder usar um número inteiro constante no
índice de um vetor, também é possível usar variáveis inteiras nos índices dos vetores,
de forma que essas estruturas têm uma importância essencial em processos iterativos
como for e while.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
21
No exemplo do vetor nome declarado acima, os índices válidos vão de 0 a 29.
Muito embora esses sejam os valores válidos, o C não considera um erro de sintaxe
utilizar um índice fora dos limites, então caso seu código fonte tenha a linha nome[50],
por exemplo, o compilador não irá apontar erro de sintaxe e o programa será
compilado, muito embora deva ocorrer algum erro durante a execução do programa.
Vejamos alguns exemplos corretos e incorretos do uso de vetores:
int idades[100];
int i = 5;
Correto:
idades[10] = idades[50];
idades[0] = idades [3]-idades[8];
idades[i]= idades[i+5]
Incorreto:
idades[100]=idades[0];
idades[-1]=idades[3];
idades = idades +1;
Abaixo temos um exemplo ilustrativo do uso de vetores em um processo
iterativo:
/*Calcula a media dos números inteiros inseridos pelo usuário*/
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int numeros[50] = {0}; /* Declara um vetor int de 50 posições e inicializa-os com
0 */
int i, j;
int total=0;
float media;
printf(“Insira números inteiros para calcular a média, para parar a inserção
digite -999”);
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
22
for (i=0; (numeros[i-1] != -999) || ( i != 50) ; i++)
scanf ("%d",&numeros[i]);
i--;
for(j = 0 ; j != i ; j++)
total = total + numeros[j];
media = (float) total/i;
printf ("\n\n A média dos numeros eh %f\n",media);
system("pause");
return(0);
}
O programa acima lê números inteiros e armazena em um vetor, a leitura
continua até que o usuário insira o número -999, em seguida a média é calculada.
Entenda esse programa, copie no seu IDE e tente alterá-lo para que o programa
imprima todos os números da série no seguinte formato: números =
[n1,n2,n3,...,nmax].
o Matrizes
Matrizes têm a maioria das características semelhantes aos vetores, a diferença
primordial é o número de dimensões que as matrizes possuem, enquanto vetores
possuem apenas uma dimensão, matrizes possuem n dimensões. Um caso bastante
particular é de matrizes bidimensionais (n=2), vejamos a sintaxe para a declaração
dessa matriz:
/*declaração de uma matriz bidimensional*/
tipo nome_da_matriz[número_de_linhas][número_de_colunas];
Para referenciar um elemento particular da matriz deve-se utilizar dois índices, o
número da linha e o da coluna do elemento que se deseja acessar. Assim como em
vetores, o compilador não verifica se o índice está dentro dos limites permitidos,
ficando a cabo do programador essa tarefa.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
23
Vejamos um exemplo de aplicação que utiliza matrizes bidimensionais:
/*Exemplo de uso de matrizes bidimensionais*/
#include <stdlib.h>
#include <stdio.h>
int main ()
{
int matriz[20][10];
int i,j,k;
k=1;
for (i=0;i<20;i++)
{
for (j=0;j<10;j++)
{
matriz[i][j]=k;
printf("%d\t",matriz[i][j]);
k++;
}
printf("\n");
}
system("pause");
return 0;
}
O programa acima preenche uma matriz 20x10 com valores de 1 a 200, entenda
o programa, copie e altere-o para que ele preencha cada elemento com o produto do
número da linha pelo número da coluna.
Matrizes com dimensões maiores que dois têm propriedades análogas às das
matrizes bidimensionais, para declarar uma matriz n-dimensional usa-se a seguinte
sintaxe:
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
24
/*Sintaxe para declaração de matrizes n-dimensionais*/
tipo nome_da_matriz[tamanho 1][tamanho 2][tamanho 3]...[tamanho n-
1][tamanho n];
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
25
o Exercícios de revisão
I.Faça um vetor de tamanho 50 preenchido com o seguinte valor: (i+5i)%i, sendo
i a posição do elemento no vetor, em seguida imprima o vetor na tela.
II.Faça um programa que preenche um matriz quadrada 5x5 com 1´s na diagonal
principal (matriz identidade) e imprime a matriz na tela.
III.Faça um programa que preenche uma matriz com o produto do valor da linha
e da coluna de cada elemento, depois imprime na tela.
Números pseudo-aleatórios
o Visão geral
Muitas aplicações, principalmente jogos, exigem o uso de números aleatórios para diversas funcionalidades, um computador digital não é capaz de gerar um número totalmente aleatório, pois é um sistema determinístico. No entanto, é possível, através de uma função bastante caótica, gerar números com uma distribuição probabilística aproximadamente uniforme, são os números pseudo-aleatórios. Para gerar números pseudo-aleatórios, usa-se a função rand() que retorna um número pseudo-aleatório no conjunto dos inteiros. Se você executar o comando abaixo: for(i=0; i<10; i++) printf("%d ", rand()%6); Será gerada uma seqüência de dez números entre 0 e 5. Mas se o comando for executado novamente, os mesmos números serão gerados. Isto ocorre devido ao fato de que as condições iniciais para a execução da função são as mesmas. Para que isso não ocorra, devemos enviar uma "semente" (um valor arbitrário) como entrada do sistema. Para enviar uma semente à função rand(), devemos usar a função srand(num), onde num é um número inteiro que serve como semente. É interessante que a cada execução do programa seja enviado uma semente diferente, uma forma de fazer isso é enviar um valor que muda freqüentemente.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
26
Uma das sementes mais utilizadas pelos programadores é o tempo do relógio do computador, que muda constantemente, esse valor é retornado pela função time(NULL), da biblioteca <time.h>. Para inseminar a função rand() com o valor do clock, fazemos: srand(time(NULL)); Dessa forma, a cada execução, os números pseudo-aleatórios geradores serão diferentes, dando mais confiabilidade ao sistema.
o Exercícios de revisão
I.Faça um programa que simula o lançamento de dois dados, d1 e d2, n vezes, e tem
como saída o número de cada dado e a relação entre eles (>,<,=) de cada lançamento.
Funções
o Visão geral
Para fazer um programa grande e complexo temos que dividi-lo em blocos, ou
seja, fazer unidades autônomas para realizar determinadas tarefas. Para esses blocos
damos o nome de funções, a forma geral de uma função é:
/*Sintaxe de uma função*/
Tipo_de_retorno nomedafuncao(parâmetros) {
Comandos;
}
O tipo_de_retorno é o tipo do dado que a função vai retornar que se não for
especificado, retornará um tipo int, ou seja, o default é o tipo int. Os parâmetros é
uma lista de valores que a função recebe, ou seja, é a entrada da função e tem a
seguinte forma:
(parâmetros) = (Tipo nome1, tipo nome2, tipo nome3,..., tipo nomeN)
Um exemplo simples de um função:
/*Função que calcula o quadrado de um número */
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
27
#include <stdio.h>
#include <stdlib.h>
/*Função que calcula o quadrado de um número */
int quadrado(int a)
{
return (a*a);
}
int main ()
{
int numero;
printf ("Entre com um numero: ");
scanf ("%d",&numero);
numero = quadrado(numero); /*chamada da função */
printf ("\n\nO seu quadrado vale: %d\n",numero);
system(“pause”);
return 0;
}
Vamos fazer uma análise do exemplo acima.
Toda função necessita ser chamada. Podemos perceber que no exemplo a
chamada da função é:
numero = quadrado(numero);
O dado de entrada da função é o argumento da chamada à função. No exemplo
o dado de entrada da função quadrado é “numero”. O parâmetro da função quadrado
é “int a”, onde “a” recebe o valor de entrada, ou seja, os parâmetros recebem os
valores dos argumentos da chamada da função. Percebemos também que o tipo da
variável “numero” é igual ao da variável “a”. Esta relação deve ser satisfeita sempre.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
28
Um função é processada até chegar no seu valor de retorno (return). O valor de
retorno deve ser compatível ao tipo de retorno declarado na função. No exemplo, a
função “quadrado” retorna o valor “a*a”.
Vejamos outro exemplo do uso de funções:
#include <stdio.h>
#include<stdlib.h>
int EhPar (int b)
{
if (b%2) /* Verifica se a e divisivel por dois */
return 0; /* Retorna 0 se nao for divisivel */
else
return 1; /* Retorna 1 se for divisivel */
}
/*Vemos que a função EhPar tem dois retornos possíveis mas apenas um é
executado! */
int main ()
{
int numero;
printf ("Entre com numero: ");
scanf ("%d",&numero);
if (EhPar(numero))
printf ("\n\nO numero e par.\n");
else
printf ("\n\nO numero e impar.\n");
system(“pause”);
return 0;
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
29
o Protótipo
Para uma programação mais organizada, fazemos o uso de protótipos.
Protótipos são as declarações das funções. Nos exemplos acima, as funções eram
escritas antes da função principal (main) com o objetivo de informar ao compilador
com antecedência quais eram os tipos de retorno e quais eram os parâmetros das
funções para que este pudesse compilar o programa corretamente. Os protótipos são
colocados antes da função principal, para informar os tipos de retorno e parâmetros,
desta forma, a função pode ser escrita depois da função main, os protótipos tem a
seguinte forma geral:
tipo_de_retorno nome_da_função (parâmetros);
Onde o tipo_de_retorno, nome_da_funcao e parâmetros devem ser os mesmos
usados na função. A título de exemplo, reescrevemos os dois exemplos da seção
anterior usando protótipos:
/*Exemplo 1*/
#include <stdio.h>
#include <stdlib.h>
/*Função que calcula o quadrado de um número */
int quadrado(int a); //Protótipo da função
int main ()
{
int numero;
printf ("Entre com um numero: ");
scanf ("%d",&numero);
numero = quadrado(numero); /*chamada da função */
printf ("\n\nO seu quadrado vale: %d\n",numero);
system(“pause”);
return 0;
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
30
int quadrado(int a)
{
return (a*a);
}
/*Exemplo 2*/
#include <stdio.h>
#include<stdlib.h>
int EhPar (int b); // Protótipo da função
int main ()
{
int numero;
printf ("Entre com numero: ");
scanf ("%d",&numero);
if (EhPar(numero))
printf ("\n\nO numero e par.\n");
else
printf ("\n\nO numero e impar.\n");
system(“pause”);
return 0;
}
int EhPar (int b)
{
if (b%2) /* Verifica se a e divisivel por dois */
return 0; /* Retorna 0 se nao for divisivel */
else
return 1; /* Retorna 1 se for divisivel */
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
31
}
o Função sem retorno
Se quisermos usar uma função, mas ela não retorna nenhum valor, declaramos o
tipo de retorno da função como sendo void.
Protótipo:
void nome_da_funcao (parâmetros);
Também podemos ter funções que não tem entrada. Assim seu protótipo fica da
seguinte forma:
Tipo_de_retorno nome_da_funcao (void);
Ou ainda funções que não tem entrada e não retornam nenhum valor.
void nome_da_funcao (void);
Vejamos um exemplo de função sem parâmetros de entrada e sem retorno:
/*Exemplo de função void-void*/
#include <stdio.h>
#include <stdlib.h>
void Mens (void);
int main ()
{
Mens();
printf ("\tRepita!:\n");
Mens();
system(“pause”);
return 0;
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
32
void Mens (void)
{
printf ("PET Elétrica! \n");
}
o Vetores como parâmetros de funções
Além de variáveis, podemos também passar vetores para funções, algumas
observações devem ser feitas a respeito disso.
Ao passarmos variáveis para funções, estamos passando apenas o seu valor, ou
seja, seu valor é processado, modificado e retornado. Quando passamos vetores,
estamos, na realidade, passando o endereço do primeiro elemento do vetor. Assim,
iremos processar os valores dos vetores, mas não os retornaremos, pois eles foram
modificados dentro de seus endereços.
Para vetores, temos o seguinte protótipo:
void func (int matrx[50]);
void func (int matrx[]);
O mesmo ocorre com vetores bidimensionais (matrizes). Só temos uma
observação a ser feita. Ao passarmos vetores bidimensionais, devemos sempre
especificar o tamanho da “primeira dimensão”. Isto é feito para reconhecer o
endereço corretamente das “duas dimensões”.
Para vetores bidimensionais, temos o seguinte protótipo:
void func (int matrx[50][]);
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
33
o Recursividade
Uma poderosa característica de muitas linguagens de programação, incluindo o
C, é o fato de que uma função pode chamar a si mesma! Quando isso ocorre, dizemos
que a função é recursiva. Um exemplo clássico de função recursiva é para o cálculo de
fatorial. Veja o exemplo abaixo:
/*Exemplo de função recursiva*/
#include <stdio.h>
#include <stdlib.h>
int fatorial(int n)
{
if (n)
return n*fatorial(n-1); // Chama a própria função.
else return 1;
}
/* Enquanto n não for zero, a função fatorial chama a si mesma sempre com um
valor de n menor que o anterior. O critério de parada é n = 0. */
int main()
{
int n;
printf("\n\nDigite um valor para n: ");
scanf("%d", &n);
printf("\nO fatorial de %d eh %d", n, fatorial(n));
system(“pause”);
return 0;
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
34
Algumas observações relevantes devem ser feitas a respeito do uso da
recursividade:
Deve-se tomar bastante cuidado ao usar recursividade, tenha muita atenção no
critério de parada para evitar erros de lógica e que a função “se chame” infinitas vezes.
A cada vez que o computador faz uma chamada a uma função, é consumida uma
parcela da memória. Assim, o uso incorreto da recursividade pode esgotar
rapidamente a memória do computador. A recursividade é evitada, sempre que
possível.
o Escopo de variáveis
Variáveis locais: Este tipo de variável só tem validade dentro do bloco no qual
foram declaradas. Bloco, como foi dito anteriormente, é um conjunto de instruções
dentro de chaves { BLOCO }.Dessa forma, podemos declarar variáveis dentro de um
for. A característica que torna as variáveis locais tão importantes é justamente a de
serem exclusivas do bloco. Uma variável de nome A pode estar em quantos blocos
desejarmos, ela não causará conflito!
Alguns exemplos de variáveis locais são dados abaixo:
/*Variáveis locais*/
func1 (...)
{
int abc,x;
...
}
func (...)
{
int abc;
...
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
35
}
void main ()
{
int a,x,y;
for (...)
{
float a,b,c;
...
}
...
}
Variáveis globais: Este tipo de variável é declarada fora de todas as funções do
programa. Pode ser acessada e alterada por todas as funções do programa. Uma
função pode ter uma variável local com o mesmo nome de uma variável global.
Quando isto ocorrer, a função dará prioridade à variável local.
/*Variáveis globais e locais*/
int z,k;
func1 (...)
{
int x,y;
...
}
func2 (...)
{
int x,y,z;
...
z=10;
...
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
36
}
main ()
{
int count;
...
}
Variáveis formais: Este tipo de variável é a declarada como sendo à entrada de
uma função. Assim, seu escopo é de variável local da função.
o Exercícios de revisão
I.Escreva uma função que recebe um inteiro positivo m e devolve 1 se m é primo,
0 em caso contrário.
II.Escreva um programa que leia um inteiro não-negativo n e imprima a soma dos
n primeiros números primos.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
37
Exercícios Complementares
I. Faça um programa em C que recebe as notas de quatro estágios, a nota
de um exercício extra (que vale 1 ponto) e diga se o aluno foi aprovado
por média, reprovado por média ou para final, nesse último caso,
informar qual a nota mínima necessária para ser aprovado. (As regras de
aprovação serão as da UFCG)
II. Faça um programa que imprimi as n primeiras linhas do triângulo de
Pascal
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
III. Calcule a soma dos 10 primeiros termos da série de Taylor para a função
exponencial, para x = 1:
Determinando, dessa forma, um valor aproximado da constante de Euler.
IV. Faça um vetor de tamanho 100 que é preenchido com os 100 primeiros
naturais que não são múltiplos de 7 ou que terminam com 7.
V. Faça um programa que dada uma seqüência de n números reais,
determina o número de vezes que cada um deles ocorre na mesma.
VI. Escreva uma função que calcula o produto dos elementos da coluna j de
uma matriz real Amxn.
VII. Faça um programa que lê da entrada padrão duas matrizes 3x3, calcula o
produto de ambas e imprime o resultado na tela.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
38
VIII. Faça um programa que lê os coeficientes (a,b,c) de uma equação do
segundo grau da forma ax² + bx + c = 0, e informa se as raízes são duplas,
distintas ou complexas. Caso sejam duplas ou distintas, exibir as raízes.
IX. Escreva uma função que recebe uma matriz real Amxn e determina a sua
transposta (se B é a matriz transposta de A então aij = bji) e depois
imprime.
X. Faça uma função que verifica se uma matriz Amxm é a matriz identidade.
XI. Faça um jogo que simula o jogo de par ou impar. Usuário contra a
máquina.
XII. Dados n e dois números inteiros positivos, i e j, diferentes de 0, imprimir
em ordem crescente os n primeiros naturais que são múltiplos de i ou de
j e ou de ambos. Exemplo: Para n = 6 , i = 2 e j = 3 a saída deverá ser :
0,2,3,4,6,8.
XIII. Faça um programa que gera um número aleatório de 1 a 1000. O usuário
deve tentar acertar qual o número foi gerado, a cada tentativa o
programa deverá informar se o chute é menor ou maior que o número
gerado. O programa acaba quando o usuário acerta o número gerado. O
programa deve informar em quantas tentativas o número foi descoberto.
XIV. Faça uma função recursiva que retorna o n-ésimo valor da série de
Fibonacci. Onde o n-ésimo termo é a soma dos termos anteriores. Os dois
primeiros termos são 1. Vejamos os 10 primeiros termos:
1 1 3 5 8 13 21 34 55 89 ...
XV. Implemente a mesma função da questão anterior, mas de forma iterativa.
XVI. Implemente o jogo da velha, o programa deve informar quando o jogo
acaba e qual jogador venceu.
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
39
Resolução dos Exercícios Complementares
Questão 01:
#include <stdio.h>
#include <stdlib.h>
#define QUANT_NOTAS 4
int main() {
int i;
double notas[QUANT_NOTAS], ponto_extra, media = 0.0, media_final;
char nome[30];
//obtencao do nome do aluno
printf("Digite o nome do aluno: ");
gets(nome);
//obtencao das notas do aluno
for (i = 0; i < QUANT_NOTAS; i++) {
do {
printf("Digite a %dº nota: ", (i + 1));
scanf("%lf", ¬as[i]);
if (notas[i] < 0.0 || notas[i] > 10.0) {
printf("\nNota inválida! Nota tem que ser entre 0.0 e
10.0.\n");
}
} while (notas[i] < 0.0 || notas[i] > 10.0);
media += notas[i];
}
//obtencao da nota do exercicio extra
do {
printf("Digite a nota do exercício extra ");
scanf("%lf", &ponto_extra);
if (ponto_extra < 0.0 || ponto_extra > 1.0) {
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
40
printf("\nNota inválida! Nota tem que ser entre 0.0 e 1.0.\n");
}
} while (ponto_extra < 0.0 || ponto_extra > 1.0);
media += ponto_extra;
media /= QUANT_NOTAS;
media = media > 10.0 ? 10.0 : media; //caso a media fique acima de 10 (possivel
por causa do exercicio extra), a media eh modificada para 10
//impressao do resultado
if (media >= 7.0) {
printf("O aluno %s foi aprovado com a média de %lf\n", nome, media);
} else if (media >= 4.0) {
media_final = (50 - media * 6) / 4;
printf("O aluno %s foi para final com a média de %lf, e precisa de %lf
para passar\n", nome, media, media_final);
}
else {
printf("O aluno %s foi reprovado com a média de %lf\n", nome, media);
}
system("pause");
return 0;
}
Questão 02:
#include <stdio.h>
#include <stdlib.h>
#define TAM_MAX 40
int main() {
int n, i, j, triangulo_pascal[TAM_MAX][TAM_MAX];
//obtencao do tamanho do triangulo
printf("Digite o tamanho do triangulo de pascal: ");
scanf("%d", &n);
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
41
//inicializacao dos valores
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (j == 0)
triangulo_pascal[i][j] = 1;
else
triangulo_pascal[i][j] = 0;
}
}
//obtencao do triangulo
for (i = 1; i < n; i++) {
for (j = 1; j <= i; j++) {
triangulo_pascal[i][j] = triangulo_pascal[i - 1][j - 1]+
triangulo_pascal[i - 1][j];
}
}
//impressao do triangulo
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
printf("%d ", triangulo_pascal[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
Questão 03:
#include <stdio.h>
#include <stdlib.h>
#define QUANT 10
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
42
int main() {
int i;
double constante_euler = 0.0, denominador = 1.0;
//obtencao da constante de Euler
for(i = 0; i < QUANT; i++){
constante_euler += 1/denominador;
denominador *= (i+1);
}
//impressao do resultado
printf("O valor aproximado da constante de Euler eh %lf\n", constante_euler);
system("pause");
return 0;
}
Questão 04:
#include <stdio.h>
#include <stdlib.h>
#define TAM 100
//verifica se num nao eh multiplo de num2
int nao_eh_multiplo(int num, int num2);
//verifica se num termina em num2
int termina(int num, int num2);
int main() {
int vetor[TAM], pos = 0, aux = 0, i;
//obtencao dos valores
while (pos < TAM) {
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
43
if (nao_eh_multiplo(aux, 7) || termina(aux, 7)) {
vetor[pos] = aux;
pos++;
}
aux++;
}
//impressao do resultado
printf("Os %d primeiros numeros nao multiplos de 7 ou que terminam em 7 sao: \n",
TAM);
for (i = 0; i < TAM; i++) {
printf("%d ", vetor[i]);
}
system("pause");
return 0;
}
int nao_eh_multiplo(int num, int num2) {
if(num%num2!=0){
return 1;
}
return 0;
}
int termina(int num, int num2){
if(num % 10 == num2){
return 1;
}
return 0;
}
Questão 05:
#include <stdio.h>
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
44
#include <stdlib.h>
#define QUANT_MAX 100
//verifica se os dois numeros reais sao iguais a uma taxa de precisao de "precisao"
int equals(double num1, double num2, double precisao);
int main() {
int n, aux[QUANT_MAX], i, j, pos = 0, aux_pos;
double numeros[QUANT_MAX], num;
//obtencao do tamanho do vetor
printf("digite a quantidade de numeros: ");
scanf("%d", &n);
//obtencao dos numeros
for(i = 0; i < n; i++){
printf("digite o %dº numero: ", (i+1));
scanf("%lf", &num);
aux_pos = -1;
for(j = 0; j < pos; j++){
if(equals(numeros[j], num, 0.000001)){
aux_pos = j;
break;
}
}
if(aux_pos == -1){
aux[pos] = 1;
numeros[pos] = num;
pos++;
}else{
aux[aux_pos]++;
}
}
//impressao do resultado
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
45
printf("Numero\t\tQuantidade de repeticoes\n");
for(i = 0; i < pos; i++){
printf("%lf\t\t%d\n", numeros[i], aux[i]);
}
system("pause");
return 0;
}
int equals(double num1, double num2, double precisao){
if(num2 <= num1+precisao && num2 >= num1-precisao) return 1;
return 0;
}
Questão 06:
#include <stdio.h>
#include <stdlib.h>
#define TAM_MAX 50
int main() {
double matriz[TAM_MAX][TAM_MAX], resultado = 1.0;
int m, n, i, j, coluna;
//obtencao do tamanho da matriz
printf("digite a quantidade de linhas da matriz: ");
scanf("%d", &m);
printf("digite a quantidade de colunas da matriz: ");
scanf("%d", &n);
//obtencao da matriz
printf("Digite os valores da matriz A:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Digite o valor de A[%d][%d]: ", (i + 1), (j + 1));
scanf("%lf", &matriz[i][j]);
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
46
}
}
//obtencao da coluna da matriz que serao multiplicados os valores
do {
printf("Digite a coluna em que se deseja multiplicar os valores: ");
scanf("%d", &coluna);
if (coluna <= 0 || coluna > n) {
printf("Valor de coluna invalido. Digite um valor entre 1 e %d\n",
n);
}
} while (coluna <= 0 || coluna > n);
//impressao da matriz e obtencao do resultado
printf("matriz A: \n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%lf ", matriz[i][j]);
if ((j+1) == coluna)
resultado *= matriz[i][j];
}
printf("\n");
}
//impressao do resultado
printf("O resultado da multiplicacao dos elementos da coluna %d eh %lf\n",
coluna, resultado);
system("pause");
return 0;
}
Questão 07:
#include <stdio.h>
//Cabeçalhos das funções
void lermatriz(float[][3]);
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
47
void imprime(float[][3]);
void produto(float[][3],float[][3],float[][3]);
//Função Main: declaração das variáveis e chamada de funções
int main(){
float a[3][3];
float b[3][3];
float c[3][3];
lermatriz(a);
puts("Matriz A:");
imprime (a);
lermatriz(b);
puts("\n\nMatriz B:");
imprime (b);
produto(a,b,c);
puts("\n\nO valor de A.B:");
imprime(c);
getch();
}
//Função que lê os valores de uma matriz da entrada padrão (teclado)
//Note que uma função para isso evita que tenhamos que copiar o código 2 vezes
//uma para ler A e outra para ler B
void lermatriz(float mat[][3]){
int i, j;
float temp;
puts("\n\nInsira os 9 valores");
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{scanf("%f",&temp);
mat[i][j]=temp;
fflush(stdin); //Necessário para limpeza do buffer de entrada
}
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
48
//Função que imprime na tela uma matriz 3x3
//Essa função também evita que o código seja escrito duas vezes
void imprime(float mat[][3]){
int i, j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%.2f\t",mat[i][j]);
putchar('\n'); //Pula linha a cada nova linha da matriz
}
}
//Função para calcular o produto de duas matrizes 3x3, analise-o com cuidado
void produto(float a[][3],float b[][3],float prod[][3]){
int i, j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
prod[i][j]= a[i][0]*b[0][j]+a[i][1]*b[1][j]+a[i][2]*b[2][j];
}
Questão 08:
#include <stdio.h>
#include <math.h> //Necessária para a função sqrt()
//Função Main: todo código foi escrito nela, pois é um programa simples
int main(){
//Declaração dos parâmetros da equação
float a,b,c,delta;
float x1,x2;
//Leitura dos parâmetros
puts("Insira o valor de a");
scanf("%f",&a);
puts("Insira o valor de b");
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
49
scanf("%f",&b);
puts("Insira o valor de c");
scanf("%f",&c);
//Calculo do Delta
delta = b*b - 4*a*c;
//Checagem do sinal do delta, e calculo das soluções caso sejam reais
//Note que usamos a fórmula de Baskhara
if (delta<0)
puts("Raizes Complexas");
else if(delta==0){
puts("Raizes Reais Repetidas");
x1 = -b/(2*a);
printf("\nA raiz eh %.2f",x1);
}
else{
puts("Raizes Reais Distintas");
x1 = (-b -sqrt(delta))/(2*a);
x2 = (-b +sqrt(delta))/(2*a);
printf("\nAs raizes sao %.2f e %.2f",x1,x2);
}
getch();
}
Questão 09:
#include <stdio.h>
//Cabeçalho das funções
void lermatriz(float[][3]);
void imprime(float[][3]);
void transposta(float[][3],float[][3]);
//Função Main: declaração das variáveis e chamada de funções
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
50
int main(){
float a[3][3];
float b[3][3];
lermatriz(a);
puts("\n\nMatriz A:");
imprime (a);
transposta(a,b);
puts("\n\nTransposta de A:");
imprime (b);
getch();
}
//Função que lê os valores de uma matriz da entrada padrão (teclado)
void lermatriz(float mat[][3]){
int i, j;
float temp;
puts("\n\nInsira os 9 valores");
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{scanf("%f",&temp);
mat[i][j]=temp;
fflush(stdin); //Necessário para limpeza do buffer de entrada
}
}
//Função que imprime na tela uma matriz 3x3
void imprime(float mat[][3]){
int i, j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%.2f\t",mat[i][j]);
putchar('\n'); //Pula linha a cada nova linha da matriz
}
}
//Função que guarda na matriz do segundo argumento a transposta da matriz do
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
51
//primeiro argumento
void transposta(float a[][3],float trans[][3]){
int i, j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
trans[i][j]= a[j][i]; //Definição de transposta
}
Questão 10:
#include <stdio.h>
//Cabeçalho das funções
void lermatriz(float[][3]);
void imprime(float[][3]);
int checa(float[][3]);
//Função Main: declaração das variáveis, chamada de funções e controle do fluxo
//do programa através de uma variável flag
int main(){
int id; //Variável que guardará o valor 1 caso seja identidade e 0 caso contrário
float a[3][3];
lermatriz(a);
puts("\n\nMatriz A:");
imprime (a);
id = checa(a); //checa() retorna 1 caso a seja identidade e 0 caso contrário
if(id) puts("\nMatriz Identidade");
else puts("\nMatriz nao eh identidade");
getch();
}
//Função que lê os valores de uma matriz da entrada padrão (teclado)
void lermatriz(float mat[][3]){
int i, j;
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
52
float temp;
puts("Insira os 9 valores");
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{scanf("%f",&temp);
mat[i][j]=temp;
fflush(stdin); //Necessário para limpeza do buffer de entrada
}
}
void imprime(float mat[][3]){
int i, j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%.2f\t",mat[i][j]);
putchar('\n'); //Pula linha a cada nova linha da matriz
}
}
int checa(float a[][3]){
int i, j;
int flag = 1; //A variável flag inicialmente é 1, caso achemos algo que
for(i=0;i<3;i++) //quebre a definição de matriz identidade, ela é setada em 0
for(j=0;j<3;j++){
if(i==j){
if(a[i][j]!=1) flag = 0;}
else
if(a[i][j]!=0) flag = 0;
}
return flag;
}
Questão 11:
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
53
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
//Função Main: como o programa é simples, tudo foi feito nela
int main(){
int n_jog, n_pc, opcao, total;
srand(time(NULL)); //Semente para a função geradora de números aleatórios
puts("Jogo de Par ou Impar contra o Computador");
puts("\nPar ou Impar? Digite 0 para Par e 1 para Impar");
scanf("%d",&opcao);
if(opcao) puts("\nVoce escolheu Impar");
else puts("\nVoce escolheu Par");
puts("\nQual numero voce quer jogar?");
scanf("%d",&n_jog);
n_pc = rand()%10; //Pc só joga de 0 a 9
printf("\nO computador jogou %d",n_pc);
total = n_pc+n_jog;
printf("\n\nA soma dos numeros eh %d",total);
if(total%2 == opcao) puts("\n\nParabens, voce ganhou"); //Caso o resto da
else puts("\n\nQue pena, voce perdeu"); // divisão por 2 seja igual a opção
getch(); // escolhida, você
acertou a paridade
}
Questão 12:
/*Dados n e dois números inteiros positivos i e j diferentes de 0, imprimir
em ordem crescente os n primeiros naturais que são múltiplos de i ou de j e ou
de ambos. Exemplo: Para n = 6 , i = 2 e j = 3 a saída deverá ser : 0,2,3,4,6,8.*/
#include<stdio.h>
#include<stdlib.h>
main()
{
int n, i, j, cont, aux_i = 0, aux_j = 0, m;
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
54
printf("Digite o numero de termos da sequencia ");
scanf("%d", &n);
printf("\nDigite os numeros i e j ");
scanf("%d%d",&i,&j);
for(cont = 0; cont < n; )
{
if(aux_i*i <= aux_j*j){ // Imprime um múltiplo de i, se ele for menor que o
múltiplo de j
printf("%d ", aux_i*i);
cont++; // Incrementa o contador, pois um número foi impresso
aux_i++;} // Incrementa o fator que multiplica o numero i
else{
if( (aux_j*j)% i != 0){ // Imprime um múltiplo de j, desde que ele não seja
múltiplo de i
printf("%d ", aux_j*j);
cont++;} // Incrementa o contador, pois um número foi impresso
aux_j++;} // Incrementa o fator que multiplica o numero j
}
system("pause>>null");
return 0;
}
Questão 13:
#include<stdio.h>
#include<stdlib.h>
#include<time.h> // Essa biblioteca é necessária para gerar a semente para a função
geradora
// de números aleatórios
main() //Função Principal
{
int n, tentativa, cont = 0;
srand(time(NULL)); // Muda a semente para a função geradora de números aleatórios
n = (rand() % 1000) + 1; // Gera um numero aleatório de 1 a 1000
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
55
do{
system("cls"); // Limpa a tela do programa
cont++;
printf("Um numero entre 1 e mil foi sorteado, tente adivinha-lo \nTentativa - ");
scanf("%d", &tentativa);
if(tentativa < n){
printf("\nO numero que voce digitou eh menor que o numero sorteado \nPressione
“
“qualquer tecla para tentar novamente");
system("pause>>null");}
else if(tentativa > n){
printf("\nO numero que voce digitou eh maior que o numero sorteado \nPressione
“
“qualquer tecla para tentar novamente");
system("pause>>null");}
}while(tentativa != n); // O programa pede novas tentativas até que o usuário
adivinhe o
//número sorteado
printf("\nParabens!!! Voce acertou o numero sorteado! \nVoce precisou de um total de
%d “
“ tentativas para acertar",cont);
system("pause>>null");
return 0;
}
Questão 14:
/*Faça uma função recursiva que retorna o n-ésimo valor da série de Fibonacci.
Onde o n-ésimo termo é a soma dos termos anteriores. Os dois primeiros termos
são 1. Vejamos os 10 primeiros termos: 1 1 2 3 5 8 13 21 34 55 ...*/
#include<stdlib.h>
#include<stdio.h>
int fibonacci(int); // Protótipo da função fibonacci
main()// Função Principal
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
56
{
int n;
printf("Digite o termo da sequencia de fibonacci que vc deseja saber: ");
scanf("%d", &n);
printf("\n\nO %d termo da sequencia de fibonacci eh %d", n, fibonacci(n));
system("pause>>null");
return 0;
}
int fibonacci(int n) // Função que retorna o n-ésimo termo da sequência de fibonacci
{
if(n > 2) // A condição de parada é n ser menor que 2
return fibonacci(n-1) + fibonacci(n-2); // Note que a função "chama" a si mesma
else
return 1;
}
Questão 15:
#include<stdlib.h>
#include<stdio.h>
int fibonacci(int); // Protótipo da função fibonacci
main() // Função Principal
{
int n;
printf("Digite o termo da sequencia de fibonacci que vc deseja saber: ");
scanf("%d", &n);
printf("\n\nO %d termo da sequencia de fibonacci eh %d", n, fibonacci(n));
system("pause>>null");
return 0;
}
int fibonacci(int n) // Função que retorna o n-ésimo termo da sequência de fibonacci
{
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
57
int cont, fib[3] = {1,1,1};
for(cont = 2; cont < n; cont++)
{
fib[2] = fib[1] + fib[0]; // Um termo é igual a soma dos dois anteriores
fib[0] = fib[1]; //Muda as variáveis de posição
fib[1] = fib[2]; // para que possamos calcular o próximo termo
}
return fib[2];
}
Questão 16:
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
void mostra_jogo(char[][3]);
void jogada_jogador(char [][3], int, int, int); // Protótipos de todas as funções
int teste_jogada(char[][3], int, int);
int teste_fim_de_jogo(char [][3]);
void inicia_jogo(char[][3]);
main() // Função Principal
{
char jogo[3][3], opcao;
int linha, coluna;
srand(time(NULL)); // Muda a semente para a função geradora de números aleatórios
system("TITLE JOGO DA VELHA"); // Coloca a frase JOGO DA VELHA como título da
janela
do{
inicia_jogo(jogo); // Chama a função que inicializa a matriz jogo
do
{
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
58
system("cls"); // Limpa a tela do programa
mostra_jogo(jogo); // Chama a função que imprime o jogo na tela
printf("\n\n\nDigite a linha e a coluna (nessa ordem) do espaco"
" que deseja marcar (Voce eh o 'X'):");
scanf("%d%d", &linha,&coluna);
while(teste_jogada(jogo,linha,coluna)) // Testa a validade da jogada
{ //e, caso a jogada seja inválida, pede outros valores
printf("\nJogada invalida. Escolha outro espaco: ");
scanf("%d%d", &linha,&coluna);
}
jogada_jogador(jogo,linha,coluna, 1); // Chamada à função que
// insere a jogada na matriz jogo (jogador 1 = X)
if(teste_fim_de_jogo(jogo) == 1)//Testa se o usuário venceu o jogo
{
system("cls");
mostra_jogo(jogo);
printf("\nParabens!!!! Voce eh o vencedor!");
break;
}
else if(teste_fim_de_jogo(jogo) == 2) // Testa se o jogo terminou empatado
{
system("cls");
mostra_jogo(jogo);
printf("\nO jogo terminou empatado! Tente Novamente.");
break;
}
do
{
linha = rand() % 3; // Gera valores válidos para
coluna = rand() % 3; // a jogada do computador
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
59
}while(teste_jogada(jogo,linha,coluna));
jogada_jogador(jogo,linha,coluna, 2);// Chamada à função que
// insere a jogada na matriz jogo (jogador 2 = O)
if(teste_fim_de_jogo(jogo) == 1)//Testa se o computador venceu
{ // venceu o jogo
system("cls");
mostra_jogo(jogo);
printf("\nVoce perdeu! Tente Novamente...");
break;
}
else if(teste_fim_de_jogo(jogo) == 2)//Testa se houve empate
{
system("cls");
mostra_jogo(jogo);
printf("\nO jogo terminou empatado! Tente Novamente.");
break;
}
}while(1);
printf("\nDeseja jogar novamente? (s/n) ");
fflush(stdin); // Limpa o buffer de entrada
opcao = getchar();
}while(opcao == 's' || opcao == 'S');
return 0;
}
void inicia_jogo(char jogo [3][3]) // Função que incializa a matriz jogo
{ // com espaços em branco (início do jogo)
int linha, coluna;
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
60
for(linha = 0; linha < 3; linha ++)
for(coluna = 0; coluna < 3; coluna++)
jogo[linha][coluna] = ' ';
}
void mostra_jogo(char jogo[3][3]) // Função que mostra o jogo da velha
{
printf("\t\t\t 0 1 2\n\t\t\t | |\n"
"\t\t\t0 %c | %c | %c\n\t\t\t__________|__________|__________\n"
"\t\t\t | |\n"
"\t\t\t1 %c | %c | %c\n\t\t\t__________|__________|__________\n"
"\t\t\t | |\n\t\t\t2 %c | %c | %c\n"
"\t\t\t |
|\n",jogo[0][0],jogo[0][1],jogo[0][2],jogo[1][0],jogo[1][1],
jogo[1][2],jogo[2][0],jogo[2][1],jogo[2][2]);
}
//Função que insere a jogada dos jogadores na matriz jogo, com o símbolo correspondente
(X ou O)
void jogada_jogador(char jogo[3][3], int linha, int coluna, int numero_jogador)
{
if(numero_jogador == 1)
jogo[linha][coluna] = 'X';
else
jogo[linha][coluna] = 'O';}
//Função que teste a validade das jogadas
//retorna 0 para jogadas válidas e 1 para jogadas inválidas
int teste_jogada(char jogo[3][3], int linha, int coluna)
{
if(jogo[linha][coluna] != ' ' || linha > 2 || coluna > 2 || linha < 0 || coluna < 0)
return 1;
else
return 0;
}
//Função que checa se o jogo acabou
// retorna 1 em caso de vitória de um jogador, 2 em caso de empate e
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
61
// 0 caso o jogo deva continuar
int teste_fim_de_jogo(char jogo[3][3])
{
int linhas[3] = {0}, colunas[3] = {0}, diagonais[2] = {0}, cont_linha, cont_coluna,
cont = 0,
cont_espacos_vazios = 9;
for(cont_linha = 0; cont_linha < 3; cont_linha ++)
{
for(cont_coluna = 0; cont_coluna < 3; cont_coluna++)
{
linhas[cont] += jogo[cont_linha][cont_coluna]; // Soma os elementos da
linha cont
colunas[cont] += jogo[cont_coluna][cont_linha];// Soma os elementos da
coluna cont
if(jogo[cont_linha][cont_coluna] != ' ')//Conta os espaços vazios
restantes
cont_espacos_vazios--;
if(cont_linha == cont_coluna) // Soma os elementos da diagonal principal
diagonais[0] += jogo[cont_linha][cont_coluna];
if((cont_linha + cont_coluna) == 2)// Soma os elementos da diagonal
secundária
diagonais[1] += jogo[cont_linha][cont_coluna];
//Se a soma de uma linha, coluna ou diagonal dividida por 3 for X(88) ou
O(79),
//houve um vencedor e a função retorna 1
if(linhas[cont] / 3 == 88 || linhas[cont] / 3 == 79 || colunas[cont] / 3
== 88
|| colunas[cont] / 3 == 79 || diagonais[0] / 3 == 88
|| diagonais[1] / 3 == 88 || diagonais[0] / 3 == 79 || diagonais[1] / 3 ==
79)
return 1;
}
cont++;
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
62
if(!cont_espacos_vazios) // Se o número de espaços vazios for 0, houve empate
return 2; // e a função retorna 2
else
return 0; // A função retorna 0, caso não haja vitória nem empate
}
Curso Introdutório à Linguagem C
Nustenil Segundo e Dinart Duarte
63
Bibliografia
Mesquita R. C. Apostila: Curso de Linguagem C. UFMG.
Projeto Mac Multimídia - Material Didático para disciplinas
de Introdução à Computação - http://www.ime.usp.br/~macmulti/ - acessado no dia
29/09/2008
Introdução à Linguagem C. Centro de Computação, UNICAMP.
Schildt, H. C - Completo e Total . Editora McGraw-Hill, 1990.
Gurjão, E. C.Notas de Aula: Introdução a Programação – UFCG, 2006.