Preview only show first 10 pages with watermark. For full document please download

Linguagem C - Ufcg

Um pequeno compilado sobre os princípios da Linguagem C, com exercicios resolvidos e propostos, desenvolvidos para o curso de Eng. Elétrica da UFCG.

   EMBED


Share

Transcript

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 Í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 2 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte  Exercícios complementares  Resolução dos exercícios complementares  Bibliografia 3 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte  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) DevC++, 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 4 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte  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 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. 5 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 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. 6 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte  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 %d %f %c %s %H %% Significado Inteiro Float Caractere String 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% 7 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 // Biblioteca que contém as funções scanf printf #include //Biblioteca que contém a função system int main () { int idade; 8 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 Soma variáveis Subtrai variáveis Multiplica variáveis Divide variáveis Retorna o resto da divisão inteira Incrementa uma variável Decrementa uma variável Tipo Unário ou Binário Unário ou Binário Binário Binário Binário Unário 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. 9 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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; e = -a; b = (3 + 3.14)/5.; f=a++; c++; g=++a; d = ((132324%3)*3)--; 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) E = (1<3)==1 (D =1 ) D = 10==9 (D = 0) F = A>B 10 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  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) { 12 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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; 13 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte Vejamos um exemplo: #include #include 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: 14 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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; 15 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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: 16 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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" 17 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte } 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){ 18 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include int main () { int contador; for (contador=1; contador<=100; contador++) printf ("%d ",contador); system(“pause”); return(0); } 19 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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. 20 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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: Incorreto: idades[10] = idades[50]; idades[100]=idades[0]; idades[0] = idades [3]-idades[8]; idades[-1]=idades[3]; idades[i]= idades[i+5] 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 #include 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”); 21 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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. 22 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte Vejamos um exemplo de aplicação que utiliza matrizes bidimensionais: /*Exemplo de uso de matrizes bidimensionais*/ #include #include 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: 23 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte /*Sintaxe para declaração de matrizes n-dimensionais*/ tipo nome_da_matriz[tamanho 1][tamanho 2][tamanho 3]...[tamanho n1][tamanho n]; 24 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 pseudoaleató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. 25 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 . 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 */ 26 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte #include #include /*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. 27 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include 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; } 28 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include /*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; } 29 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte int quadrado(int a) { return (a*a); } /*Exemplo 2*/ #include #include 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) return 0; /* Verifica se a e divisivel por dois */ /* Retorna 0 se nao for divisivel */ else return 1; /* Retorna 1 se for divisivel */ 30 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte } 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 #include void Mens (void); int main () { Mens(); printf ("\tRepita!:\n"); Mens(); system(“pause”); return 0; } 31 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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][]); 32 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include 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; } 33 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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; ... 34 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte } 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; ... 35 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte } 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. 36 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte  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. 37 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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. 38 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte  Resolução dos Exercícios Complementares Questão 01: #include #include #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) { 39 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include #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); 40 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte //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 #include #define QUANT 10 41 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include #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) { 42 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 43 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte #include #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 44 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include #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]); 45 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte } } //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 //Cabeçalhos das funções void lermatriz(float[][3]); 46 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 } } 47 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte //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 #include //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"); 48 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 //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 49 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 50 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte //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 //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; 51 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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: 52 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte #include #include #include //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(); acertou a paridade // escolhida, você } 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 #include main() { int n, i, j, cont, aux_i = 0, aux_j = 0, m; 53 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include #include // 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 54 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include int fibonacci(int); // Protótipo da função fibonacci main()// Função Principal 55 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte { 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 #include 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 { 56 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 #include #include 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 { 57 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 58 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte }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; 59 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 "\t\t\t0 %c "\t\t\t "\t\t\t1 "\t\t\t 0 | 1 %c | %c | 2\n\t\t\t | | |\n" %c\n\t\t\t__________|__________|__________\n" |\n" %c | | %c\n\t\t\t__________|__________|__________\n" |\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 60 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte // 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 colunas[cont] += jogo[cont_coluna][cont_linha];// Soma os elementos da linha cont 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++; } 61 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte 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 } 62 Curso Introdutório à Linguagem C Nustenil Segundo e Dinart Duarte  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. 63