Buscar

Apostila de PCII

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 80 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 80 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 80 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Programação de Computadores II Prof. Erlon Pinheiro
2
Programação de Computadores II Prof. Erlon Pinheiro
Sumário
Unidade 1: MODULARIZAÇÃO ..................................................................................... 5 
1.1 - Introdução .............................................................................................................. 5 
1.2 - MODULARIZAÇÃO EM C ................................................................................. 6 
1.2.1 - Introdução às Funções .................................................................................... 6 
1.2.2 – Argumentos e Passagem de parâmetros ........................................................ 8 
1.2.3 - Retornando valores ......................................................................................... 9 
1.2.4 – Passagem de parâmetros por valor ............................................................. 11 
1.2.5 – PONTEIROS ............................................................................................... 12 
1.2.5.2 - Declarando e Utilizando Ponteiros ............................................................ 12 
1.2.6 - Passagem de parâmetros por valor e passagem por referência .................... 15 
1.2.7 - Variáveis globais .......................................................................................... 19 
1.2.8 - Ponteiros e Vetores ....................................................................................... 19 
Exercícios Complementares 1 .................................................................................... 23 
Unidade 2: Strings ........................................................................................................... 29 
2.1 - Introdução ............................................................................................................ 29 
2.2 – Leitura de Strings ................................................................................................ 30 
2.3 – Criando funções que manipulam strings ............................................................ 32 
2.4 – Funções pré-definidas para manipulação de strings ........................................... 34 
a) gets ....................................................................................................................... 34 
c) strcpy ................................................................................................................... 35 
d) strcat .................................................................................................................... 35 
e) strlen .................................................................................................................... 36 
f) strcmp ................................................................................................................... 36 
g) toupper ................................................................................................................. 37 
Exercícios Complementares 2 ..................................................................................... 37 
Unidade 3: Matrizes ......................................................................................................... 40 
3.1 – Introdução: Definições Iniciais ........................................................................... 40 
3.2 - Matrizes de strings .............................................................................................. 40 
3.3 - Matrizes multidimensionais ................................................................................ 41 
3.4 - Inicialização ........................................................................................................ 41 
3.4.1 - Inicialização sem especificação de tamanho ................................................ 42 
3.5 – Passagem de Matrizes para Funções .................................................................. 43 
3.6 – Tipos Básicos de Matrizes .................................................................................. 43 
Exercícios Complementares 3 ..................................................................................... 45 
Unidade 4: Pesquisa e Ordenação de Vetores ................................................................. 49 
4.1 - Ordenação em vetores ......................................................................................... 49 
4.2 - Pesquisa em vetores ............................................................................................ 52 
4.2.1 - Método Pesquisa Sequencial........................................................................ 52 
4.2.2 - Pesquisa Binária .......................................................................................... 54 
Exercícios de Complementares 4 ................................................................................ 57 
Unidade 5: Estruturas ...................................................................................................... 58 
5.1 – Introdução ao Uso de Structs .............................................................................. 58 
5.2 – Definição de Tipos ............................................................................................. 58 
5.3 – Declarando variáveis do tipo estrutura ............................................................... 58 
5.4 - Vetores de estruturas ........................................................................................... 61 
5.5 - Atribuição entre estruturas do mesmo tipo ......................................................... 62 
5.6 - Passando uma estrutura para funções .................................................................. 63 
5.7 – Ponteiros e Estruturas ......................................................................................... 64 
Exercícios Complementares 5 ..................................................................................... 66 
3
Programação de Computadores II Prof. Erlon Pinheiro
(Dica: Estudar a seção 5.5 - Atribuição entre estruturas do mesmo tipo) ................... 69 
Unidade 6: Arquivos ........................................................................................................ 71 
6.1 – Introdução: Definições e uso de Arquivos ......................................................... 71 
6.2 - Abrindo e Fechando um Arquivo .................................................................... 71 
- fopen ...................................................................................................................... 71 
- fclose ..................................................................................................................... 72 
6.3 – Finalizando a execução de um programa .......................................................... 72 
Comando exit ........................................................................................................... 72 
6.4 - Lendo e Escrevendo Caracteres em Arquivos ..................................................... 73 
Função putc .............................................................................................................. 73 
Função getc .............................................................................................................. 74 
6.5 - Outros Comandos de Acesso a Arquivos ............................................................ 76 
Função fgets ............................................................................................................ 76 
Função fputs ............................................................................................................ 76 
Fluxos Padrão .......................................................................................................... 76 
Função fprintf ......................................................................................................... 77 
Função fscanf ........................................................................................................... 77 
Exercícios Complementares 6 ..................................................................................... 78 
Referências Bibliográficas ............................................................................................... 80 
4
Programação de Computadores II Prof. Erlon Pinheiro
Unidade 1: MODULARIZAÇÃO
1.1 - Introdução
Estudos da psicologia mostram que o ser humano normal é capaz de resolver problemas que 
envolvam 7 (com incerteza de 2) variáveis simultaneamente. Um problema é complexo se 
envolve mais do que 9 ou 10 variáveis. Como, então, podemos resolver problemas desse tipo?
A solução que encontramos para solucionar esses problemas é dividir um problema complexo 
em vários subproblemas elementares, onde não estejamos sujeitos a esta limitação humana. 
Esta estratégia de solução de problemas é comumente conhecida como a técnica de Dividir para 
Conquistar, a qual é o fundamento básico para a Modularização. 
Neste sentido a modularização de programas consiste da divisão do programa em módulos ou 
subprogramas, que nada mais são do que um conjunto de comandos agrupados com a finalidade 
de executar uma determinada função.
Além disso, a modularização é uma técnica de programação que permite a aplicação direta dos 
refinamentos sucessivos, isto é, possibilita que haja um mapeamento entre os diversos tipos de 
algoritmos criados quando utilizamos refinamentos e o próprio ato de programar.
Outro problema que nos defrontamos quando estamos programando é a repetição de código. 
Você já deve ter notado que certos trechos de seus programas se repetem em vários momentos, 
igualmente como foram escritos num primeiro instante ou de uma maneira muito aproximada. 
Esta repetição decódigo, além de ser algo desagradável para o programador, torna o programa 
redundante e dificulta, em última instância, a sua legibilidade. 
A modularização é uma solução natural para este problema, pois um módulo pode ser ativado 
em pontos diferentes de um mesmo programa.
Para falarmos um pouco mais sobre as vantagens da modularização necessitamos definir alguns 
conceitos sobre qualidade de programas. Um programa é de boa qualidade quando apresenta as 
seguintes características: 
• Confiabilidade: o programa está correto e é confiável. 
• Legibilidade: o programa é fácil de ser lido por um programador de nível médio. 
• Manutenibilidade: o programa é fácil de ser modificado. Quando o usuário requer 
modificações no programa, fruto de novas necessidades, a atualização do programa deve 
ser natural. 
• Flexibilidade: o programa é fácil de ser reutilizado; não possui muitas restrições. 
Nesse contexto, podemos citar agora uma série de vantagens da modularização:
 Facilita o projeto de sistemas: 
Incentiva a aplicação da técnica de refinamentos sucessivos. 
 Minimiza a manutenção de programas: 
5
Programação de Computadores II Prof. Erlon Pinheiro
Modificações no programa precisam ser realizadas apenas no módulo 
correspondente, sem ter de alterar o resto do programa. 
 Melhora a legibilidade dos programas: 
Não há necessidade de se entrar em detalhes de programação para se 
entender o que o programa faz. 
 Viabiliza a validação: 
Testes e correções de cada segmento podem ser realizados em separado, só 
reunindo os módulos quando todos estiverem devidamente validados. 
 Permite a divisão de tarefas em uma equipe: 
Cada módulo pode ser realizado por um programador diferente. 
 Facilita a reutilização de código: 
 Em trechos onde ocorre repetição de código no programa 
 Em trechos onde ocorre repetição parcial de código, onde 
só são modificados os argumentos utilizados. 
 Estimula o encapsulamento de informações:
O programador que usará o módulo só precisa saber o que o módulo faz e não 
como faz 
1.2 - MODULARIZAÇÃO EM C
Agora que já estamos familiarizados com o conceito de modularização e conhecemos as suas 
vantagens, podemos nos ater a técnica de modularização que é implementada em C. 
Em C para modularizar programas usaremos funções. 
1.2.1 - Introdução às Funções
Na linguagem C tudo gira em torno das funções. Por exemplo, a função de nome main é 
obrigatória em todos os programas em C, pois é esta função que será chamada quando o 
programa for executado. O conteúdo da função é delimitado por chaves { }. O código que estiver 
dentro das chaves será executado seqüencialmente quando a função for chamada. Exemplos de 
outras funções que já conhecemos: a função printf () e a função scanf ().
Uma função é um bloco de código de programa que pode ser usado diversas vezes em sua 
execução. O uso de funções permite que o programa fique mais legível, mais bem estruturado. 
Um programa em C consiste, no fundo, de várias funções colocadas juntas. 
 Abaixo o tipo mais simples de função:
