Академический Документы
Профессиональный Документы
Культура Документы
ALGORITMOS E PROGRAMAO II
PROFESSOR: OSMAR J. SILVA
APOSTILA I
Programao modular em C
Por programao modular, entende-se a tcnica de se dividir o cdigo de um
determinado programa em partes, de forma a reutilizar suas funes e procedimentos.
A linguagem C permite a modularizao por meio de funes. importante perceber
que, dependendo da linguagem de programao, funo so chamadas tambm de
procedimentos ou mtodos. Em C optou-se por preservar o nome funo, tanto para
funes que retornam valores quanto para aquelas que no o fazem.
Veja a seguir uma funo que recebe um arquivo do tipo texto e o escreve na tela:
void escrever(char *texto){
printf(texto);
}
Uma chamada a esta funo pode ser feita da seguinte forma:
escrever("Gosto muito de C");
Observe o uso da palavra-chave void para indicar que a funo no retorna nenhum
valor. Veja o cdigo completo para fins de estudo:
#include <stdio.h>
#include <stdlib.h>
void escrever(char *texto){
printf(texto);
}
int main(int argc, char *argv[])
{
escrever("Gosto muito de C");
printf("\n\n");
system("PAUSE");
return 0;
}
Vejamos agora uma funo que retorna um valor:
2) Escreva uma funo que recebe duas strings como argumento e retorne a
concatenao destas:
Dica: use a funo strcat() para concatenar as duas strings.
3) Escreva uma funo que receba dois inteiros e retorne o resultado do primeiro
elevado potencia do segundo.
Obs: Use laos. No permitido usar a funo pow() do header math.h.
4) Escreva uma funo que retorne a quantidade de ocorrncias de um determinado
caractere em uma string.
Dica: Use o operador de ndice [] para acessar o caractere individual de uma string.
Embora C++ j possua o tipo bool, possvel usar a abordagem do zero para false e
qualquer outro valor para true em C++ tambm. Voc ver muito cdigo legado usando
este artifcio. Quer ver algo interessante agora? Execute o seguinte cdigo C++:
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
bool pode = true;
bool nao_pode = false;
cout << pode << "\n";
cout << nao_pode << "\n\n";
system("PAUSE"); // pausa o programa
return EXIT_SUCCESS;
}
Nos compiladores que obedecem o C++ padro voc ver os valores 1 e 0 serem
impressos.
Exerccios:
1) Escreva uma funo que retorna true se o valor fornecido como argumento for par e
false em caso contrrio.
Dica: use o nome is_par() para a sua funo.
2) Use uma varivel do tipo boolean como sentinela em uma lao while. Este lao
dever contar de 0 20. Porm, quando o valor for maior que 15, a varivel de sentinela
dever forar a interrupo do lao.
Ponteiros
Antes de pensarmos em ponteiros, importante nos lembrarmos de alguns aspectos
referentes variveis. Dependendo do seu conhecimento de programao, voc deve
saber que variveis possuem nomes que as identificam durante a execuo do programa.
Voc deve saber tambm que uma varivel armazena um valor (que pode ser fixo, no
caso de uma constante, ou pode mudar durante a execuo de seus cdigos).
O que poucos programadores se lembram que uma varivel possui um endereo, e que
o nome da varivel no nada mais que um apelido para a localizao deste endereo.
Desta forma, um ponteiro no nada mais que um tipo especial de varivel que
armazena o endereo de outra. Veja um exemplo:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
// varivel do tipo int
int valor = 10;
// ponteiro para uma varivel do tipo int
int *p = &valor;
// exibe o valor da varivel "valor", apontada
// pelo ponteiro p
printf("%d", *p);
printf("\n\n");
system("PAUSE");
return 0;
}
Neste cdigo ns temos a declarao e definio de duas variveis:
int valor = 10;
int *p = &valor;
A primeira varivel uma varivel do tipo int e a segunda um ponteiro para uma
varivel do tipo int. Veja que devemos sempre usar "*" antes do nome de um ponteiro
em sua declarao. O smbolo "&" serve para indicar que estamos acessando o endereo
de uma varivel e no o seu contedo. O resultado destas duas linhas que agora temos
um ponteiro que nos permite acessar e manipular a varivel valor.
Observe a linha:
printf("%d", *p);
Aqui ns estamos acessando o valor da varivel apontada por p. Veja o uso do smbolo
"*" para acessar o valor da varivel. Isso chamado de desreferenciamento de
ponteiros. Pareceu complicado? Veja uma linha de cdigo que altera indiretamente o
valor da varivel valor para 30:
*p = 30;
Ponteiros so ferramentas muito importantes na programao em C. No entanto,
preciso ter muito cuidado ao lidar com eles. A primeira coisa a ter em mente que um
ponteiro no est apontando para nenhum lugar at que atribuimos a ele o endereo de
uma outra varivel. E a que mora o perigo. Um programa entra em colapso absoluto
se tentarmos acessar um ponteiro que aponta para um local de memria que j foi
liberado novamente ao sistema. No caso menos grave, estaremos tentando acessar locais
de memria invlidos ou reservados a outros programas ou tarefas do sistema
operacional. Isso nos lembra os velhos tempos da tela azul de morte.
printf("%d", valor);
printf("\n\n");
system("PAUSE");
return 0;
}
Agora o valor a ser impresso ser 10. Observe que, ao efetuar a chamada funo
alterar, ns estamos usando o operador & para indicar a posio da varivel valor na
memria. Isso permite que seu valor seja alterado como pretendamos.
}
// exibe os valores
for(i = 0; i < quant; i++){
printf("%d ", ponteiro[i]);
}
// libera a memria
free(ponteiro);
printf("\n\n");
system("PAUSE");
return 0;
}
int *ponteiro;
// aloca memria para um int
ponteiro = calloc(1, sizeof(int));
// testa se a memria foi alocada com sucesso
if(ponteiro)
printf("Memoria alocada com sucesso.\n");
else
printf("Nao foi possivel alocar a memoria.\n");
// atribui valor memria alocada
*ponteiro = 45;
// obtm o valor atribudo
printf("Valor: %d\n\n", *ponteiro);
// libera a memria
free(ponteiro);
system("PAUSE");
return 0;
}
Uma aplicao interessante da funo calloc() quando precisamos construir uma
matriz dinmica. Veja como isso feito no cdigo abaixo:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i;
// quantidade de elementos na matriz
int quant = 10;
// ponteiro para o bloco de memria
int *ponteiro;
// aloca memria para uma matriz de inteiros
ponteiro = calloc(quant, sizeof(int));
// testa se a memria foi alocada com sucesso
if(ponteiro)
printf("Memoria alocada com sucesso.\n");
else{
printf("Nao foi possivel alocar a memoria.\n");
exit(1);
}
// atribui valores aos elementos do array
for(i = 0; i < quant; i++){
ponteiro[i] = i * 2;
}
// exibe os valores
for(i = 0; i < quant; i++){
printf("%d ", ponteiro[i]);
}
// libera a memria
free(ponteiro);
printf("\n\n");
system("PAUSE");
return 0;
}
Estruturas (struct) em C
Matrizes (arrays) so muito importantes quando precisamos agrupar vrias variveis de
um mesmo tipo de dados. Porm, h casos em que precisamos agrupar variveis de
diferentes tipos. Para estes casos a linguagem C nos fornece as estruturas (struct). Veja
como declar-las:
// uma estrutura Pessoa
struct Pessoa
{
char *nome;
int idade;
};
Veja que esta estrutura possui dois tipos de dados diferentes: um ponteiro para uma
cadeia de caracteres e uma varivel do tipo int.
Para declarar variveis do tipo Pessoa voc tem duas opes. A primeira consiste em
declarar as variveis juntamente com a declarao da estrutura. Veja:
// uma estrutura Pessoa
struct Pessoa
{
char *nome;
int idade;
}pessoa, cliente, chefe;
A outra forma consiste em declarar a varivel no local no qual ela ser usada. Esta
forma mais prtica. Veja um exemplo completo de como isso feito:
#include <stdio.h>
#include <stdlib.h>
// uma estrutura Pessoa
struct Pessoa
{
char *nome;
int idade;
};
int main(int argc, char *argv[])
{
// declara uma varivel do tipo struct
struct Pessoa cliente;
cliente.nome = "Osmar J. Silva";
cliente.idade = 36;
// obtm os dados
printf("O nome do cliente e: %s\n", cliente.nome);
printf("A idade do cliente e: %d\n", cliente.idade);
printf("\n\n");
system("PAUSE");
return 0;
}