A maior rede de estudos do Brasil

Grátis
169 pág.
Apostila - Programa--o C++

Pré-visualização | Página 30 de 50

de funções. Isto significa que, 
caso a chamada da função omita algum parâmetro, a função pode usar o default previamente 
definido. A forma de definir valores default é explicitá-los na declaração da função, omitindo ou 
não o nome das variáveis. Uma vez definidos na declaração, os valores default não devem ser 
repetidos na definição, pois o compilador reconhece nisto uma duplicidade de default. O exemplo a 
seguir apresenta a declaração do default de uma função e chamadas por ele viabilizadas: 
unsigned int pares(int, int = 0); // protótipo 
int n1 = pares(20,3); 
int n2 = pares(20); 
 
Se o primeiro argumento foi omitido, todos os subsequentes deverão ser omitidos. Se o 
segundo argumento for omitido, todos os subsequentes deverão ser omitidos e assim por diante. 
Podemos escrever funções que tenham parâmetros inicializados com um valor default e parâmetros 
não-inicializados, mas após a primeira inicialização todos os parâmetros seguintes devem ser 
inicializados. Exemplo: 
void linha( int n = 20, char ch, int cor); // Declaração inválida 
void linha(int n, char ch = ‘*’, int cor = 0); // Declaração válida. 
Curso de Linguagem Computacional C/C++ 
________________________________________________________________________________________________ 
Sistemas Industriais Inteligentes – DAS – CTC – UFSC 96 
13.5.2 Sobrecarga de Funções 
Sobrecarregar funções significa criar uma família de funções com o mesmo nome, mas com 
a lista de parâmetros diferentes. Funções sobrecarregadas devem ter a lista de parâmetros diferentes 
ou em número ou em tipo. Quando a função é chamada, é a lista de parâmetros passada para ela que 
permite ao sistema identificar qual é o código adequado. Por exemplo, podemos definir a família de 
funções abaixo, lembrando que devemos definir cada função como se fosse única: 
int cubo(int n); 
float cubo(float n); 
double cubo(double n); 
13.5.3 Funções Inline 
A palavra-chave inline, quando colocada como primeiro elemento do cabeçalho da definição 
de uma função, causa a inserção de uma nova cópia da função em todo lugar onde ela é chamada. 
inline int cubo(int n); 
 
A definição de uma função inline deve preceder a primeira chamada a ela. Ou seja, se a 
função for chamada em main(), seu código deve ser escrito antes de main(). Isto é necessário, 
pois o compilador deve conhecer de antemão o código da função para poder inseri-la dentro do 
programa. 
Uma função é um código presente uma única vez no programa que pode ser executado 
muitas vezes. Assim, um dos motivos para escrever funções é o de poupar memória. Quando uma 
função é pequena e queremos aumentar a velocidade de execução de um programa, tranformamo-la 
em inline. 
13.5.4 Operador Unário de Referência: & 
O operador de referência cria outro nome para uma variável já criada. As instruções: 
int n; 
int & n1 = n; // toda referência deve ser inicializada 
 
informam que n1 é outro nome para n. Toda operação em qualquer dos nomes tem o mesmo 
resultado. Uma referência não é uma cópia da variável a quem se refere. É a mesma variável sob 
nomes diferentes. 
O uso mais importante para referências é ao passar argumentos para funções. Os exemplos 
de argumentos de funções vistos até o momento são passados por valor ou por ponteiros. 
Quando argumentos são passados por valor, a função chamada cria novas variáveis do 
mesmo tipo dos argumentos e copia nelas o valor dos argumentos passados. Desta forma, a função 
não tem acesso às variáveis originais da função que chamou, portanto não as pode modificar. 
A principal vantagem da passagem por referência é a de que a função pode acessar as 
variáveis da função que chamou. Além desse benefício, este mecanismo possibilita que uma função 
retorne mais de um valor para a função que chama. Os valores a serem retornados são colocados em 
referências de variáveis da função chamadora. 
A passagem por referência possui as vantagens da passagem de parâmetros por ponteiros, 
i.e., acesso direto à variável fornecida como parâmetro. No entanto, ponteiros exigem que tenhamos 
cuidado ao manipular o endereço das variáveis para não causar um erro fatal de acesso a memória. 
Este tipo de preocupação já não existe com passagem por referência, pois não lidamos com o 
endereço da variável mas sim com uma cópia do seu nome. 
Funções que recebem argumentos por referência utilizam o operador & somente na 
definição do tipo do argumento e possuem chamadas idênticas a uma função normal. Exemplo: 
Curso de Linguagem Computacional C/C++ 
________________________________________________________________________________________________ 
Sistemas Industriais Inteligentes – DAS – CTC – UFSC 97 
void reajusta( float& num, float& p = 15 ); // Protótipo 
 