6
Programação de Computadores II Prof. Erlon Pinheiro
#include <stdio.h>
#include <stdlib.h>
 void mensagem (void) // Função simples: só imprime Ola! 
 {
 printf ("Ola! ");
 }
 main ()
 {
 mensagem();
 printf ("Eu estou estudando C!\n");
system(“pause”);
 }
Este programa define uma função mensagem() que imprime apenas a mensagem Ola! na 
tela. O primeiro void na especificação da função mensagem() significa que a função não 
retornará valor algum e o void entre parênteses significa que a função mensagem não recebe 
valor algum para sua execução. Estudaremos mais a frente maiores detalhes sobre utilização de 
argumentos. A função mensagem() é chamada a partir de main() , que, como já vimos, também 
é uma função. A diferença fundamental entre main e as demais funções do programa é que 
main é a primeira função a ser executada pelo programa.
Obs.: A função pode ser implementada depois da função main(), mas neste caso necessitamos 
colocar no início do programa o protótipo da função, por exemplo, o código anterior ficaria 
assim:
#include <stdio.h>
#include <stdlib.h>
 void mensagem (void);
 main()
 {
 mensagem();
 printf ("Eu estou estudando C!\n");
system(“pause”);
 }
 void mensagem (void) // Função simples: só imprime Ola! 
 {
 printf ("Ola! ");
 }
Exercício de Fixação
7
Programação de Computadores II Prof. Erlon Pinheiro
1) Faça um programa que utilize uma função para mostrar na tela a soma de dois números lidos 
dentro da função.
2) Faça um programa que utilize uma função para calcular e mostrar na tela o fatorial de um 
número.
1.2.2 – Argumentos e Passagem de parâmetros
Parâmetros são as entradas que a função recebe no instante da ativação do módulo. É através 
dos parâmetros que podemos nos “comunicar” com a função. Já utilizamos funções com 
parâmetros. As funções printf() e scanf() são funções que recebem uma expressão de controle e 
uma lista de argumentos.
Obs.: Costumamos dizer que na hora da chamada passamos o argumento que será um 
parâmetro na execução da função.
 Vamos ver outro exemplo simples de função com passagem de parâmetros: 
#include <stdio.h>
#include <stdlib.h>
void quadrado(int x) /* Calcula o quadrado de x */
{
 printf ("O quadrado e %d.\n",(x*x));
}
main ()
{
 int num;
 printf ("Entre com um numero: ");
 scanf ("%d",&num);
 printf ("\n\n");
 quadrado(num);
 system("pause");
}
8
Programação de Computadores II Prof. Erlon Pinheiro
Na definição de quadrado() dizemos que a função receberá um parâmetro inteiro x. Quando 
fazemos a chamada à função, o inteiro num é passado como argumento. Há alguns pontos a 
observar. Em primeiro lugar temos de satisfazer aos requisitos da função quanto ao tipo e à 
quantidade de argumentos quando a chamamos. Apesar de existirem algumas conversões de 
tipo, que o C faz automaticamente, é importante ficar atento. Em segundo lugar, não é 
importante o nome da variável que se passa como argumento, ou seja, a variável num, ao ser 
passada como argumento para quadrado() é copiada para a variável x. Dentro de quadrado() 
trabalha-se apenas com x. Se mudarmos o valor de x dentro de quadrado() o valor de num na 
função main() permanece inalterado. 
O próximo exemplo possui uma função que recebe como parâmetros mais de uma variável. 
Repare que, neste caso, os argumentos são separados por vírgula e devemos explicitar o tipo de 
cada um dos parâmetros, um a um. Note também que os argumentos passados para a função 
não necessitam ser todos variáveis, porque mesmo sendo constantes serão copiados para a 
variável de entrada da função. 
#include <stdio.h>
#include <stdlib.h>
void mult(float a, float b, float c)// Multiplica 3 números
{
 printf ("%.1f * %.1f * %.1f = %.1f.\n\n",a,b,c,a*b*c);
}
 
main ()
{
 float x,y;
 x=23.5;
 y=12.9;
 mult (x,y,3.87);
 system("pause");
}
Exercício de Fixação
1) Faça um programa que utilize uma função para mostrar na tela a soma de dois números lidos 
fora da função.
2) Faça um programa que utilize uma função para calcular e mostrar na tela o fatorial de um 
número. O número deve ser lido na função main() e passado para a função calcular o fatorial.
1.2.3 - Retornando valores
Muitas vezes é necessário fazer com que uma função retorne um valor. As funções que vimos 
até aqui não retornavam valores (usavam o void). Podemos especificar um tipo de retorno 
indicando-o antes do nome da função (no lugar do void). Mas para dizer ao C o que vamos 
9
Programação de Computadores II Prof. Erlon Pinheiro
retornar,precisamos da palavra reservada return. Sabendo disto fica fácil fazer uma função 
para multiplicar dois inteiros e que retorna o resultado da multiplicação. Veja: 
#include <stdio.h>
#include <stdlib.h>
 int prod (int x,int y)
 { return (x*y); }
 
 main ()
 {
 int saida;
 saida=prod (12,7);
 printf ("A saida e: %d\n",saida);
system(“pause”);
 }
Veja que, como prod retorna o valor de 12 multiplicado por 7, este valor pode ser usado em 
uma expressão qualquer. No programa fizemos a atribuição deste resultado à variável saida, 
que posteriormente foi impressa usando o printf. Uma observação adicional: se não 
especificarmos o tipo de retorno de uma função, o compilador C automaticamente suporá que 
este tipo é inteiro. Porém, não é uma boa prática não se especificar o valor de retorno e, neste 
curso, este valor será sempre especificado.
Com relação à função main, o retorno sempre será inteiro. Podemos fazer a função main 
retornar um zero quando ela é executada sem qualquer tipo de erro.
Mais um exemplo de função, que agora recebe dois floats e também retorna um float:
#include <stdio.h>
#include <stdlib.h>
float prod (float x,float y)
{
 return (x*y);
}
 int main (void)
 {
float saida;
saida=prod (45.2,0.0067);
printf ("A saida e: %8.5f. \n",saida);
system("pause");
 }
- Forma geral
Apresentamos aqui a forma geral de uma função: 
10
Programação de Computadores II Prof. Erlon Pinheiro
tipo_de_retorno nome_da_função (lista_de_parâmetros)
{ 
 código_da_função 
}
Exercícios de Fixação
1) Faça um programa que utilize uma função para calcular a soma de dois números lidos fora da 
função. O cálculo deve ser retornado para ser impresso pela função main().
2) Faça um programa que utilize uma função para calcular o fatorial de um número. O número 
deve ser lido na função main(), passado para a função calcular o fatorial e o resultado deve ser 
impresso na função main().
1.2.4 – Passagem de parâmetros por valor 
Até o momento utilizamos passagem de parâmetros por valor. Isto significa que qualquer 
alteração feita em um parâmetro dentro de uma função não alterou o seu argumento (fora da 
função), por exemplo: 
#include <stdio.h>
#include <stdlib.h>
 void mostra_valor(int a);
 main()
 {
 int a;
 a = 0;
mostra_valor(a);
printf("Valor de a fora da função: %d.\n\n",a);
system("pause");
 }
 void mostra_valor (int a) 
 {
a = 1;
printf("Valor de a dentro da função: %d.\n\n",a);
 }
Existe outro tipo de passagem de parâmetros que iremos estudar posteriormente: passagem de 
parâmetros por referência. Este tipo de passagem de parâmetros altera o valor do argumento 
passado para uma função. Mas para usarmos este tipo de passagem precisamos entender o que 
são variáveis do tipo ponteiro.
11
Programação de Computadores II Prof. Erlon Pinheiro
1.2.5 – PONTEIROS
O C é altamente dependente dos ponteiros. Assim, para um programador em C é 
fundamental dominar o básico (pelo menos) deles. Por isto, recomendo ao leitor um carinho 
especial com esta parte do curso que trata deles. Ponteiros são tão importantes na linguagem C 
que você já os viu e nem percebeu, pois mesmo para se fazer uma introdução básica à 
linguagem C precisa-se deles. 
O Ministério da Saúde adverte: o uso descuidado de ponteiros pode levar a sérios bugs e a dores de 
cabeça terríveis :-).
1.2.5.1 - Como Funcionam os Ponteiros
Os int s guardam inteiros. Os float s guardam números de ponto flutuante. Os char s 
guardam caracteres. Ponteiros guardam endereços de memória. Quando você anota o endereço 
de um colega você está criando um ponteiro. O ponteiro é este seu pedaço de papel. Ele tem 
anotado um endereço. Qual é o sentido disto? Simples. Quando você anota o endereço de um 
colega, depois você vai usar este endereço para achá-lo. O C funciona assim. Você anota o 
endereço de algo numa variável ponteiro para depois usar. 
Da mesma maneira, uma agenda, onde são guardados endereços de vários amigos, poderia ser 
vista como sendo uma matriz de ponteiros no C. 
Um ponteiro também tem tipo. Veja: quando você anota um endereço de um amigo você o trata 
diferente de quando você anota o endereço de uma firma. Apesar de o endereço dos dois locais 
ter o mesmo formato (rua, número, bairro, cidade, etc.) eles indicam locais cujos conteúdos são 
diferentes. Então os dois endereços são ponteiros de tipos diferentes. 
No C quando declaramos ponteiros nós informamos ao compilador para que tipo de variável 
vamos apontá-lo. Um ponteiro int aponta para um inteiro, isto é, guarda o endereço de um 
inteiro. 
1.2.5.2 - Declarando e Utilizando Ponteiros
Para declarar um ponteiro temos a seguinte forma geral: 
tipo_do_ponteiro *nome_da_variável;
É o asterisco (*) que faz o compilador saber que aquela variável não vai guardar um valor, mas 
sim um endereço para aquele tipo especificado. Vamos ver exemplos de declarações: 
 int *pt;
 char *temp,*pt2;
