Funções |
Procedimentos |
|
|
tipo_devolução
nome(lista_de_parâmetros);
Exemplo:
|
void nome(lista_de_parâmetros);
Exemplo:
|
|
|
tipo_devolução
nome(lista_de_parâmetros)
{
... // instruções.
return expressão;
}
Exemplo:
|
void nome(lista_de_parâmetros)
{
... // instruções.
}
Exemplo:
|
|
|
variável
= nome(lista_de_argumentos);
Exemplo:
|
nome(lista_de_argumentos);
Exemplo:
|
Parâmetros são as variáveis locais à rotina declaradas entre ()
no seu cabeçalho.
Argumentos são as expressões colocadas entre ()
na invocação de uma rotina e servem para inicializar
os parâmetros.
As rotinas são um mecanismo importante na programação. Permitem (entre outras coisas):
As rotinas possuem um contrato: comprometem-se a produzir um determinado resultado se os seus parâmetros verificarem uma dada condição. Para exprimir o resultado pretendido usa-se a chamada condição objectivo. Para exprimir o que se assume à partida acerca dos parâmetros usa-se a chamada pré-condição. Ao conjunto de ambas chama-se o contrato da rotina, uma vez que estabelecem um contrato entre o produtor e o consumidor da rotina. Todas as rotinas devem possuir um comentário de documentação com o seguinte aspecto (onde @pre significa "pré-condição" e @post significa "pós-condição" ou "condição objectivo"):
/**
Esta função devolve o máximo divisor comum dos inteiros
positivos passados como argumento.
@pre 0 <
m
e 0 <n
.@post
mdc
= mdc(m
,n
), ou seja,
o valor
x
devolvido é o máximo divisor comum dem
en
.*/
int mdc(int const m, int const n)
{
int x;
if(m < n)
x = m;
else
x = n;
while(m % x != 0 or n % x != 0)
--x;
return x;
}
Por outro lado, deve-se sempre que possível explicitar o contrato das rotinas no próprio código C++ através da utilização de instruções de asserção:
//
Esta linha tem de estar no topo do ficheiro:
#include <cassert>
...
using namespace std;
...
/**
Esta função devolve o máximo divisor comum dos inteiros
positivos passados como argumento.
@pre 0 <
m
e 0 <n
.@post
mdc
= mdc(m
,n
), ou seja,
o valor
x
devolvido é o máximo divisor comum dem
en
.*/
int mdc(int const m, int const n)
{
assert(0 < m and 0 < n);
int mdc;
if(m < n)
mdc = m;
else
mdc = n;
while(m % mdc != 0 or n % mdc != 0)
--mdc;
//
Neste caso é difícil fazer melhor para verificar a condição objectivo:
assert(0 < mdc and m % mdc == 0 and n % mdc == 0);
return mdc;
}
do
while
do
while
:while
:
ou
do
instrução
while(expressão_booleana);
Importante: O ciclo
do {
instruções
} while(expressão_booleana);
do while
executa pelo menos uma vez a instrução controlada, pois a
condição só é verificada depois de executada
a instrução controlada.
Importante: É sempre possível converter um ciclo de modo a usar qualquer das instruções de iteração. No entanto, a maior parte dos problemas resolvem-se de um modo mais óbvio e mais legível com uma destas instruções do que com as outras.
Exemplo de um ciclo para mostrar no ecrã os inteiros de 0 a 9 (inclusive) construído usando cada uma das três instruções.
while
:
int i = 0;
while(i != 10) {
cout << i << endl;
++i;
}
//
Neste pontoi
é visível.
for
:
ou
for(int i = 0; i != 10; ++i)
cout << i << ' ';
//
Neste pontoi
não está definida.
int i = 0;
for(; i != 10; ++i)
cout << i << ' ';
//
Neste pontoi
é visível.
do
while
(má ideia!):
int i = 0;
do {
cout << i << ' ';
++i;
} while(i != 11);
A instrução do
while
raramente é útil.