int main(int argc, char* argv[]) 
{ 
 float preco = 10; 
 reajusta( preco, 5); // Chamada a função 
 reajusta( preco); // Chamada usando o argumento default 
 return 0; 
} 
 
void reajusta( float& num, float& p ) //Definição 
{ 
 num *= p; 
} 
13.6 Alocação Dinâmica de Memória em C++ 
A alocação dinâmica de memória em C++ é feita com os operadores new (alocação) e 
delete (liberação), análogos às funções malloc() e free(). Em C++, o gerenciamento 
dinâmico de memória é tão relevante que as palavras new e delete foram incorporadas a 
linguagem. A diferença básica entre os operadores C++ e C está na confiabilidade e facilidade de 
uso. Por exemplo, o tamanho do tipo para o qual se pede memória deve ser informado à 
malloc(), enquanto que new descobre esse tamanho automaticamente. 
Declaração C: Declaração C++ 
double *ptr; double *ptr; 
prt = (double*)malloc(sizeof(double)); ptr = new double; 
 
C++ já fornece um ponteiro para o tipo de dado fornecido, não necessitando das conversões 
de tipo requeridas por malloc(). Outra vantagem é que C++ define quanto de memória é 
necessário, diminuindo o risco que o programador faça algum tipo de erro. Uma vantagem 
importante é que os operadores new e delete podem ser sobrecarregados (reimplementados) para 
um tipo de dado criado pelo programador. Isto permite que o programador controle como será 
alocada memória para o seu tipo de dado. 
Sempre que uma memória alocada para uma variável não for mais necessária, devemos 
liberá-la utilizando o operador delete. As formas de utilizar o operador new (alocação de 
memória) e delete (liberação de memória) são: 
a) como operador ou função 
 ptr_tipo = new tipo; ptr_tipo = new(tipo); 
 int * ptr1 = new int; int * ptr2 = new(int); 
 delete ptr1; delete ptr2; 
 
b) alocação e liberação de matrizes 
ptr_tipo = new tipo[tamanho_matriz]; 
int * ptr3 = new int[10]; 
delete[] ptr3; // ou, explicitamente: delete[10] ptr3; 
 
c) alocação e liberação de matrizes de ponteiros 
ptr_ptr_tipo = new tipo * [tamanho_matriz]; 
int * * ptr4 = new int * [10]; 
delete[] ptr4; // ou, explicitamente: delete[10] ptr4; 
 
Curso de Linguagem Computacional C/C++ 
________________________________________________________________________________________________ 
Sistemas Industriais Inteligentes – DAS – CTC – UFSC 98 
Analogamente ao que ocorre a função malloc() do C, o operador new retorna um 
ponteiro nulo quando a memória disponível é insuficiente. Assim, devemos sempre verificar se a 
alocação foi realizada com sucesso, ou seja, se o ponteiro contém um endereço diferente de zero. 
13.7 Exercícios 
 
13.1 Escreva um programa que desenhe na tela o gráfico da função y = cos(x) + x/2. Utilize 
cout e cin para isto. Desenhe todos os elementos do gráfico: título, legenda, linhas horizontal e 
vertical e numeração. Marque os pontos pertencentes ao gráfico com o caracter (*). 
 
13.2 Crie um programa para fazer cadastro de doentes em um hospital. Utilize estruturas e 
funções, com passagem de parâmetros por referência. O programa deve apenas adquirir os dados e 
quando o usuário terminar o cadastro, o programa deve imprimir na tela todas as fichas feitas. 
 
13.3 Modifique o programa acima para utilizar agora a alocação dinâmica em C++ e