O primeiro exemplo declara um ponteiro para um inteiro. O segundo declara dois ponteiros 
para caracteres. Eles ainda não foram inicializados (como toda variável do C que é apenas 
declarada). Isto significa que eles apontam para um lugar indefinido. Este lugar pode estar, por 
exemplo, na porção da memória reservada ao sistema operacional do computador. Usar o 
ponteiro nestas circunstâncias pode levar a um travamento do micro, ou a algo pior.
12
Programação de Computadores II Prof. Erlon Pinheiro
O ponteiro deve ser inicializado (apontado para algum lugar conhecido) antes de ser usado! Isto é de 
suma importância! 
Para atribuir um valor a um ponteiro recém-criado poderíamos igualá-lo a um valor de 
memória. Mas, como saber a posição na memória de uma variável do nosso programa? Seria 
muito difícil saber o endereço de cada variável que usamos, mesmo porque estes endereços são 
determinados pelo compilador na hora da compilação e realocados na execução. Podemos 
então deixar que o compilador faça este trabalho por nós. Para saber o endereço de uma 
variável basta usar o operador &. Veja o exemplo: 
 int cont=10;
 int *pt;
 pt=&cont;
Criamos um inteiro cont com o valor 10 e um apontador para um inteiro pt. A expressão &cont 
nos dá o endereço de cont, o qual armazenamos em pt. Simples, não é? Repare que não 
alteramos o valor de cont, que continua valendo 10. 
Como nós colocamos um endereço em pt, ele está agora "liberado" para ser usado. Podemos, 
por exemplo, alterar o valor de cont usando pt. Para tanto vamos usar o operador "inverso" do 
operador &. É o operador *. No exemplo acima, uma vez que fizemos pt=&cont a expressão *pt 
é equivalente ao próprio cont. Isto significa que, se quisermos mudar o valor de cont para 12, 
basta fazer *pt=12. 
Vamos fazer uma pausa e voltar à nossa analogia para ver o que está acontecendo. 
Digamos que exista uma firma. Ela é como uma variável que já foi declarada. Você tem um 
papel em branco onde vai anotar o endereço da firma. O papel é um ponteiro do tipo firma. 
Você então liga para a firma e pede o seu endereço, o qual você vai anotar no papel. Isto é 
equivalente, no C, a associar o papel à firma com o operador &. Ou seja, o operador & aplicado à 
firma é equivalente a você ligar para a mesma e pedir o endereço. Uma vez de posse do 
endereço no papel você poderia, por exemplo, fazer uma visita à firma. No C você faz uma visita 
à firma aplicando o operador * ao papel. Uma vez dentro da firma você pode copiar seu 
conteúdo ou modificá-lo. 
Uma observação importante: apesar do símbolo ser o mesmo, o operador * (multiplicação)não 
é o mesmo operador que o * (referência de ponteiros). Para começar o primeiro é binário, e o 
segundo é unário pré-fixado. 
Aqui vão dois exemplos de usos simples de ponteiros: 
#include <stdio.h>
#include <stdlib.h>
main ()
{
int num,valor;
int *p;
num=55;
p=&num; /* Pega o endereço de num */
valor=*p; /* Valor e igualado a num de uma 
13
Programação de Computadores II Prof. Erlon Pinheiro
maneira indireta */
printf ("\n\n Variavel valor = %d \n",valor);
printf ("Endereco para onde o ponteiro aponta: %p\n",p);
printf ("Valor da variavel apontada: %d\n",*p);
system("pause");
}
#include <stdio.h>
#include <stdlib.h>
main ()
{
int num,*p;
num=55;
p=&num; /* Pega o endereco de num */
printf ("\nValor inicial: %d\n",num);
*p=100; /* Muda o valor de num de uma maneira indireta */
printf ("\nValor final: %d\n",num);
system(“pause”);
}
Nos exemplos acima vemos um primeiro exemplo do funcionamento dos ponteiros. No 
primeiro exemplo, o código %p usado na função printf() indica à função que ela deve imprimir 
um endereço. 
Exercícios de Fixação
Veja como você está. 
a) Explique o que é uma variável do tipo ponteiro. 
b) Qual o valor de x e y no final do programa? Tente primeiro descobrir e depois verifique no 
computador o resultado. A seguir, escreva um /* comentário */ em cada comando de atribuição 
explicando o que ele faz e o valor da variável à esquerda do '=' após sua execução. 
main() 
{ 
 int x, y, *p,*q; 
 y = 1;
 x = 2;
 p = &y;
 q = &x;
 x--; //x = x -1;
 *p *= x+1;// *p = (*p)*(x+1);
 *q += y; // *q = *q +y;
 p = q;
 *p -= x; // *q = *q – x;
 printf ("y = %d\n", y); 
 printf ("x = %d\n", x); 
14
Programação de Computadores II Prof. Erlon Pinheiro
} 
1.2.6 - Passagem de parâmetros por valor e passagem por referência
Já vimos que, na linguagem C, quando chamamos uma função os parâmetros formais da função 
copiam os valores dos parâmetros que são passados para a função. Isto quer dizer que não são 
alterados os valores que os parâmetros têm fora da função. Este tipo de chamada de função é 
denominado chamada por valor. Isto ocorre porque são passados para a função apenas os 
valores dos parâmetros e não os próprios parâmetros. Veja o exemplo abaixo: 
#include <stdio.h>
#include <stdlib.h>
float quadrado (float num);
main ()
{
float num,quad;
printf ("Entre com um numero: ");
scanf ("%f",&num);
quad = quadrado(num);
printf ("\n\nO numero original e: %f\n",num);
printf ("O seu quadrado vale: %f\n",quad);
system("pause"); }
float quadrado (float num)
{
num=num*num;
return num;
}
No exemplo acima o parâmetro formal num da função quadrado() sofre alterações dentro da 
função, mas a variável num da função main() permanece inalterada: é uma chamada por valor. 
Outro tipo de passagem de parâmetros para uma função ocorre quando alterações nos 
parâmetros formais, dentro da função, alteram os valores dos parâmetros que foram passados 
para a função. Este tipo de chamada de função tem o nome de "chamada por referência". Este 
nome vem do fato de que, neste tipo de chamada, não se passa para a função os valores das 
variáveis, mas sim suas referências (a função usa as referências para alterar os valores das 
variáveis fora da função). 
O C só faz chamadas por valor. Isto é bom quando queremos usar os parâmetros formais à 
vontade dentro da função, sem termos que nos preocupar em estar alterando os valores dos 
parâmetros que foram passados para a função. Mas isto também pode ser ruim às vezes, porque 
podemos querer mudar os valores dos parâmetros fora da função também. Há entretanto, no C, 
um recurso de programação que podemos usar para simular uma chamada por referência. 
Quando queremos alterar as variáveis que são passadas para uma função, nós podemos declarar 
seus parâmetros formais como sendo ponteiros. Os ponteiros são a "referência" que precisamos 
15
Programação de Computadores II Prof. Erlon Pinheiro
para poder alterar a variável fora da função. O único inconveniente é que, quando usarmos a 
função, teremos de lembrar de colocar um & na frente das variáveis que estivermos passando 
para a função. Veja um exemplo: 
#include <stdio.h>
#include <stdlib.h>
void troca (int *a,int *b);
main ()
{
int num1,num2;
num1=100;
num2=200;
troca (&num1,&num2);
printf ("\n\nEles agora valem %d %d\n",num1,num2);
system("pause");
}
void troca (int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
Não é muito difícil. O que está acontecendo é que passamos para a função troca() o endereço 
das variáveis num1 e num2. Estes endereços são copiados nos ponteiros a e b. Através do 
operador * estamos acessando o conteúdo apontado pelos ponteiros e modificando-o. Mas, 
quem é este conteúdo? Nada mais que os valores armazenados em num1 e num2, que, portanto, 
estão sendo modificados! 
Espere um momento... será que nós já não vimos esta estória de chamar uma função com as 
variáveis precedidas de &? Já! É assim que nós chamamos a função scanf(). Mas por quê? Vamos 
pensar um pouco. A função scanf() usa chamada por referência porque ela precisa alterar as 
variáveis que passamos para ela! Não é para isto mesmo que ela é feita? Ela lê variáveis para nós 
e portanto precisa alterar seus valores. Por isto passamos para a função o endereço da variável 
a ser modificada! 
Exercício de Fixação
Escreva uma função que receba duas variáveis inteiras e "zere" o valor das variáveis. Use o que 
você aprendeu nas páginas anteriores para fazer a implementação. 
RESOLUÇÃO:
#include<stdio.h>
16
Programação de Computadores II Prof. Erlon Pinheiro
#include<stdlib.h>
void zera_numeros(int *n1, int *n2);
main()
{
int num1, num2;
//Entrada de dados
printf(“Digite dois números inteiros:”);
scanf(“%d%d”, &num1,&num2);
//Processamento de dados
zera_numeros(&num1,&num2);
//Saída de dados
printf(“\n\nnum1 = %d e num2 = %d\n\n“,num1,num2);
system(“pause”);
}
void zera_numeros(int *n1, int *n2)
{
*n1 = 0;
*n2 = 0;
}
Exercício de fixação parcialmente resolvido
Desenvolver um programa calculadora que apresente um menu de seleções no programa 
principal. Esse menu deve dar ao usuário a possibilidade de escolher uma entre quatro 
operações aritméticas. Escolhida a opção desejada, deve ser solicitada à entrada de dois 
números, processada a operação, deve ser exibido o resultado.
Algoritmo
Note que este programa deve ser um conjunto de cinco módulos, sendo um principal e quatro 
secundários. O módulo principal efetuará o controle dos quatro módulos secundários que, por 
17
Programação de Computadores II Prof. Erlon Pinheiro
sua vez, efetuarão o pedido de leitura de dois valores, farão à operação e apresentarão o 
resultado obtido. 
Tendo uma idéia da estrutura do programa, será escrito em separado cada algoritmo com os 
seus detalhes de operação. Primeiro o programa principal e depois os outros módulos.
Programa Principal 
1. Apresentar um menu de seleções com cinco opções:
1. Adição
2. Subtração
3. Multiplicação
4. Divisão Inteira
5. Fim de Programa
Escolha uma opção: 
2. Armazenar a opção escolhida;
3. O módulo correspondente a opção escolhida deve ser executado;
4. Ao escolher o valor 5, o programa deve ser encerrado e caso o usuário escolha uma opção 
inválida, o programa deve exibir uma mensagem de erro e voltar ao menu inicial.
Modulo 1 - Adição
1. Ler dois valores, no caso variáveis inteiras A e B;
2. Efetuar a soma das variáveis A e B, atribuindo o seu resultado na variável X;
3. Apresentar o valor da variável X;
4. Voltar ao programa Principal;
Modulo 2 - Subtração
1. Ler dois valores,no caso variáveis inteiras A e B;
2. Efetuar a subtração das variáveis A e B, atribuindo o seu resultado na variável X;
3. Apresentar o valor da variável X;
4. Voltar ao programa Principal;
Modulo 3 - Multiplicação
1. Ler dois valores, no caso variáveis inteiras A e B;
2. Efetuar a multiplicação das variáveis A e B, atribuindo o seu resultado na variável X;
3. Apresentar o valor da variável X;
Modulo 4 – Divisão Inteira
18
Programação de Computadores II Prof. Erlon Pinheiro
1. Ler dois valores, no caso variáveis inteiras A e B;
2. Efetuar a divisão inteira das variáveis A e B, atribuindo o seu resultado na variável X;
3. Apresentar o valor da variável X;
Faça o programa C referente a este algoritmo.
1.2.7 - Variáveis globais
Variáveis globais são declaradas fora de todas as funções do programa. Elas são conhecidas e 
podem ser alteradas por todas as funções do programa. Quando uma função tem uma variável 
local com o mesmo nome de uma variável global a função dará preferência à variável local. 
Vamos ver um exemplo: 
int z,k;
func1 (...)
{
int x,y;
...
}
func2 (...)
{
int x,y,z;
...
z=10;
...
}
main ()
{
int cont;
...
}
No exemplo acima as variáveis z e k são globais. Veja que func2() tem uma variável local 
chamada z. Quando temos então, em func2(), o comando z=10 quem recebe o valor de 10 é a 
variável local, não afetando o valor da variável global z. 
Na nossa disciplina NÃO será permitido o uso de variáveis globais. Elas ocupam memória o 
tempo todo (as locais só ocupam memória enquanto estão sendo usadas) e tornam o programa 
mais difícil de ser entendido e menos geral. As únicas variáveis que serão admitidas como 
globais serão os índices de vetores e matrizes.
1.2.8 - Ponteiros e Vetores
Veremos nestas seções que ponteiros e vetores têm uma ligação muito forte. 
Quando você declara um vetor da seguinte forma: 
19
Programação de Computadores II Prof. Erlon Pinheiro
tipo_da_variável nome_da_variável [tam];
o compilador C calcula o tamanho, em bytes, necessário para armazenar este vetor. Este 
tamanho é: 
tam x tamanho_do_tipo
O compilador então aloca este número de bytes em um espaço livre de memória. O nome da 
variável que você declarou é na verdade um ponteiro para o tipo da variável vetor. Este conceito é 
fundamental. Eis por que: Tendo alocado na memória o espaço para o vetor, ele toma o nome da 
variável (que é um ponteiro) e aponta para o primeiro elemento do vetor. 
Mas aí surge a pergunta: então como é que podemos usar a seguinte notação? 
nome_da_variável[índice]
Isto pode ser facilmente explicado desde que você entenda que a notação acima é absolutamente 
equivalente a se fazer:
*(nome_da_variável+ índice)
Agora podemos entender como é que funciona um vetor! Vamos ver o que podemos tirar de 
informação deste fato. Fica claro, por exemplo, porque é que, no C, a indexação começa com 
zero. É porque, ao pegarmos o valor do primeiro elemento de um vetor, queremos, de fato, 
*nome_da_variável e então devemos ter um índice igual a zero. Então sabemos que: 
*nome_da_variável é equivalente a nome_da_variável[0]
Outra coisa: apesar de, na maioria dos casos, não fazer muito sentido, poderíamos ter índices 
negativos. Estaríamos pegando posições de memória antes do vetor. Isto explica também 
porque o C não verifica a validade dos índices. Ele não sabe o tamanho do vetor. Ele apenas 
aloca a memória, ajusta o ponteiro do nome do vetor para o início do mesmo e, quando você 
usa os índices, encontra os elementos requisitados. 
Há uma diferença entre o nome de um vetor e um ponteiro que deve ser frisada: um ponteiro é 
uma variável, mas o nome de um vetor não é uma variável. Isto significa que não se consegue 
alterar o endereço que é apontado pelo "nome do vetor". Seja: 
 const int tam = 10;
 int vetor[tam];
 int *ponteiro, i;
 ponteiro = &i;
 /* as operações a seguir são inválidas */
 vetor = vetor + 2; /* ERRADO: vetor não e' variavel */
 vetor++; /* ERRADO: vetor não e' variavel */
 vetor = ponteiro; /* ERRADO: vetor não e' variavel */
Teste as operações acima no seu compilador. Ele dará uma mensagem de erro. 
20
Programação de Computadores II Prof. Erlon Pinheiro
 /* as operacoes abaixo sao validas */
 ponteiro = vetor; /* CERTO: ponteiro e' variavel */
 ponteiro = vetor+2; /* CERTO: ponteiro e' variavel */
Sabemos agora que, na verdade, o nome de um vetor é um ponteiro constante. Sabemos 
também que podemos indexar o nome de um vetor. Como conseqüência podemos também 
indexar um ponteiro qualquer. O programa mostrado a seguir funciona perfeitamente: 
#include <stdio.h>
#include <stdlib.h>
main ()
{
const int tam = 10;
int vetor [tam] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *p;
p=vetor;
printf ("O terceiro elemento do vetor e: %d",p[2]);
system(“pause”);
}
Podemos ver que p[2] equivale a *(p+2) e a vetor[2]. 
O que você aprendeu nesta seção é de suma importância. Não siga adiante antes de entendê- la 
bem. 
1.2.9 - Vetores como Parâmetros
Seja o seguinte vetor:
const int TAM = 50;
int meuvetor[TAM];
Para passar o vetor meuvetor como parâmetro em uma função C, por exemplo, da função 
func(), tem-se que ter o parâmetro formal de func() declarado de uma das três maneiras 
apresentadas a seguir:
void func(int vet[TAM])
ou
void func(int vet[])
ou
void func(int *vet)
Nos três casos, tem-se em func() um int * chamado vet. Ao passar um vetor para uma função, 
na realidade se está passando um ponteiro. Nesse ponteiro é armazenado o endereço do 
primeiro elemento do vetor. Isto significa que não é feita uma cópia, elemento a elemento do 
21
Programação de Computadores II Prof. Erlon Pinheiro
vetor. Isso faz com que se possa alterar o valor dos elementos do vetor dentro da função 
(passagem por referência). Para simplificar podemos utilizar o primeiro modelo como padrão.
Exemplo: Como que ficaria um programa (modularizado) que apenas leia um vetor de 15 
números inteiros e apresente-o na tela?
Resolução:
#include <stdio.h>
#include <stdlib.h>
const int TAM = 15;
int i;
void leitura(int vet[TAM]);// ou void leitura(int *vet);
void mostra_vet(int vet[TAM]); // void mostra_vet(int *vet);
main ()
{
int meuvetor[TAM];
//Entrada de dados
printf ("Entrada de dados do vetor:\n\n”);
leitura(meuvetor);//Note que passamos apenas o nome
//Saída de dados
printf(“\n\nO vetor lido:\n\n”);
mostra_vet(meuvetor);
system(“pause”);
}
void leitura(int vet[TAM])// void leitura(int *vet)
{
for(i=0;i<TAM;i++)
{
printf(“Digite o %do numero: “, i+1);
scanf(“%d”, &vet[i]);
}
}
void mostra_vet(int vet[TAM])
{
for(i=0;i<TAM;i++)
printf(“%5d”, vet[i]);
printf(“\n\n”);
}
Obs.: Refaça os exercícios de Programação I para treinar modularização utilizando vetores.
22
Programação de Computadores II Prof. Erlon Pinheiro
Exercícios Complementares 1
PROCURE PRIMEIRO PENSAR E RESOLVER OS EXERCÍCIOS EM PAPEL, E SÓ DEPOIS 
IMPLEMENTE E TESTE O PROGRAMA EM SEU COMPUTADOR.
1. Faça um programa que calcule e mostre o CÁLCULO DA HIPOTENUSA, sabendo as medidas 
dos catetos do triângulo retângulo.
2. Para cada item faça um programa modularizado C que:
a) utilizando uma função calcule o arranjo de n elementos, p a p. Utilize fórmula A = 
n!/( n – p)!. A leitura de n e p deve ser feita na função main() e deve ser criado um 
módulo que retorne o valor de A. Deve-se utilizar o módulo que calcula o fatorial 
implementado em sala.
b) utilizando uma função calcule o número de combinações de n elementos, p a p. Utilize 
fórmula C = n!/(p! * ( n – p)!). A leitura de n e p deve ser feitana função main() e deve ser 
criado um módulo que retorne o valor de C.
c) calcule o somatório dos n primeiros termos da série de Fibonacci ( 1, 1, 2, 3, 5, 8, ...). A 
função deve receber o valor de n e retornar o valor do somatório para ser impresso na 
função principal.
3. Faça um programa C modularizado que leia 2 salários, identifique e imprima o maior. Use 
uma função para identificar e imprimir o maior salário.
4. Faça um programa C modularizado que calcule e mostre o valor da ÁREA DE UM QUADRADO, 
sabendo a medida do lado do quadrado. 
Faça uma versão deste problema para a área DE UM CÍRCULO.
5. Faça um programa C modularizado que calcule e mostre o CÁLCULO DA ÁREA DE UM 
TRIÂNGULO, sabendo a medida da base e da altura do triângulo. 
6. Crie um programa C modularizado que simule uma CALCULADORA que apresente o menu 
abaixo e permita que o usuário efetue quantas e quais operações desejar com dois números 
lidos na opção 1 - Entrada de Dados. Ou seja, o usuário deve escolher a opção 1, digitar dois 
números e, em seguida, voltar ao menu para escolher qualquer das 4 operações. Após o usuário 
efetuar a escolha da operação, mostre o resultado e volte ao menu para que uma nova operação 
possa ser escolhida ou uma nova entrada de dados possa ser feita.
 1 - Entrada de dados
2 - Adição
3 - Subtração
4 - Multiplicação
5 - Divisão
6 - Encerrar
Escolha uma das operações:
 Para mostrar o menu de opções e ler a opção escolhida use uma função. 
 Use funções para implementar as opções 2, 3, 4 e 5. Em cada função use como parâmetros os 
dois valores numéricos reais lidos na opção 1; os quais serão usados nas operações de adição, 
23
Programação de Computadores II Prof. Erlon Pinheiro
subtração, multiplicação ou divisão, dependendo da operação realizada pela função. Cada 
função deve retornar o resultado da operação realizada.
 Na operação de divisão o denominador não pode ser nulo. Use uma função para verificar 
este fato antes de efetuar a divisão. Esta função deve ter como parâmetro o denominador da 
divisão e retornar verdadeiro caso o denominador seja nulo e falso caso contrário.
Resolução Parcial
Algoritmo
Note que este programa deve ser um conjunto de seis módulos, além da função principal. O 
módulo principal efetuará o controle dos seis módulos secundários que: (1º módulo) mostrará o 
menu, lerá e retornará a opção lida;
(2º módulo) calculará e retornará a adição;
(3 º módulo) calculará e retornará a subtração;
(4 º módulo) calculará e retornará a multiplicação;
(5 º módulo) calculará e retornará a divisão;
(6 º módulo) verificará se o denominador é nulo. 
Tendo uma ideia da estrutura do programa, será escrito em separado cada algoritmo com os 
seus detalhes de operação. Primeiro o programa principal (main) e depois os outros módulos.
Programa Principal 
1. Chamar o módulo que apresenta um menu de seleções com seis opções:
1. Entrada de dados
2. Adição
3. Subtração
4. Multiplicação
5. Divisão
6. Fim de Programa
Escolha uma opção: 
2. Armazenar a opção escolhida;
3. O módulo correspondente a opção escolhida deve ser executado;
4. Ao escolher o valor 6, o programa deve ser encerrado e caso o usuário escolha uma opção 
inválida, o programa deve exibir uma mensagem de erro e voltar ao menu inicial (uso de um 
24
Programação de Computadores II Prof. Erlon Pinheiro
comando de repetição: de preferência o do/while). Observe que na opção 5 a função que 
verifica se o denominador é nulo deverá ser utilizada.
Modulo 1 – Mostra o menu 
Apresentar o menu de opções;
Ler a opção desejada;
Retornar a opção para a função main;
Modulo 2: Adição
Efetuar a soma dos números lidos na função main;
retornar o valor calculado;
Voltar ao programa Principal = finalizar o módulo;
Modulo 3 - Subtração
Efetuar a subtração dos números lidos na função main;
retornar o valor calculado;
Voltar ao programa Principal = finalizar o módulo;
Modulo 4 - Multiplicação
Efetuar a multiplicação dos números lidos
retornar o valor calculado;
Voltar ao programa Principal = finalizar o módulo;
Modulo 5 – Divisão 
Efetuar a divisão dos números lidos
retornar o valor calculado;
Voltar ao programa Principal = finalizar o módulo;
Modulo 6: Verifica denominador nulo:
Fica como exercício...
Obs.: A verificação do denominador nulo será feita na função principal.
25
Programação de Computadores II Prof. Erlon Pinheiro
Faça o programa C referente a este algoritmo.
7. Faça um programa que leia os limites de um intervalo de números inteiros, identifique, conte 
e imprima a quantidade de números pares e ímpares deste intervalo. Construir uma função 
para identificar, contar a quantidade de números pares e ímpares. A impressão deve ser feita na 
função main().
8. Faça um programa C que utilizando uma função ordene três números inteiros (distintos) 
lidos na função principal main( ). Imprima os números ordenados em main( ). A função deve 
receber apenas os três parâmetros (ponteiros) para ordenar os números por referência. Dica: 
Podem usar variáveis locais para ajudar no processo de ordenação.
9. Faça uma função que verifique se um número inteiro, declarado como parâmetro da função, é 
divisível por 5. A função deve retornar 1 se sim e 0 caso contrário.
10. No algoritmo abaixo implemente a função MAIOR
algoritmo imprime_maior;
.
:
{ algoritmo principal }
inicio
 inteiro a, b, c;
 leia (a, b, c);
 escreva (“Maior número = “, MAIOR (a, b, c));
 fim.
11. Escreva uma função que possua um número inteiro A como parâmetro e devolva o número 
de divisores de A. Para verificar o número de divisores de A teste, para todo x no intervalo [1, 
A/2].
Usando a função escrita acima, escreva outra função que possua um número inteiro N como 
parâmetro e determine se ele é ou não um número primo. N será primo se a função definida no 
parágrafo acima retornar o número de divisores igual a 1.
12. No algoritmo abaixo implemente a função F de forma que retorne o resultado da seguinte 
expressão: f(x) = x2 + 3x -9
algoritmo expressao;
:
{ALGORITMO PRINCIPAL}
inicio
 real x;
 escreva(“Digite um numero real: “);
 leia (x);
 escreva (“f(x) = x2 + 3x –9 = “, f(x));
 fim.
26
Programação de Computadores II Prof. Erlon Pinheiro
13. Seja o seguinte trecho de programa:
int i=3,j=5;
int *p, *q;
p = &i;
q = &j;
Qual é o valor das seguintes expressões ?
a) p == &i; b) *p - *q c) (*p)*(*q)== 20 d) 10* - (*p)/(*q)+7
14. Se i e j são variáveis inteiras e p e q ponteiros para inteiros devidamente inicializadas, quais 
das seguintes expressões de atribuição são ilegais?
a) p = &i; b) *q = &j; c) p = q; d) i = *j;
e) i = *&j; f) i = *&*&j; g) q = *p; h) i = (*p)++ + *q
15. Utilizando a elaboração de procedimentos, faça um programa que leia dois vetores de 10 
elementos do tipo real. Intercale os elementos destes dois vetores criando um novo vetor de 20 
elementos. Exiba o novo vetor.
Exemplo:
Vetor1
0 1 2 3 4 5 6 7 8 9
2 9 7 5.5 10 4 3 -1 6 21
Vetor2
0 1 2 3 4 5 6 7 8 9
 32 -4 12 6 90 -4 5 43 27 82
Vetor criado a partir dos anteriores
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
19
2 3
2
9 -4 7 1
2
5.5 6 1
0
9
0
4 -4 3 5 -1 4
3
6 2
7
2
1
82
 
16. Utilizando a elaboração de procedimentos, faça um programa que tendo lido um vetor VET 
de 10 números inteiros diferentes de zero, crie um novo vetor VETPAR com os elementos pares 
do vetor VET. Antes de preencher o vetor VETPAR com os números pares de VET faça com que 
todos os componentes de VETPAR recebam o valor zero. Ao finalexiba VETPAR.
Exemplo:
27
Programação de Computadores II Prof. Erlon Pinheiro
Vetor VET
0 1 2 3 4 5 6 7 8 9
2 9 7 5 10 4 3 5 6 21
Vetor VETPAR
0 1 2 3 4 5 6 7 8 9
2 10 4 6 0 0 0 0 0 0
17. Uma mercearia trabalha com 10 mercadorias diferentes identificadas pelos números 
inteiros de 1 a 10. O dono da mercearia anota em uma tabela a quantidade de cada mercadoria 
vendida durante o dia. Ele possui uma outra tabela que indica para cada mercadoria o preço de 
venda. Um exemplo das tabelas é mostrado abaixo. Utilizando a elaboração de procedimentos, 
faça um programa que calcule e exiba o faturamento do dia da mercearia.
Vetores exemplo:
0 1 2 3 4 5 6 7 8 9
Quantidade 23 41 7 23 23 45 6 8 211 112
0 1 2 3 4 5 6 7 8 9
Preço 10 5 2 12 23 1.5 6 5.55 3.50 1
Faturamento referente a mercadoria número 2 = 41*5
18. Faça um programa que leia 2 vetores, A e B, de tamanhos e tipos iguais e, construa um 
terceiro vetor C composto pela junção de A e B. Use módulos.
19. Uma Universidade deseja saber se existem alunos cursando simultaneamente as disciplinas 
Programação II e Lógica para Computação. Para tanto, coloque os números de matrícula dos 
alunos que cursam a disciplina Programação II em um vetor e os números de alunos que cursam 
Lógica para Computação em outro vetor. Exiba os números de matrícula que aparecem em 
ambos os vetores. Use procedimentos e funções.
28
Programação de Computadores II Prof. Erlon Pinheiro
Unidade 2: Strings
2.1 - Introdução
Strings são vetores de char s . Nada mais e nada menos. As strings são o uso mais comum para os 
vetores. Devemos apenas ficar atentos para o fato de que as strings têm o seu último elemento 
como um '\0'. A declaração geral para uma string é: 
char nome_da_string [tamanho];
Devemos lembrar que o tamanho da string deve incluir o '\0' final. A biblioteca padrão do C 
possui diversas funções que manipulam strings. Estas funções são úteis pois não se pode, por 
exemplo, igualar duas strings: 
string1==string2; /* NAO faca isto */
Fazer isto é um desastre. As strings devem ser igualadas elemento a elemento. 
Para armazenar uma string em C devemos reservar uma posição adicional para o caractere de 
fim da cadeia. Todas as funções de manipulação de strings em C recebem como parâmetro um 
vetor de char, isto é, um ponteiro para o primeiro elemento do vetor que representa a string. 
Ex.: para imprimir uma string utilizando o comando printf, utiliza-se o especificador de 
formato %s printf recebe um vetor de char e imprime elemento por elemento até encontrar o 
caractere nulo. Vantagem de delimitar a string por ‘\0’ não é necessário passar explicitamente 
o número de caracteres a ser considerado.
main( )
{
 const int tam = 4;
char faculdade[tam];
faculdade[0] = ‘U’;
faculdade[1] = ‘V’;
faculdade[2] = ‘V’;
faculdade[3] = ‘\0’;
printf(“%s \n”, faculdade);
system(“pause”);
} 
29
Programação de Computadores II Prof. Erlon Pinheiro
Se o caractere ‘\0’ não fosse colocado, a função printf seria executada de forma errada, pois não 
conseguiria identificar o final da cadeia.
Como as strings são vetores, podemos reescrever o código anterior inicializando os elementos 
diretamente na declaração:
main( )
{
char faculdade[ ] = {‘U’,‘V’,‘V’,‘\0’}; /*a variável 
faculdade é automaticamente dimensionada e 
inicializada com 4 elementos.*/
printf(“%s \n”, faculdade);
system(“pause”);
}
Exemplos de declarações e inicializações de strings:
char s1[] = “”; //cadeia vazia (‘\0’)
char s2[] = “Vila Velha”; //vetor de 11 elementos
char s3[81]; /*string capaz de armazenar cadeias de até 80 elementos, com conteúdo 
desconhecido */
char s4[81] = “UVV”; /* também capaz de armazenar até 80 caracteres, mas seus primeiros 4 
elementos já foram atribuídos na declaração. */
2.2 – Leitura de Strings
Em programação I vimos que a leitura de um caractere deve ser feita com cuidado, por 
exemplo:
char a;
...
scanf(“%c”, &a);
...
30
Programação de Computadores II Prof. Erlon Pinheiro
Diferentemente dos especificadores %d e %f, o %c não pula os caracteres brancos (espaço, 
tabulação ou nova linha). Assim, este código possivelmente gerará erro quando for utilizado em 
programas maiores. O correto seria:
char a;
...
scanf(“ %c”, &a); /* o branco no formato pula brancos 
da entrada */
...
Para capturar uma string:
char faculdade[81];
...
scanf(“%s”, faculdade); /* aqui não foi usado o caractere & pois a string é um vetor – o nome da 
variável representa o endereço do primeiro elemento do vetor */
Uso do especificador %s na leitura é limitado, pois ele pula os caracteres brancos, capturando 
somente a primeira seqüência de não-brancos.
Como ler nomes compostos?
Especificador %[...], onde especificamos entre os colchetes todos os caracteres que aceitaremos 
na leitura. Exemplo: o formato “%[aeiou]” lê seqüências de vogais, isto é a leitura prossegue até 
se encontrar um caractere que não seja vogal.
Se o primeiro caractere for o acento circunflexo (^), teremos o efeito inverso (negação). Assim, 
“%[^aeiou]” faz a leitura enquanto uma vogal não for encontrada.
char faculdade[81];
scanf(“ %[^\n]”, faculdade); /* lê seqüência de caracteres até que seja encontrado o caractere 
de mudança de linha (‘\n’), ou seja, captura-se 
até que ele tecle “Enter” */
Perigo: se o usuário fornecer uma linha com mais de 80 caracteres... invasão de espaço de 
memória não reservado!
char faculdade[81];
scanf(“ %80[^\n]”, faculdade); /* lê no máximo 80 caracteres */
Exemplos:
31
Programação de Computadores II Prof. Erlon Pinheiro
2.3 – Criando funções que manipulam strings
A impressão de uma variável string é feita como se ela fosse uma variável simples, isto é, basta 
usar a tag %s em um printf que a string será impressa.
1) É possível criar uma função que imprima o string caractere por caractere:
void imprime(char *s) 
{
int i;
for (i=0; s[i] != ‘\0’; i++)
 printf(“%c”, s[i]);
printf(“\n”);
}
2) Esse código teria uma funcionalidade análoga à utilização do especificador de formato %s.
void imprime (char* s) 
{
printf(“%s\n”, s);
}
3) Função para retornar o comprimento de uma string – basta contar o número de caracteres até 
o caractere nulo.
int comprimento (char *s)
{
int i;
int n = 0; /* contador */
for (i=0; s[i] != ‘\0’; i++)
 n++;
return n;
}
32
Programação de Computadores II Prof. Erlon Pinheiro
O trecho de código a seguir faz uso desta função:
main ( )
{
int tam;
char cidade[ ] = “Vila Velha”;
tam = comprimento(cidade);
printf(“A string \“ %s \“ tem %d caracteres\n”, cidade, tam);
system(“pause”);
} 
4) Função que copia os elementos de uma string para outra:
void copia (char *dest, char *orig) 
{
int i;
for(i=0; orig[i] != ‘\0’; i++)
 dest[i] = orig[i];
dest[i] = ‘\0’; /* fecha a cadeia copiada */
} 
6) Função para concatenar uma string com outra já existente:
void concatena (char* dest, char* orig) 
{
int i=0; /* indice usado na cadeia de destino */
int j; /* indice usado na cadeia de origem */
/* acha o final do destino */
while (dest[i] != 0) 
 i++;
33
Programação de Computadores II Prof. Erlon Pinheiro
/* copia elementos da origem para o final do destino */
for (j=0; orig[j] != ‘\0’; j++) 
{
 dest[i] = orig[j];
 i++;
}
dest[i] = ‘\0’; /* fecha a cadeia destino */
}
2.4 – Funções pré-definidas para manipulação de strings
Vamos ver agora algumas funções básicas para manipulação de strings. 
a) gets
A função gets( ) lê uma string do teclado. Sua forma geral é: 
gets (nome_da_string);
 O programaabaixo demonstra o funcionamento da função gets( ): 
#include <stdio.h>
#include <stdlib.h>
main ( )
{
char nome[100];
printf ("Digite o seu nome: ");
gets (nome);
printf ("\n\n Ola %s", nome);
system(“pause”);
}
b) puts
puts imprime o conteúdo de uma string e desce para a próxima linha. Para imprimir a string do 
exemplo anterior bastava usar: puts(nome);
34
Programação de Computadores II Prof. Erlon Pinheiro
c) strcpy
Sua forma geral é: strcpy (string_destino,string_origem);
A função strcpy() copia a string-origem para a string- destino. Seu funcionamento é 
semelhante ao da rotina apresentada na seção anterior. As funções apresentadas nestas seções 
estão no arquivo cabeçalho string.h. A seguir apresentamos um exemplo de uso da função 
strcpy(): 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main ()
{
char str1[100],str2[100],str3[100];
printf ("Entre com uma string: ");
gets (str1);
strcpy (str2,str1); /* Copia str1 em str2 */
strcpy (str3,"Voce digitou a string "); /* Copia "Voce digitou a string" em str3 */
printf ("\n\n%s%s",str3,str2);
system(“pause”);
}
d) strcat
A função strcat() tem a seguinte forma geral: 
strcat (string_destino,string_origem);
A string de origem permanecerá inalterada e será anexada ao fim da string de destino. Um 
exemplo: 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main ()
{
char str1[100],str2[100];
printf ("Entre com uma string: ");
gets (str1);
strcpy (str2,"Voce digitou a string ");
strcat (str2,str1); /* str2 armazenara' Voce digitou a string + o conteudo de str1 */
printf ("\n\n%s",str2);
system(“pause”);
}
35
Programação de Computadores II Prof. Erlon Pinheiro
e) strlen
Sua forma geral é: strlen (string);
A função strlen() retorna o comprimento da string fornecida. O terminador nulo não é contado. 
Isto quer dizer que, de fato, o comprimento do vetor da string deve ser um a mais que o inteiro 
retornado por strlen().
Um exemplo do seu uso:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main ()
{
int comprimento;
char frase[100];
printf ("Entre com uma frase: ");
gets (frase);
comprimento = strlen (frase);
printf ("\n\nA frase que voce digitou tem tamanho %d", comprimento);
system(“pause”);
}
f) strcmp
Sua forma geral é: strcmp (string1,string2);
A função strcmp() compara a string 1 com a string 2. Se as duas forem idênticas, a função 
retorna zero. Se elas forem diferentes a função retorna não-zero. Um exemplo da sua 
utilização: 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main ()
{
char str1[100],str2[100];
printf ("Entre com uma string: ");
gets (str1);
printf ("\n\nEntre com outra string: ");
gets (str2);
if (strcmp(str1,str2)) // strcmp(str1,str2) != 0
 printf ("\n\nAs duas strings são diferentes.");
else 
 printf ("\n\nAs duas strings são iguais.");
system(“pause”);
}
36
Programação de Computadores II Prof. Erlon Pinheiro
g) toupper
Esta é uma função para tornar um caractere alfabético no seu correspondente maiúsculo. Para 
utilizá-lo deve-se utilizar a biblioteca ctype, isto é, para utilizá-la no início do programa deve-se 
usar a diretiva: #include<ctype.h>
A função toupper recebe um caractere e retorna o seu correspondente maiúsculo. Caso o 
caractere não seja uma letra válida a função mantém o caractere original.
Exemplo: Considere a declaração abaixo:
char car;
car = toupper(`a`);
Após a execução destas linhas a variável car conterá o caractere `A`.
Exercício de Fixação
Faça um programa que leia quatro palavras pelo teclado, e armazene cada palavra em uma 
string. Depois, concatene todas as strings lidas numa única string. Por fim apresente esta como 
resultado ao final do programa. 
Exercícios Complementares 2
1. Fazer um programa em "C" que lê uma string qualquer de no máximo 80 caracteres e 
imprime:
a) Quantos caracteres tem o string;
b) Quantos caracteres são de pontuação;
c) Quantos caracteres são números;
d) Quantos caracteres são espaço em branco.
2. Fazer um programa em "C" que lê uma string contendo palavras separadas por um 
espaço em branco cada e as imprime uma abaixo das outras.
3. Fazer um programa em "C" que pergunta o nome, o endereço, o telefone e a idade de 
uma pessoa e monta um string com a seguinte frase:
"Seu nome é ..., você tem ... anos, mora na rua ... e seu telefone é ... ."
4. Fazer uma rotina que recebe uma string como parâmetro e imprime quantas palavras 
(separadas por espaços em branco) o mesmo contém.
5. Fazer uma rotina que aguarda (leia) uma string do teclado e retorna o valor 1 se a string 
digitada foi "SIM" e 0 se a string digitada foi "NAO". A rotina só deve retornar alguma coisa 
se a string digitada for "SIM" ou "NAO".
6. Implemente uma rotina que faça a mesma coisa que a função "strcpy". (essa foi feita em 
sala de aula...)
37
Programação de Computadores II Prof. Erlon Pinheiro
7. Fazer um programa em "C" que solicita um número inteiro e soletra o mesmo na tela.
Ex:
124: um, dois, quatro
8. Escrever uma função que recebe uma string e um caractere como parâmetro e remove 
todas as ocorrências do caractere da string.
9. Escreva uma função em "C" que receba uma string, um caractere e o índice de uma 
posição válida da string como parâmetro e insira o caractere na posição "empurrando" 
todos os demais para o lado.
10. Faça um programa que leia uma frase de no máximo 80 caracteres e imprima o número 
de vogais presentes na frase.
11. Escreva um programa que leia um texto (de no máximo 70 caracteres) e mostre na tela o 
mesmo texto, duplicando cada uma das letras deste texto. Exemplo: 
texto lido: INSTITUTO DE INFORMATICA 
texto devolvido: 
IINNSSTTIITTUUTTOO DDEE IINNFFOORRMMAATTIICCAA.
12. Faça um programa que leia uma string e o codifique, utilizando a tabela de substituição 
de caracteres abaixo. Imprima a string original e a string decodificada. 
CARACTERE EXISTENTE CARACTERE A SER SUBSTITUÍDO
M A
N E
P O
Q I
R U
A M
E N
O P
I Q
U R
13. Faça um programa que leia uma string e o decodifique, utilizando a tabela de 
substituição de caracteres do exercício anterior.
38
Programação de Computadores II Prof. Erlon Pinheiro
14. Implemente um módulo que faça a mesma coisa que a função "strcmp". 
(O algoritmo foi falado em sala)
15 . Faça um módulo que receba um string e retorne a mesma string toda em maiúsculo.
39
Programação de Computadores II Prof. Erlon Pinheiro
Unidade 3: Matrizes
3.1 – Introdução: Definições Iniciais
Já vimos como declarar matrizes unidimensionais (vetores). Vamos tratar agora de matrizes 
bidimensionais. A forma geral da declaração de uma matriz bidimensional é muito parecida 
com a declaração de um vetor: 
tipo_da_variável nome_da_variável [altura][largura];
É muito importante ressaltar que, nesta estrutura, o índice da esquerda indexa as linhas e o da 
direita indexa as colunas. Quando vamos preencher ou ler uma matriz no C o índice mais à 
direita varia mais rapidamente que o índice à esquerda. Mais uma vez é bom lembrar que, na 
linguagem C, os índices variam de zero ao valor declarado, menos um; mas o C não vai verificar 
isto para o usuário. Manter os índices na faixa permitida é tarefa do programador. Abaixo 
damos um exemplo do uso de uma matriz: 
#include <stdio.h>
#include <stdlib.h>
main ()
{
int mat [20][10];
int i,j,cont;
cont=1;
for (i=0;i<20;i++)
 for (j=0;j<10;j++)
 {
 mat[i][ j ]=cont;
 cont++;
 }
system(“pause”);
}
No exemplo acima, a matriz mat é preenchida, sequencialmente por linhas, com os números de 
1 a 200. Você deve entender o funcionamento do programa acima antes de prosseguir. 
3.2 - Matrizes de strings
Matrizes de stringssão matrizes bidimensionais. Imagine uma string. Ela é um vetor. Se 
fizermos um vetor de strings estaremos fazendo uma lista de vetores. Esta estrutura é uma 
matriz bidimensional de char s . Podemos ver a forma geral de uma matriz de strings como 
sendo: 
char nome_da_variável [num_de_strings][compr_das_strings];
Aí surge a pergunta: como acessar uma string individual? Fácil. É só usar apenas o primeiro 
índice. Então, para acessar uma determinada string faça: 
40
Programação de Computadores II Prof. Erlon Pinheiro
nome_da_variável [índice]
 Aqui está um exemplo de um programa que lê 5 strings e as exibe na tela: 
#include <stdio.h>
#include <stdlib.h>
main ()
{
 char strings [5][100];
 int cont;
 for (cont=0;cont<5;cont++)
 {
 printf ("\n\nDigite uma string: ");
 gets (strings[cont]);
 }
 printf ("\n\n\nAs strings que voce digitou foram:\n\n");
 for (cont=0;cont<5;cont++)
 printf ("%s\n",strings[cont]);
system(“pause”);
}
3.3 - Matrizes multidimensionais
O uso de matrizes multidimensionais na linguagem C é simples. Sua forma geral é: 
tipo_da_variável nome_da_variável [tam1][tam2] ... [tamN];
Uma matriz N-dimensional funciona basicamente como outros tipos de matrizes. Basta lembrar 
que o índice que varia mais rapidamente é o índice mais à direita. 
3.4 - Inicialização
Podemos inicializar matrizes, assim como podemos inicializar variáveis. A forma geral de uma 
matriz como inicialização é: 
tipo_da_variável nome_da_variável [tam1][tam2] ... [tamN] = {lista_de_valores};
A lista de valores é composta por valores (do mesmo tipo da variável) separados por vírgula. Os 
valores devem ser dados na ordem em que serão colocados na matriz. Abaixo vemos alguns 
exemplos de inicializações de matrizes: 
float vect [6] = { 1.3, 4.5, 2.7, 4.1, 0.0, 100.1 };
int matrx [3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
char str [10] = { 'J', 'o', 'a', 'o', '\0' };
char str [10] = "Joao";
char str_vect [3][10] = { "Joao", "Maria", "Jose" };
O primeiro demonstra inicialização de vetores. O segundo exemplo demonstra a inicialização de 
matrizes multidimensionais, onde matrx está sendo inicializada com 1, 2, 3 e 4 em sua primeira 
linha, 5, 6, 7 e 8 na segunda linha e 9, 10, 11 e 12 na última linha. No terceiro exemplo vemos 
41
Programação de Computadores II Prof. Erlon Pinheiro
como inicializar uma string e, no quarto exemplo, um modo mais compacto de inicializar uma 
string. O quinto exemplo combina as duas técnicas para inicializar um vetor de strings. Repare 
que devemos incluir o ; no final da inicialização. 
3.4.1 - Inicialização sem especificação de tamanho
Podemos, em alguns casos, inicializar matrizes das quais não sabemos o tamanho a priori. O 
compilador C vai, neste caso verificar o tamanho do que você declarou e considerar como sendo 
o tamanho da matriz. Isto ocorre na hora da compilação e não poderá mais ser mudado durante 
o programa, sendo muito útil, por exemplo, quando vamos inicializar uma string e não 
queremos contar quantos caracteres serão necessários. Alguns exemplos: 
 char mess [] = "Linguagem C: flexibilidade e poder.";
 int matrx [][2] = { 1,2,2,4,3,6,4,8,5,10 };
No primeiro exemplo, a string mess terá tamanho 36. Repare que o artifício para realizar a 
inicialização sem especificação de tamanho é não especificar o tamanho! No segundo exemplo o 
valor não especificado será 5. 
Obs: Note que o número de linhas pode ser omitido, mas o número de coluna não!
42
Programação de Computadores II Prof. Erlon Pinheiro
AUTO AVALIAÇÃO 
Veja como você está. O que imprime o programa a seguir? Tente entendê-lo e responder. A 
seguir, execute-o e comprove o resultado.
# include <stdio.h> 
# include <stdlib.h>
main() 
{ 
 int t, i, M[3][4]; 
 for (t=0; t<3; t++) 
 for (i=0; i<4; i++) 
 M[t][i] = (t*4)+i+1; 
 for (t=0; t<3; t++) 
 { 
 for (i=0; i<4; i++) 
 printf (“%3d “, M[t][i]); 
 printf (“\n”); 
 } 
 system(“pause”); 
}
3.5 – Passagem de Matrizes para Funções
Após a declaração de uma matriz, a variável que representa a matriz é um ponteiro para o 
primeiro “vetor-linha” da matriz.
Com isto, mat[1] aponta para o primeiro elemento do segundo “vetor-linha”, e assim por 
diante.
Assim, uma matriz criada estaticamente é representada por um ponteiro para um “vetor-linha” 
com o número de elementos da linha. Quando passamos uma matriz para uma função, o 
parâmetro da função deve ser deste tipo. Infelizmente, a sintaxe para representar este tipo é 
obscura. O protótipo de uma função que recebe a matriz declarada acima seria:
void f (..., float (*mat)[3], ...);
Para uma matriz com 3 colunas
Uma segunda opção é declarar o parâmetro como matriz, podendo omitir o número de linhas:
void f (..., float mat[][3], ...);
Ou ainda uma terceira opção seria declarar o parâmetro com o tamanho específico da matriz:
void f (..., float mat[4][3], ...);
De qualquer forma, o acesso aos elementos da matriz dentro da função é feito da forma usual, 
com indexação dupla.
3.6 – Tipos Básicos de Matrizes
Matrizes Quadradas – São matrizes que possuem a quantidade de linhas igual a quantidade de 
colunas, formando um quadrado.
43
Programação de Computadores II Prof. Erlon Pinheiro
Devido a essa propriedade essas matrizes apresentam características únicas comparadas às 
outras matrizes.
Matriz Diagonal: elementos que podem ser diferentes de zero estão dispostos nas posições 
ocupadas por uma linha imaginária que corta a matriz na sua diagonal, do canto superior 
esquerdo ao canto inferior direito, o resto da matriz só pode conter zeros.
Os elementos que ocupam essas posições possuem o número da sua linha igual ao número da 
sua coluna, sendo possível identificá-los em um trecho de programa através do comando de 
seleção:
if (linha == coluna)
Matriz Triangular Superior: Os elementos que estão dispostos nas posições ocupadas abaixo 
da diagonal principal devem (obrigatoriamente) ser iguais a zero, o resto da matriz pode ser 
não nula. 
Os elementos que ocupam essas posições possuem o número da sua linha menor que o número 
da coluna, sendo possível identificá-los em um trecho de programa através do comando:
if (linha < coluna)
Matriz Triangular Inferior: elementos que estão dispostos nas posições ocupadas abaixo da 
diagonal principal podem ser diferentes de zero.
Os elementos que ocupam essas posições possuem o número da sua linha maior que o número 
da coluna, sendo possível identificá-los em um trecho de programa através do comando:
if (linha > coluna)
44
9
-1
-1
0
0 0 0
0 0 0
0
0 0
0
0
0
9 1 1
00 1
00
0 0
0
0 8
4
3
9 1 1
00
0
00
0 0
0
0 0
4
31
9
Programação de Computadores II Prof. Erlon Pinheiro
Matriz Diagonal Secundária: elementos que estão dispostos nas posições ocupadas por uma 
linha imaginária que corta a matriz na sua diagonal, do canto superior direito ao canto inferior 
esquerdo podem ser diferentes de zero, o resto da matriz só pode conter zeros. 
Os elementos que ocupam essas posições possuem o número da sua linha somado ao de sua 
coluna igual à dimensão de colunas menos uma unidade (lembre-se, em C a contagem inicia-se 
do zero), sendo possível identificálos em um trecho de programa (em C) através do comando:
if (linha + coluna == qtde_colunas-1)
No caso de matriz 4x4 do exemplo acima:
if (linha + coluna == 3)
Se essa condição for verdadeira, esse elemento estará na diagonal secundária.
Exercícios Complementares 3
1. Escreva um programa em C que preencha uma matriz 4X4 com "0" e a sua diagonal 
principal com "1“. Em seguida, exiba a matriz na tela (uma linha da matriz por vez).
Resolução:
#include<stdio.h>
#include<stdlib.h>
const int

Outros materiais