Programação 2007/2008 DEEC-IST 1
Sumário
Argumentos da linha de comando
Exemplos
Recursividade de funções
Exemplos
Argumentos da linha de comando
Motivação:
Nas aulas de laboratório foi utilizado o compilador de C, gcc, para
efectuar a compilação e linkagem. A execução do programa gcc é
realizada através da linha de comando, especificando o nome (gcc) e
mais um conjunto de opções:
gcc -g -Wall -pedantic -ansi factorial.c -o factorial
Sendo o gcc um programa executável, cujo programa fonte está escrito
na linguagem C, como é que é possível ter acesso às opções que vêm
a seguir ao nome do programa gcc?
A resposta a esta pergunta passa pela utilização da lista de
argumentos da função main. Em vez de void, é possível especificar um
conjunto de argumentos.
Programação 2007/2008 DEEC-IST 3
Argumentos da linha de comando
Utilização:
Em C o acesso às opções da linha de comando é realizado através de
dois argumentos, na lista de argumentos da função main:
int
main (
int
argc,
char
*argv[]) {
/* … */
return
0
;
}
argc
- Indica o número de palavras que foram escritas na linha de
comando incluindo o nome do programa executável. Cada palavra
deve estar separada por um ou mais espaços em branco.
argv[]
- É um vector de apontadores para caracteres, tendo a
dimensão de argc elementos.
O primeiro apontador (argv[0]) permite aceder ao nome do programa
executável, o apontador (argv[k]) permitem aceder à palavra k+1 da linha
de comando.
Nota: argc e argv, são variáveis locais da função main. O seu nome pode
ser alterado mas não o seu tipo, por tradição utiliza-se argc-argument
count, argv- argument value.
Argumentos da linha de comando
Exemplo: Programa que mostra as palavras da linha de
comando.
/* Linha de comando */
#include <stdio.h>
intmain(intargc,char*argv[]) {
inti;
printf("Echo da linha de comando \n");
for(i=0; i<argc; ++i) {
printf("Arg n.%d = %s\n", i, argv[i]); }
printf("\nFIM.\n");
return0; }
Resultado:
lincom.exe Primeiro 2. Terceiro
Echo da linha de comando
Arg n.0 = lincom.exe
Arg n.1 = Primeiro
Arg n.2 = 2.
Arg n.3 = Terceiro
FIM.
Programação 2007/2008 DEEC-IST 5
Argumentos da linha de comando
Exemplo: Máquina de calcular elementar:
O programa deve ter o nome de calcula, deve receber no máximo três argumentos que especificam os dados e a operação como se mostra:
calcula 3 + 5
#include <stdio.h>
intmain(intargc,char*argv[]) {
floatoperando1, operando2, resultado;
if(argc !=4) {
printf("Programa que simula uma calculadora elementar\n"); printf("Numero de argumentos errado\n");
printf("Exemplo: \n");
printf("cal 4 + 5 <Enter>\n");
return0; }
if(sscanf(argv[1],"%f", &operando1) !=1) { printf("Erro de conversao no 1. argumento\n");
return0; }
if(sscanf(argv[3],"%f", &operando2) !=1) { printf("Erro de conversao no 2. argumento\n");
return0; }
Argumentos da linha de comando
Exemplo: Máquina de calcular elementar (cont.)
switch( *(argv[2])) {
case'+':
resultado = operando1 + operando2;
break;
case'-':
resultado = operando1 - operando2;
break;
case'*':
resultado = operando1 * operando2;
break;
case'/':
/* Cuidado com a divisao por zero */ resultado = operando1 / operando2;
break;
default:
printf("Operador deconhecido\n");
return0; }
printf("%s %s %s = %f\n", argv[1], argv[2], argv[3], resultado);
Programação 2007/2008 DEEC-IST 7
Argumentos da linha de comando
Exemplo: Máquina de calcular elementar. Resultados
>calcula
Programa que simula uma calculadora elementar Exemplo: calcula 4 + 5 <Enter> >calcula 2 + 3 2 + 3 = 5.000000 >calcula 2 - 3 2 - 3 = -1.000000 >calcula 2 * 3 2 * 3 = 6.000000 >calcula 2 / 3 2 / 3 = 0.666667 >calcula (:-) + 3
Erro de conversao no 1. argumento >calcula 2 % 3
Operador desconhecido >calcula 2 + :-)
Erro de conversao no 2. argumento
Argumentos da linha de comando
Problema:
Desenvolva um programa cuja acção seja equivalente
ao comando cp do Linux ou copy do MSDOS.
O programa deve:
Apresentar uma ajuda no caso de o número de
argumentos na linha de comando seja inadequado.
Deve verificar a existência dos ficheiros.
Se existe o ficheiro fonte.
Se não existe o ficheiro destino.
Deve copiar o conteúdo do ficheiro fonte para o
ficheiro destino.
Exemplo:
Programação 2007/2008 DEEC-IST 9
Recursividade
As funções recursivas têm a sua origem na Matemática
O exemplo mais conhecido consiste na definição da função
factorial, f(n) = n!
De salientar que tem que existir:
Uma condição inicial, valor de n
Uma condição de finalização, quando n = 0, caso contrário não
será possível calcular o valor da função
=
>
−
=
0
1
1
)
1
(
*
)
(
n
se
n
se
n
f
n
n
f
Recursividade
No caso da função factorial, esta recebe um número inteiro e devolve
um número inteiro.
#include <stdio.h>
intfactorial(intn) {
intvalor; if(n >0) valor = n * factorial(n-1); else valor =1; returnvalor; }
intmain(void) {
intx;
printf("Funcao factorial.\n\n x="); scanf("%d", &x);
printf("factorial(%d) = %d\n", x, factorial(x));
Resultado:
Funcao factorial. x=6
factorial(6) = 720 FIM.
Programação 2007/2008 DEEC-IST 11
Recursividade
Para compreender melhor o funcionamento das funções recursivas,
são introduzidas algumas alterações no código da função factorial de
modo a mostrar no ecrã a evolução das chamadas da função.
intfactorial(intn) {
intvalor;
if(n >0) {
printf(”n = %d, Chamada a factorial(%d)\n", n, n-1); valor = n * factorial(n-1);
}
else{
printf("Condicao de finalizacao, n = %d\n", n); valor =1;
}
printf(" Saida de factorial(%d) com valor = %d\n", n, valor);
returnvalor; }
Recursividade
O resultado da execução do programa
Funcao factorial.
x=6
n = 6, Chamada a factorial(5)
n = 5, Chamada a factorial(4)
n = 4, Chamada a factorial(3)
n = 3, Chamada a factorial(2)
n = 2, Chamada a factorial(1)
n = 1, Chamada a factorial(0)
Condicao de finalizacao, n = 0
Saida de factorial(0) com valor = 1
Saida de factorial(1) com valor = 1
Saida de factorial(2) com valor = 2
Saida de factorial(3) com valor = 6
Saida de factorial(4) com valor = 24
Saida de factorial(5) com valor = 120
Saida de factorial(6) com valor = 720
factorial(6) = 720
Programação 2007/2008 DEEC-IST 13
Recursividade
Interpretação dos resultados:
Sempre que a função se chama a si própria para execução, há a
criação de um novo conjunto de variáveis locais, distinto. As variáveis
são criadas no stack e como consequência o stack vai crescendo.
O processo de criação de variáveis locais termina quando se alcança a
condição de finalização, (ou há falta de memória :-( ( ) .
Após a execução da condição de finalização é executado o primeiro
return, correspondente à última invocação da função recursiva.
Por cada return que é executado, as variáveis locais vão sendo
libertadas e o stack vai diminuindo.
Recursividade
Interpretação dos resultados:
x=6 n=6 <- factorial (6) valor = 6 * ? n=5 <- factorial (5) valor = 5 * ? n=4 <- factorial (4) valor = 4 * ? n=3 <- factorial (3) valor = 3 * ? n=2 <- factorial (2) valor = 2 * ? n=1 <- factorial (1) valor = 1 * ? n=0 <- factorial (0) valor = 1 n=1 <- factorial (1) valor = 1 * 1 n=2 <- factorial (2) valor = 2 * 1 n=3 <- factorial (3) n=4 <- factorial (4) valor = 4 * 6 n=5 <- factorial (5) valor = 5 * 24 n=6 <- factorial (6) valor = 6 * 120 factorial(6) = 720
Stack
aumenta
Stack
diminui
Programação 2007/2008 DEEC-IST 15