Commit a8f6ad74 authored by Jomaro Rodrigues's avatar Jomaro Rodrigues

Merge branch 'master' of gitlab.c3sl.ufpr.br:pet/apostila_c

parents 93e18c87 06477d86
/* calcula a media de n notas especificadas pelo usuario */
#include <stdlib.h>
#include <stdio.h>
int main() {
double *notas, media=0;
int i, n;
printf ("Digite o numero de notas: ");
scanf ("%d", &n); /* obtem o numero de notas */
if (n < 1) { /* verifica se o numero e valido */
printf ("Numero invalido! Deve ser maior que zero.\n");
return;
}
/* aloca memoria */
notas = (double*) malloc (n * sizeof(double));
for (i = 0; i < n; i++) { /* obtem as notas */
printf ("Digite a %da. nota: ", i+1);
scanf ("%lf", (notas+i));
}
/* calcula a media das notas */
for (i = 0; i < n; i++)
media += *(notas+i);
media /= n;
printf ("A media das notas e: %f\n", media);
free (notas); /* desaloca a memoria alocada previamente */
}
#include <stdio.h>
#include <stdlib.h> //Na apostila nao tem, sem isto nao da para usar exit
void main(int count, char *parametros[]) {
if (count != 2) {
printf("Voce esqueceu de digitar o seu nome!\n");
exit(0);
}
printf ("Alo %s\n", parametros[1]);
}
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
int i;
for (i=1; i < argc; i++) {
if(system(argv[i])) {
printf("%s falha\n", argv[i]);
return -1; /* codigo de falha */
}
}
return 0; /* retorna o codigo de sucesso da operacao */
}
/* O programa que le arquivos e exibe-os na tela */
#include <stdio.h>
#include <stdlib.h>
void main (int argc, char *argv[]) {
FILE *fp;
char ch;
if (argc != 2) {
printf ("Voce esqueceu de informar o nome do arquivo!\n");
exit (1);
}
if ((fp = fopen(argv[1], "r")) == NULL) {
printf ("O arquivo nao pode ser aberto\n");
exit (1);
}
ch = getc(fp); /* le um caractere */
while (ch != EOF) {
/* repete enquanto nao for o final do arquivo */
printf("%c", ch); /* imprime caracter lido na tela */
ch = getc(fp); /* le proximo caracter */
}
fclose(fp); /*fecha o arquivo */
}
#include <stdio.h>
void main() {
int contagem;
for(contagem = 0; contagem < 10; contagem++) {
if (contagem == 5) /* quando contagem for 5 */
break; /* interrompe o loop */
printf ("%d ", contagem);
}
printf ("\n");
}
#include <stdio.h>
void main() {
char c;
char *pc;
pc = &c; /* pc aponta para c */
for (c = 'A'; c <= 'Z'; c++)
printf ("%c ", *pc); /* derreferencia o ponteiro */
printf("\n");
}
#include <string.h>
#include <stdio.h>
int main (){
char str[] = "Aritmetica de Ponteiros";
char *p;
p = &str[0];
printf ("*p = %c\n", *p);
printf ("*(p+1) = %c\n", *(p+1));
printf ("*(p+5) = %c\n", *(p+5));
printf ("*(p+7) = %c\n", *(p+7));
}
#include <stdio.h>
#include <stdlib.h>
struct coord {
int x;
int y;
};
struct retang {
struct coord esqcima;
struct coord dirbaixo;
};
void main() {
int altura, largura;
long area;
struct retang quadro;
/* recebe as coordenadas */
printf("Digite a coordenada x superior esq.: ");
scanf("%d", &quadro.esqcima.x);
printf("digite a coordenada y superior esq.: ");
scanf("%d", &quadro.esqcima.y);
printf("Digite a coordenada x inferior dir.: ");
scanf("%d", &quadro.dirbaixo.x);
printf("digite a coordenada y inferior dir.: ");
scanf("%d", &quadro.dirbaixo.y);
/* calcula o comprimento e a largura */
largura = quadro.dirbaixo.x - quadro.esqcima.x;
altura = quadro.esqcima.y - quadro.dirbaixo.y;
/* calcula e informa a area */
area = abs(largura * altura);
printf("O retangulo tem uma area de %ld unidades.\n", area);
//O exemplo da apostila daria numero negativo
}
/* Passando argumentos por valor e referencia */
#include <stdio.h>
struct coord {
int x;
int y;
};
void por_valor( struct coord );
void por_ref( struct coord * );
void main () {
struct coord ponto;
ponto.x = 2;
ponto.y = 4;
printf("Antes de chamar por_valor(): x = %d, y = %d\n", ponto.x, ponto.y);
por_valor(ponto); /* chamada por valor */
printf("Depois de chamar por_valor(): x = %d, y = %d\n", ponto.x, ponto.y);
por_ref(&ponto); /* chamada por referencia */
printf("Depois de chamar por_ref(): x = %d, y = %d\n", ponto.x, ponto.y);
}
void por_valor(struct coord ponto) {
ponto.x = ponto.y = 0;
}
void por_ref(struct coord *ponto) {
ponto->x = ponto->y = 0;
}
#include <stdio.h>
#include <stdlib.h>
void main() {
char vogal;
printf("Digite uma vogal: ");
scanf("%c", &vogal); /* le uma letra */
switch (vogal) {
case 'a': vogal='e'; break;
case 'e': vogal='i'; break;
case 'i': vogal='o'; break;
case 'o': vogal='u'; break;
case 'u': vogal='a'; break;
default: printf("Erro!A letra nao e vogal\n");
exit(0);
};
printf ("A vogal subsequente eh %c\n", vogal);
}
#include <stdio.h>
int prox_par(void) {
static int pares = -2;
pares += 2;
return (pares);
}
void main(void) {
int i;
printf ("Os numeros pares menores que 100 sao: "); //Se seguir apostila tem que ser 200
for(i = 0; i < 50; i++) { //Apostila i < 100
printf ("%d ", prox_par());
}
printf ("\n");
}
struct pessoa {
char nome[30];
int sexo: 1; /* 0-> feminino, 1->masculino */
int idade: 7;
int estado_civil: 2;
/* 0-> solteiro
1-> casado
2-> desquitado
3->viuvo */
} pessoas[2];
int main () {
pessoas[0].nome = "Jose Maria da Silva"; //Verificar!!!!
pessoas[0].sexo = 1; /* masculino */
pessoas[0].idade = 34;
pessoas[0].estado_civil = 0; /* solteiro */
}
\ProvidesClass{pet-apostila}[2011/12/23 Apostilas para o PET Computação UFPR]
%% Process given options
\ProcessOptions\relax
%% Load base
\LoadClass[a4paper]{book}
\RequirePackage[brazil]{babel}
\RequirePackage[utf8]{inputenc}
\RequirePackage{subfiles}
\RequirePackage{listings}
\RequirePackage{verbatim}
\RequirePackage{amsmath, amssymb}
\RequirePackage{textcomp}
\RequirePackage{lmodern}
\RequirePackage{indentfirst}
\RequirePackage{color}
\definecolor{mygreen}{rgb}{0,0.6,0}
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
\definecolor{mymauve}{rgb}{0.58,0,0.82}
\lstset{ %
backgroundcolor=\color{white},
% choose the background color; you must add
%\usepackage{color} or \usepackage{xcolor}
basicstyle=\scriptsize,
% the size of the fonts that are used for the code
breakatwhitespace=false,
% sets if automatic breaks should only happen at whitespace
breaklines=true,
% sets automatic line breaking
captionpos=b,
% sets the caption-position to bottom
commentstyle=\color{mygreen},
% comment style
deletekeywords={...},
% if you want to delete keywords from the given language
escapeinside={\%*}{*)},
% if you want to add LaTeX within your code
extendedchars=true,
% lets you use non-ASCII characters; for 8-bits encodings only,
% does not work with UTF-8
frame=single,
% adds a frame around the code
keepspaces=true,
% keeps spaces in text, useful for keeping indentation of code (possibly
% needs columns=flexible)
keywordstyle=\color{blue},
% keyword style
language=C,
% the language of the code
otherkeywords={*,...},
% if you want to add more keywords to the set
numbers=left,
% where to put the line-numbers; possible values are (none, left, right)
numbersep=5pt,
% how far the line-numbers are from the code
numberstyle=\tiny\color{mygray},
% the style that is used for the line-numbers
rulecolor=\color{black},
% if not set, the frame-color may be changed on line-breaks within
% not-black text (e.g. comments (green here))
showspaces=false,
% show spaces everywhere adding particular underscores; it overrides
% 'showstringspaces'
showstringspaces=false,
% underline spaces within strings only
showtabs=false,
% show tabs within strings adding particular underscores
stepnumber=1,
% the step between two line-numbers. If it's 1, each line will be
% numbered
stringstyle=\color{mymauve},
% string literal style
tabsize=4,
% sets default tabsize to 2 spaces
%title=\lstname
% show the filename of files included with
%\lstinputlisting; also try caption instead of title
}
\lstset{literate=
{á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
{Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
{à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
{À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
{ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
{Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
{â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
{Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
{œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
{ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
{}{{\EUR}}1 {£}{{\pounds}}1
{ã}{{\~a}}1 {õ}{{\~o}}1 {ç}{{\,c}}1
}
\endinput
\ No newline at end of file
......@@ -2,232 +2,116 @@
\begin{document}
Recursividade
Recursividade é uma t'ecnica de programação que envolve utilizar defini,cões recursivas de modo a simplificar vários algoritmos.
\chapter{RECURSIVIDADE}
Uma definição recursiva é uma defini,c~ao que utiliza a si mesmo para se definir. A princípio, a id'eia
\emph{Recursividade} é uma técnica de programação que envolve utilizar definições recursivas de modo a simplificar vários algoritmos.
Uma definição recursiva é uma definição que utiliza a si mesma para se definir. A princípio, a ideia
pode parecer confusa e obscura, mas na realidade é um conceito relativamente simples.
Por exemplo, é possível definir uma exponenciação dessa maneira:
Seja n, k 2 N,
n
0
= 1
n
k
= n:n
k\Gamma 1
Observe que, no exemplo acima, a exponenciação nk está sendo definida através de uma outra exponencia,c~ao (n
k\Gamma 1
), ou seja, este é um caso em que a exponenciação 'e definida atrav'es dela mesma (o que
é uma definição recursiva ou tamb'em chamada de recorr^encia).
Analisando um pouco melhor o exemplo acima, n
k\Gamma 1
também 'e uma exponenciação, portanto poderia
utilizar a mesma definição para se definir, ou seja, se tomamos n
k\Gamma 1
= n:n
k\Gamma 2
ê assim podemos definir
n
k\Gamma 2
, nk \Gamma 3, etc.
Note que deveria haver um momento em que a definição termina, pois sen~ao seria impossível calcular
n
k
. Por isso, toda definição recursiva deve ser acompanhada de um caso trivial que será o final da
definição. No exemplo apresentado, n
0
= 1 é o caso trivial e determina o final da recursividade sobre n
k
.
Assim, seria possível calcular, por exemplo 3
3
:
Seja n, k \in N,
3
n^0 = 1
3
n^k = n.n^{k-1}
= 3:3
2
Observe que, no exemplo acima, a exponenciação n^k está sendo definida através de
uma outra exponenciação (n^{k-1}), ou seja, este é um caso em que a exponenciação
é definida através dela mesma (o que é uma definição recursiva ou também chamada de recorrência).
, 3
Analisando um pouco melhor o exemplo acima, n^{k-1} também é uma exponenciação,
portanto poderia utilizar a mesma definição para se definir, ou seja, se tomamos
n^{k-1} = n.n^{k-2} e assim podemos definir, n^{k-3}, etc.
2
Note que deveria haver um momento em que a definição termina, pois senão seria
impossível calcular n^k. Por isso, toda definição recursiva deve ser acompanhada
de um caso trivial que será o final da definição. No exemplo apresentado, n^0 = 1
é o caso trivial e determina o final da recursividade sobre n^k.
= 3:3
Assim, seria possível calcular, por exemplo 3^3:
1
3^3 = 3.3^2, 3^2 = 3.3^1, 3^1=3.3^0, 3^0 = 1 \Rightarrow 3^1 = 3.1, 3^2 = 3.3, 3^3 = 3.3.3
, 3
1
= 3:3
0
, 3
0
= 1 ) 3
1
= 3 3
2
= 3:3 e 3
3
= 3:3:3
Na linguagem C, funções podem chamar a si próprias, ou seja, fun,c~oes podem ser recursivas também,
Na linguagem C, funções podem chamar a si próprias, ou seja, funções podem ser recursivas também,
já que podem ser definidas através delas mesmas.
Para uma linguagem permitir recursividade, uma função deve estar apta a chamar a si própria. Um
êxemplo clássico de recursividade em programação é a fun,c~ao que calcula o fatorial de um número.
êxemplo clássico de recursividade em programação é a função que calcula o fatorial de um número.
\begin{lstlisting}
-Exemplo 1: Duas versões de fatorial -
/* não recursiva */
/* não recursiva */
int fat (int n)
f int t, resp;
{
int t, resp;
resp = 1;
for (t = 1; t <= n; t++)
resp = resp*t;
return resp;
}
resp = 1;
for (t=1; t!=n; t++)
resp = resp*t;
return resp;
g
/* recursiva */
int fat (int n)
f int resp;
if (n!2) return 1;
resp = fat(n-1)*n;
return resp;
g
85
86 AP
^
êNDICE E. RECURSIVIDADE
O funcionamento da função fat n~ao recursiva deve estar claro. Ela usa uma repeti,c~ao come,cando
{
int resp;
if (n < 2) return 1;
resp = fat(n-1)*n;
return resp;
}
\end{lstlisting}
O funcionamento da função \emph{fat} não recursiva deve estar claro. Ela usa uma repetição começando
com 1 e terminando com o valor objetivado e multiplica progressivamente cada número pelo produto
acumulado.
A operação da fun,c~ao fat recursiva é um pouco mais complexa. Quando a fun,c~ao fat 'e chamada
com um argumento 1, a função retorna 1 (esse é o caso trivial da defini,c~ao recursiva do fatorial), caso
contrário, ela retorna o produto de fat(n-1)*n.
Para avaliar essa expressão, fat é chamada com n-1. Isso acontece at'e que n seja igual a 1, quando as
chamadas `a função come,cam a retornar. O exemplo abaixo ilustra a configura,c~ao da pilha na memória
durante cada passo da sequ^encia de execução da fun,c~ao fat(4).
)
resp/n
)
resp/n
resp/n
A operação da função fat recursiva é um pouco mais complexa. Quando a função \emph{fat} é chamada
com um argumento 1, a função retorna 1 (esse é o caso trivial da definição recursiva do fatorial), caso
contrário, ela retorna o produto de \emph{fat(n-1)*n}.
)
Para avaliar essa expressão, fat é chamada com n-1. Isso acontece até que n seja igual a 1, quando as
chamadas à função começam a retornar. O exemplo abaixo ilustra a configuração da pilha na memória
durante cada passo da sequ^encia de execução da função \emph{fat(4)}.
resp/n
resp/n
resp/n
% FIXME: Inserir a imagem
)
resp/n
resp/n
)
resp/n
)
Figura E.1: Estágios da pilha na chamada recursiva de fat(4)
Quando uma função chama a si própria, as novas variáveis locais e os par^ametros s~ao alocados na
pilha (que é uma região da memória) e o c'odigo da funç~ao 'e executado com esses novos valores a partir do
início. Uma chamada recursiva não faz uma nova cópia da funç~ao. Somente os argumentos e as variáveis
Quando uma função chama a si própria, as novas variáveis locais e os parâmetros são alocados na
pilha (que é uma região da memória) e o código da função é executado com esses novos valores a partir do
início. Uma chamada recursiva não faz uma nova cópia da função. Somente os argumentos e as variáveis
são novas.
Quando cada chamada recursiva retorna, as antigas variáveis locais e os par^ametros são removidos da
pilha e a execução recome,ca no ponto de chamada da fun,c~ao dentro da fun,c~ao.
Quando cada chamada recursiva retorna, as antigas variáveis locais e os parâmetros são removidos da
pilha e a execução recomeça no ponto de chamada da função dentro da função.
A principal vantagem das funções recursivas é que elas podem ser usadas para criar vers~oes mais claras
A principal vantagem das funções recursivas é que elas podem ser usadas para criar versões mais claras
ê mais simples de muitos algoritmos complexos do que os seus equivalentes iterativos.
Por exemplo, o algoritmo de ordenação rápida é bastante difícil de ser implementado pelo modo
iterativo. Também, alguns problemas, especialmente os relacionados com IA (intelig^encia artificial),
levam a si próprios a soluções recursivas. Finalmente, muitas defini,c~oes são naturalmente recursivas, o
que torna muito mais fácil implement'a-las utilizando recursividade.
iterativo. Também, alguns problemas, especialmente os relacionados com IA (inteligência artificial),
levam a si próprios a soluções recursivas. Finalmente, muitas definições são naturalmente recursivas, o
que torna muito mais fácil implementá-las utilizando recursividade.
Na criação de fun,cões recursivas é muito importante que seja definido um caso trivial que determina
quando a função deverá come,car a retornar valores. Se n~ao houver um caso que obrigue a fun,c~ao a parar
de chamar a si mesma, o programa certamente irá entrar estourar a pilha, j'a que a memória não é infinita.
Na criação de funções recursivas é muito importante que seja definido um caso trivial que determina
quando a função deverá começar a retornar valores. Se não houver um caso que obrigue a função a parar
de chamar a si mesma, o programa certamente irá entrar estourar a pilha, já que a memória não é infinita.
ê.1 Exercícios
\section{Exercícios}
1. Crie uma definição recursiva para as seguintes opera,cões:
1. Crie uma definição recursiva para as seguintes operações:
a) soma de dois números a e b;
b) multiplicação de dois números a e b ;
c) cálculo do n-ésimo número de uma PA de razão r;
d) cálculo do n-ésimo número de uma PG de razão q;
2. Implemente a função soma pa (int x, int r, int n) que retorna a soma dos n termos de uma PA de
2. Implemente a função soma_pa (int x, int r, int n) que retorna a soma dos n termos de uma PA de
termo inicial x e razão r.
3. Desenhe um diagrama da memória para a seguinte chamada de soma pa:
soma pa(1,3,4);
\end{document}
3. Desenhe um diagrama da memória para a seguinte chamada de soma_pa:
\begin{verbatim}
soma pa(1,3,4):
\end{verbatim}
\end{document}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment