Buscar

Programação Estruturada Unisc 2017

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 106 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 106 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 106 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

DEPARTAMENTO DE INFORMÁTICA 
 
 
 
 
 
 
 
 
Programação 
Estruturada 
 
 
Notas de aula 
 
Profa. Beatriz Lux 
Prof. Rolf Fredi Molz 
 
Atualizada em fevereiro 2017 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
1 
 
 
 Sumário 
 
 
2.0 Bibliografia recomendada 
 
2 
 
3.0 Conceitos Gerais 
 
3 
 
4.0 Comandos de controle de fluxo 
 
17 
 
5.0 Tipo Ponteiro 
 
24 
 
6.0 Modularização 
 
33 
 
7.0 Tipo estruturado homogêneo - matrizes 
 
47 
 
8.0 Strings em C 
 
57 
 
9.0 Tipo estruturado heterogêneo - registros 
 
62 
 
10.0 Métodos internos de ordenação 
 
70 
 
11.0 Métodos internos de pesquisa 
 
77 
 
12.0 Recursividade 
 
79 
 
13.0 Operações em meio magnético - arquivos 
 
82 
 
14.0 Estruturas e alocação dinâmica de memória – exemplo com 
Lista Encadeada 
 
94 
 
15.0 Anexo – Como adicionar um arquivo Header a um projeto 
 
16.0 Anexo – Tabela ascii 
 
99 
 
 101 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
2 
 
2.0 Bibliografia Recomendada 
 
Recomenda-se ao aluno não basear seu estudo apenas no conteúdo destas notas 
de aula, sendo importante que busque mais informações através da leitura de livros 
dedicados ao estudo de programação estruturada e da linguagem C. Abaixo cita-
mos alguns títulos que consideramos apropriados e que nortearam a produção des-
tas notas de aula. Ambos podem ser encontrados na nossa biblioteca: 
 
SCHILDT, Herbert. C : completo e total. 3. ed., rev. e atual. São Paulo: Makron, 
c1997. 
 
MIZRAHI, Victorine Viviane. Treinamento em linguagem C. Volume 1. São 
Paulo: Makron, 1990. 
 
MIZRAHI, Victorine Viviane. Treinamento em linguagem C. Volume 2. São 
Paulo: Makron, 1990. 
 
ZIVIANI, Nivio. Projeto de algoritmos com implementações em Pascal e C. São 
Paulo: Pioneira, 1999. 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
3 
 
3.0 Conceitos Gerais 
 
3.1 Objetivos e Caracterização da Linguagem 
 
A linguagem de programação C foi criada por Dennis Richtie,no início da década 
de 70, nos laboratórios Bell para ser usada na implementação de sistemas opera-
cionais (UNIX) e outras tarefas de programação de baixo nível. 
A linguagem era fornecida junto com o UNIX e manteve sua sintaxe padrão inalte-
rada por cerca de dez anos. A principal documentação deste padrão encontra-se 
na publicação "The C Programming Language", de Brian Kernighan e Dennis 
Ritchie (K&R), tida como a "bíblia da linguagem C". 
Em 1985, ANSI (American National Standards Institute) estabeleceu um padrão 
oficial de C, o chamado "C ANSI". Um dos objetivos do processo de padronização 
C ANSI foi o de produzir um sobreconjunto do C K&R, incorporando muitas das 
características não-oficiais subseqüentemente introduzidas. 
C caracteriza-se por ser uma linguagem estruturada, pois possibilita dividir a infor-
mação em blocos estanques, o que é feito através de subprogramas (funções), que 
são os blocos fundamentais de um programa em C. Desta maneira, determinada 
tarefa pode ser definida e escrita em separado, numa função, utilizando suas pró-
prias variáveis (chamadas locais) de cuja existência, não precisará tomar conheci-
mento o resto do programa ou os demais subprogramas. Este conceito é um dos 
tópicos que estudaremos com profundidade em nossa disciplina. 
 
Outra característica de C é sua portabilidade, ou seja, um código escrito em 
linguagem C poderá ser executado em diferentes máquinas, independentemente 
da sua configuração física e do sistema operacional residente, sendo apenas 
necessário sua re-compilação para cada arquitetura diferente 
A Linguagem C tornou-se ao longo do tempo uma das linguagens de programação 
mais usadas, pois, afora as qualidades acima citadas, possibilita produzir códigos 
concisos e de rápido processamento por ser uma linguagem de nível médio, onde 
estão combinados elementos de linguagens de alto nível e as funcionalidades de 
assembly. Foi utilizada na criação e desenvolvimento de softwares e sistemas ope-
racionais que se tornaram famosos em todo mundo, como por exemplo o Sistema 
Operacional Windows. 
 
 
 
3.2 Elementos Básicos da Linguagem 
 
3.1 Símbolos usados 
 
 Letras de A a Z tanto maiúsculas como minúsculas. 
 
 O símbolo _ (caracter de sublinha) é considerado letra. 
 
 Digitos de 0 a 9. 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
4 
 
 
 Especiais + - * / = ^ # & , : ; ‘ $ e outros 
 
 Símbolos especiais usados em conjunto: 
 = atribuição 
 != diferente 
 <= menor ou igual 
 >= maior ou igual 
 { } delimitadores de inicio e fim de um bloco de comandos 
 /* inicio de comentário 
 */ fim de comentário 
// inicio de comentário de aoenas 1 linha (não é necessário fechá-lo) 
 
 O tamanho máximo de uma linha é de 127 caracteres. 
 
 
3.2 Tipos Básicos de Dados 
 
Todas as vaiáveis em C possuem um identificador (nome) e um tipo, que especifica 
os valores que a variável poderá assumir. A tabela 1 apresenta o s cinco tipos bá-
sicos, o número de bits que cada um utiliza e a faixa e valores que alcança. 
 
Tipo Bits Faixa de valores 
char 8 -128 à 127 
int 16 -32768 à 32767 
float 32 -3.4E-38 à 3.4E+38 
double 64 -1.7E-308 à 1.7E+308 
void 0 Sem valor 
Tabela 1 
 
 
3.3 Identificadores 
Os identificadores, que servem para nomear programas, variáveis, constantes, pro-
cedimentos, etc., seguem a seguinte regra: 
 
Devem iniciar por uma letra e a esta podem seguir letras, números ou sinal 
de sublinha. Não pode conter espaços. Tamanho: até 127 caracteres, sendo 
significativos os 32 primeiros. Obs.: atentar para as palavras reservadas 
da linguagem que não podem ser usadas. 
 
Em C os primeiros 32 caracteres de um nome de identificador são significan-
tes. Isso quer dizer que duas variáveis com os 32 primeiros caracteres em 
comum, diferindo somente no 33º , são consideradas iguais. 
A linguagem C é case-sensitive , o que significa que letras maiúsculas e mi-
núsculas são tratadas como diferentes umas das outras. Por isso, media, Me-
dia e MEDia são distintos. 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
5 
 
3.4 Palavras reservadas da linguagem 
A tabela 2 apresenta as palavras reservadas da linguagem C, que não poderão ser 
utilizadas como identificadores. 
 
auto double if static 
break else int struct 
case entry long switch 
char extern register typedef 
continue float return union 
default for sizeof unsigned 
do goto short while 
Tabela 2 
 
 
3.5 Estrutura básica de um Programa em C 
 
Os programas em C são formados por uma ou mais funções, porém sempre haverá 
uma (e só uma) função denominada main, onde a execução do programa neces-
sariamente irá começar. Além da main poderá haver outras funções, dependendo 
apenas de como o programador dividir as tarefas que seu programa deverá realizar. 
 
Exemplo de um programa simples em C: 
 
#include<stdio.h> //inclusão de biblioteca 
#include<math.h> //inclusão de biblioteca 
#define v 3.0 // definição de contante 
int main() 
{ float a,r,q; // declaração de variáveis 
 printf("Informe um real\n"); //apresentação de dados na tela 
 scanf("%f",&a); //entrada de dados via teclado 
 printf("O no.lido foi: %.2f\n", a); 
 r=sqrt(a); 
 printf("raiz quadrada de %.2f: %.2f\n",a,r); 
 q=pow(a,2); 
 printf("%.2f ao quadrado: %.2f\n",a,q); 
 printf("%.2f ao quadrado: %.2f",v,pow(v,2)); 
 return 0; //retorno da função main 
} 
 
Tela de entrada e saída do programa quando executado (F9): 
 
 
3.5.1 Diretiva #include 
Toda a diretiva, em C, começa com o símbolo # no início da linha. 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
6 
 
A diretiva #include inclui o conteúdo de um outro arquivo dentro do programa 
atual, ou seja, a linha que contêm a diretiva é substituída pelo conteúdo do ar-
quivo especificado. 
No programa exemplo acima necessitamos incluir alguns arquivos que contêm a 
declaração de funções de bibliotecas padrão. As bibliotecas, normalmente, pos-
suem a extensão .h e se encontram em algum diretório pré-definido pelo compila-
dor. Sempre que o programa utilizar alguma função da biblioteca-padrão deve ser 
incluído o arquivo correspondente. 
Apresenta-se a seguir alguns dos principais .h da linguagem C: Descrição 
stdio.h - Funções de entrada e saída (I/O) 
string.h - Funções de tratamento de strings 
math.h - Funções matemáticas 
ctype.h - Funções de teste e tratamento de caracteres 
stdlib.h - Funções de uso genérico 
É importante saber que cada diretiva deve estar em sua própria linha. 
 
3.5.2 – Definição de Constantes 
O conceito de constantes em linguagens de programação é atribuir um certo valor 
constante (que não pode ser alterado) a um nome, e quando este nome for refe-
renciado dentro do código do programa, será utilizado nas operações o valor atri-
buído a este nome. 
Uma das formas de definirmos constantes em C é utilizar a diretiva #define que 
é conhecida como diretiva de macro-substituição. 
 
Conforme o tipo da constante, será sua representação: 
 
 Constantes de caractere são envolvidas por aspas simples (‘’); 
 Ex; ‘a’ 
 Constantes formadas por cadeia de caracteres são envolvidas por aspas du-
plas; 
Ex: “Tecle algo para sair do programa” 
 Constantes com valor inteiro são representadas por um número inteiro; 
Ex: 10, -100 
 Constantes com valor real (float) devem apresentar o ponto decimal seguido 
da parte fracionária do número; 
Ex: 19.55 
 
# define nome “João” 
# define pi 3.1416 
# define letra ´a´ 
 
O compilador substitui o identificador pelo valor cada vez que aquele for encontrado 
no programa fonte antes da compilação do programa. 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
7 
 
É recomendável o uso de identificadores como sinônimos de constantes pois au-
menta a legibilidade do programa e auxilia sua documentação, além disto, o agru-
pamento das constantes no início do programa torna mais fácil a sua modificação, 
caso necessário. 
 
3.5.3 Comentários 
É bastante útil e indicado colocar comentários nos códigos de programas para fa-
cilitar sua leitura e elucidar seu objetivo e funcionamento . 
 
Utiliza-se caracteres especiais para indicar comentários: 
 comentários de uma linha podem ser iniciados com duas barras ( // ) 
 comentários de mais de uma linha iniciam com uma sequencia dos carac-
teres barra asterisco ( /* ) e encerrados com asterisco barra ( */ ) 
 
 
3.5.4 Declaração e variáveis 
Todas as variáveis de um programa deverão ser declaradas. 
Para declarar uma variável devemos identificador inicialmente seu tipo, a seguir 
o nome da variável e encerrar a declaração com ponto e vírgula. 
 
float raio; 
int idade; 
 
Se tivermos mais de uma variável com o mesmo tipo, podem ser declaradas na 
mesma linha, separadas por vírgula. 
float raio, área; 
 
As variáveis são classificadas em variáveis locais e globais. 
Variáveis globais são aquelas declaradas fora do escopo das funções. 
Variáveis locais são aquelas declaradas no início de um bloco e seus escopos 
estão restritos aos blocos em que foram declaradas. A tabela 2 exemplifica as duas 
formas de declaração, local e global. 
 
#include<stdio.h> 
#include<math.h> 
#define v 3.0 
float a,r,q; 
 
int main() 
{ 
printf("Informe um real\n"); 
scanf("%f",&a); 
printf("O no.lido foi: %.2f\n ", 
a); 
r=sqrt(a); 
printf("raiz quadrada de %.2f: 
%.2f\n", a,r); 
 return 0; 
} 
#include<stdio.h> 
#include<math.h> 
#define v 3.0 
 
 
int main() 
{float a,r,q; 
printf("Informe um real\n"); 
scanf("%f",&a); 
printf("O no.lido foi: %.2f\n ", 
a); 
r=sqrt(a); 
printf("raiz quadrada de %.2f: 
%.2f\n", a,r); 
 return 0; 
} 
 
Exemplo variável global Exemplo variável local 
Tabela 2 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
8 
 
 
Observações: 
 É uma prática tradicional do C, usar letras minúsculas para nomes de 
variáveis e maiúsculas para nomes de constantes. Isto facilita na hora 
da leitura do código; 
 Quando se escreve código usando nomes de variáveis em português, 
evita-se possíveis conflitos com nomes de rotinas encontrados nas di-
versas bibliotecas, que são em sua maioria absoluta, palavras em in-
glês. 
 
 
3.5.4 A função principal 
 
A linha int main() indica que estamos definindo uma função de nome main. To-
dos os programas em C devem ter uma função main, pois é esta função que será 
chamada quando o programa for executado. 
 
O conteúdo da função é delimitado por chaves { }, obrigatoriamente. 
Isso significa que { (abre chaves) substitui a palavra inicio que utilizamos em algo-
ritmos e } (fecha chaves) substitui a palavra fim. 
O código que estiver dentro das chaves será executado seqüencialmente quando 
a função for chamada. 
 
Em C, sempre que necessitarmos delimitar um bloco de comandos que deve ser 
executado sequencialmente, utilizamos as chaves, isto se tornará novamente re-
levante quando estudarmos o uso dos comando condicionais e de repetição. 
 
 
3.5.5 O uso do ponto e vírgula 
 
É importante notar no exemplo que todas as linhas de comando são separadas 
por ponto e vírgula, exceto as declarações #include, #define, o cabeçalho da fun-
ção e os demarcadores de blocos (chaves) de instruções. 
Durante a compilação do programa, o ponto-e-vírgula mostra ao compilador quando 
uma linha de comando termina e quando outra linha de comando se inicia. 
Assim, o compilador acusará um erro sempre que verificar a falta de um ponto-e-
vírgula, pois ele não saberá quando termina ou começa um determinado comando 
dentro do código digitado. 
 
3.5.6 Operador de atribuição 
O operador “=” atribui um valor ou resultado de uma expressão contida a sua direita 
para a variável (ou constante) especificada a sua esquerda. 
Exemplos: 
a=V*2; 
b=c*valor+sqrt(x); 
 
É possível fazer atribuição sucessiva de valores: a=b=c=1; 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
9 
 
É possível atribuir um valor a uma variável ao mesmo tempo em que ela é decla-
rada. 
int a=5,b=2; 
float r=8.6; 
 
 
3.5.7 Expressões, Operadores e funções aritméticas 
 
 Expressões são algoritmos especificados para a computação de valores, consis-
tem em operações com variáveis, constantes e funções combinadas com opera-
dores. 
 a=v*2; c=a+b; c=a/d; 
 
3.5.7.1 Operadores Aritméticos 
Veja na tabela 3 os operadores aritméticos 
 
Operador Ação 
+ Soma (inteira e ponto flutuante) 
- Subtração ou Troca de sinal (inteira e ponto flutuante) 
* Multiplicação (inteira e ponto flutuante) 
/ Divisão (inteira e ponto flutuante) 
% Resto de divisão (de inteiros) 
-- Decremento 
++ Incremento 
Tabela 3O operador / (divisão) 
 quando aplicado a variáveis inteiras, fornece o resultado da divisão inteira; 
 quando aplicado a variáveis em ponto flutuante fornece o resultado da divi-
são "real". 
O operador % fornece o resto da divisão inteira entre dois inteiros. 
 Exemplo: 
 int a ,b, x, y; 
 float z , z1, z2; 
 { a=17; 
b=3; 
z=17.0 
 x = a / b; 
 y = a % b; 
 z1 = z / b; 
 z2 = a/b; 
 } 
ao final da execução destas linhas, os valores calculados seriam 
 x = 5 y = 2 z1 = 5.666666 z2 = 5.0 . 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
10 
 
Note que, na linha correspondente a z2, primeiramente é feita uma divisão inteira 
(pois os dois operandos são inteiros). Somente após efetuada a divisão é que o 
resultado é atribuído a uma variável float. 
 
3.5.7.2- Funções Aritméticas Pré-Definidas 
 
São funções implementadas na biblioteca math.h. 
Na tabela 4 são apresentadas algumas funções matemáticas em C 
 
resultado função tipo do pa-
râmetro 
tipo do re-
sultado 
Logaritmo neperiano log(x) real real 
Logaritmo base 10 log10(x) 
 
real real 
e elevado à potencia x exp(x) real real 
Valor absoluto de x fabs(x) real real 
abs(x) int int 
Decompõe um real x em duas partes: 
y recebe a parte inteira e a função devolve 
a parte fracionária, ambas como real (dou-
ble) 
 
modf(x,y) real, real real 
Arredonda o valor de x para cima ceil (x) real real 
Arredonda o valor de x para baixo floor(x) real real 
Retorna x elevado a potência y pow(x,y) real real 
Raiz quadrada de x sqrt(x ) real real 
Retorna o resto da divisão de x por y 
Ex: fmod (25.55 , 2) = 1.55 
fmod(x,y) real, real real 
Seno de x sin(x ) real real 
Cosseno de x cos( x) real real 
Arco-tangente de x atan( x) real real 
Tabela 4 
 
A ativação da função no programa é feita através do identificador, nome da função 
e da lista de argumentos (parâmetros), entre parênteses e separados por vírgula.
 
Obs. : x é o argumento da função, pode ser uma expressão aritmética. 
 
 
 
3.5.7.3 Operadores Relacionais 
 
Uma relação é uma comparação realizada entre valores do mesmo tipo. Estes va-
lores são representados na relação por constantes, variáveis ou expressões. O re-
sultado será sempre True ou False. A natureza da relação é indicada por um ope-
rador relacional, descrito na tabela 5. 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
11 
 
 
 
Operador Ação 
> Maior do que 
>= Maior ou igual a 
< Menor do que 
<= Menor ou igual a 
== Igual a 
!= Diferente de 
Tabela 5 
 
 
3.5.7.4 Operador ternário 
 
Em C podemos expressar relações de uma forma bastante compacta, através do 
uso do operador ternário, que serve para substitui o comando if-else. 
 
Como exemplo, na coluna 1 da tabela 6 é apresentada uma construção condicional 
com o comando if–else e na coluna 2 a sua correspondente com comando ternário. 
 
If (n1>n2) 
 maior= n1 
else 
 maior=n2 
maior=(n1>n2) ? n1 : n2 
Tabela 6 
 
Fica definido na construção que aparece na segunda coluna que haverá uma ava-
liação da expressão lógica e que se resultar verdadeira deverá ser atribuido o valor 
de n1 à variavel maior, se resultar falsa, a variável maior receberá o valor de n2. 
 
Forma geral do operador ternário: 
 
 condição ? expressão_1 : expressão_2 
 
 
 
3.5.7.5 Operadores Lógicos 
Os operadores lógicos em C são descritos na tabela 7 
 
 
Operador Ação 
&& E 
|| OU 
! NÃO 
Tabela 7 
 
 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
12 
 
 
3.5.7.6 Operadores de Atribuição Composta 
 
Em C qualquer expressão da forma: 
 
 variável = variável operador expressão 
 
pode ser escrita como: 
 variável operador = expressão 
 
 
Exemplos: 
raiz = raiz * 4; raiz *= 4; 
ano = ano + 10; ano += 10; 
soma = soma / ( a + b); soma /= (a + b); 
i = i % 2; i %= 2; 
 
A tabela 8 mostra que diferentes posicionamentos dos operadores resultados origi-
nam diferentes resultados. 
 
x=10; 
y=++x; y recebe 11 e x recebe 11 
x=10; 
y=x++; y recebe 10 e x recebe 11 
 
int a,b,c,i=3; a:? b:? c:? i:3 
a=i++; a:3 b:? c:? i:4 
b=++i; a:3 b:5 c:? i:5 
c=--i; a:3 b:5 c:4 i:4 
Tabela 8 
 
 
3.5.7.7 Conversão entre tipos de variáveis - type casting 
 
O C permite a mudança de tipo das suas variáveis através do operador (cast), onde 
cast é o novo tipo pretendido. 
O casting pode ser usado com qualquer um dos tipos simples. 
Exemplo: 
 
int k; 
char ch = 'A'; 
k = (int) ch; 
 
Aqui o valor de k será 65 (o código ascii do carácter 'A'). 
 
Um uso freqüente do casting é assegurar que a divisão entre inteiros não seja uma 
divisão inteira. Basta para isso converter para real o numerador ou denominador. 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
13 
 
O outro operando é assim também automaticamente convertido, antes de se efe-
tuar a operação. 
 
 
3.5.7.8 Operador unário sizeof() 
 
O operador sizeof()retorna o tamanho em bytes da expressão ou tipo fornecido 
entre parênteses Por exemplo, suponha que o tipo float tenha quatro bytes então 
o operador sizeof(float) retorna o valor 4. 
 
 
 
3.6 Funções de entrada e saída de dados 
 
3.6.1 Função de saída de dados formatada 
 
Forma Geral: 
printf (“expressão de controle”, lista de argumentos); 
 
Esta função permite escrever na tela e é um comando da biblioteca stdio.h 
A expressão de controle pode conter caracteres que serão exibidos na tela e os 
códigos de formatação (ou controle) que indicam o formato em que os argumentos 
deverão ser impressos. 
Cada argumento deve ser separado por vírgula. Os códigos de controle usam a 
notação % para formatar variáveis e \ para formatar a disposição na tela (quebra 
de linha, tabulação, etc). Para cada formatação de variável na expressão de con-
trole deve haver uma variável na lista de argumentos. 
Exemplo: 
printf("O MDC entre %d e %d eh: %d\n",m,n,x); 
 
A tabela 9 apresenta códigos de controle para formatar variáveis: 
 
 
Código Significado 
%d inteiro 
%f float 
%lf double 
%c 1 caractere 
%s String 
%p ponteiro 
%% Coloca na tela um % 
Tabela 9 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
14 
 
A tabela 10 apresenta os códigos de controle para disposição na tela 
 
Código Significado 
\b Retrocesso ("back") 
\f Alimentação de formulário ("form feed") 
\n Nova linha ("new line") 
\t Tabulação horizontal ("tab") 
\" Aspas 
\' Apóstrofo 
\0 Nulo (0 em decimal) 
\\ Barra invertida 
\v Tabulação vertical 
\a Sinal sonoro ("beep") 
\N Constante octal (N é o valor da constante) 
\xN Constante hexadecimal (N é o valor da constante) 
Tabela 10 
Na lista de argumentos pode haver variáveis e/ou constantes, sempre separadas 
por vírgula, veja o exemplo do trecho de programa abaixo: 
int p 
p= 65487 * 236597 ; 
printf("O Produto entre %d e %d eh: %d\n",65487, 236597 ,p); 
 
A função printf(): 
 Imprime a partir do último caracter impresso.• 
 Não muda de linha até que a linha acabe ou que encontre um \n. 
 
Alguns exemplos de printf() e o que eles exibem: 
printf ("Teste %% %%") -> "Teste % %" 
printf ("%f",40.345) -> "40.345" 
printf ("Um caractere %c e um inteiro %d",'D',120) -> "Um carac-
tere D e um inteiro 120" 
printf ("%s e um exemplo","Este")-> "Este e um exemplo" 
printf ("%s%d%%","Juros de ",10) -> "Juros de 10%" 
 
Ao apresentar na tela valores com ponto flutuante, estes serão colocados em nota-
ção científica. Se quisermos apresentar os valores com casas decimais é necessá-
rio acrescentar um formato, como no exemplo abaixo: 
 
#include <stdio.h> 
#define V 3 
int a; 
float b; 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
15 
 
int main() 
{ a=V*2; 
 b=sqrt(a); 
 printf(" %d %5.2f ",a,b); 
 return 0; 
 } 
 
Através desta especificação de formato ( printf(" %d %5.2f ",a,b), o valor de b será 
escrito com 5 caracteres no total (incluindo o ponto da casa decimal) e duas ca-
sas depois do ponto decimal. 
A tabela 11 apresenta mais exemplos: 
 
Código Descrição 
%6f Ponto flutuante com pelo menos seis caracteres 
%.2f Ponto flutuante com dois caracteres após o ponto decimal 
%6.2f Ponto flutuante com pelo menos seis caracteres e dois após o ponto 
decimal 
%6d Inteiro com pelo menos seis caracteres 
Tabela 11 
 
 
3.6.2 Função de entrada de dados formatada 
 
Permitem ler dados pelo teclado. Sua sintaxe é semelhante ao printf: 
Forma Geral : scanf(“expressão de controle”, lista de argumentos); 
 
A expressão de controle pode conter códigos de formatação, precedidos por %. 
 
A lista de argumentos: 
 Depende da String de Formato. 
 Separados por ‘,’. 
 Sempre variáveis. 
 As variáveis devem ser precedidas por ‘&’ 
 
Exemplo: 
int mat; 
float media; 
int main () 
{ printf(“Entre com a matrícula do aluno e sua media: "); 
 scanf(“%d %f“, &mat, &media); 
-------; 
--------; 
} 
 %f indica que será lido um valor do tipo float, atribuído a uma variável na 
sequencia indicada na lista de argumentos (&media). 
 A lista de argumentos consiste então no endereço das variáveis. 
 C oferece um operador para tipos básicos chamado operador de endereço 
&, que retorna o endereço do operando. 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
16 
 
Exemplo para o operador de endereços: 
 
int main() 
 { 
 int num; 
 num = 2; 
 printf (“Valor %d, endereço = %u”, num, &num); 
 return 0; 
 } 
 
O programa acima imprime o valor e o endereço de memória da variável num. 
%u é usado pois endereço é visto como inteiro sem sinal. 
Ex. de saída: Valor=2, endereço = 1370 
 
 
3.6.3 Funções de Entrada e Saída de dados para caracteres 
 
3.6.3.1 Funções de Entrada e Saída para caracteres (com enter) 
 
getchar() 
Biblioteca: stdio.h 
Declaração: int getchar(void); 
Propósito: A função getchar() (get character) lê um caracter individual da entrada 
padrão (em geral, o teclado). 
Esta função é dita line buffered, isto é, não retorna valores até que o caracter de 
controle line feed (\n) seja lido. Este caracter, normalmente, é enviado pelo teclado 
quando a tecla [enter] é pressionada. Se forem digitados vários caracteres, estes 
ficarão armazenados no buffer de entrada até que a tecla [enter] seja pressionada. 
Então, cada chamada da função getchar() lerá um caracter armazenado no buffer. 
 
 
putchar() 
Biblioteca: stdio.h 
Declaração: int putchar(int c); 
Propósito: Esta função putchar() (put character) imprime um caracter individual c 
na saída padrão (em geral o monitor de vídeo). 
 
 getchar retorna inteiro mas é possível atribuir a uma variável char (o que 
geralmente é feito). 
 putchar é declarada para entrada de inteiro mas geralmente é usada com 
um argumento caracter. 
 
 
3.6.3.2 Funções de Entrada e Saída para caracteres (sem enter) 
getch(), getche() 
 
Alguns compiladores nào comportam estas funções 
 
Declaração: int getch(void); 
 int getche(void); 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
17 
 
Ao ser executada, a função getch() (get character) aguarda que uma tecla (ou com-
binação de teclas) seja pressionada, recebe do teclado o código correspondente e 
retorna este valor. 
 
A função getche() (get character and echoe) tem o mesmo funcionamento porém 
escreve na tela, quando possível, o caracter correspondente. 
 
 
Exemplo 
// Uso das funcoes getchar() e putchar() 
#include <stdio.h> 
char c; 
void main(void) 
{ 
 printf("\nDigite uma frase:\n"); 
 do 
 { 
 c = getchar(); // leitura do 'buffer' 
 if(c >= 97 && c <= 122) // se c e' minúsculo... 
 { 
 c -= 32; // c=c-32 transforma em maiúsculo 
 } 
 putchar(c); // impressao dos caracteres maiúsculos 
 }while (c != '\n'); // ...enquanto nao e' [enter] 
 
} 
 
 
4.0 Comandos de controle de fluxo 
 
4.1 Comandos Condicionais 
Um comando condicional é usado para selecionar um único comando de seus com-
ponentes para a execução. 
 
4.1.1 Comando if- else 
O comando IF especifica que um comando deve ser executado somente se o re-
sultado de uma expressão lógica for verdadeira. Se for falsa, então outro comando 
deve ser executado, ou nenhum comando da sua estrutura deve ser executado. 
 
Formas do comando: 
 
A) if (condição) 
 comando ; 
 
Nesta forma, o comando somente será executado se a condição for TRUE. Caso 
contrário, se a condição for FALSE, nenhuma ação será realizada. 
O comando a ser executado pode ser simples ou composto. 
Um comando será simples quando for apenas uma linha de instrução (seguida de 
ponto e vírgula) e será composto quando houver mais de uma linha de instrução, 
originando um bloco que deverá ser delimitado por chaves 
 
 Ex: if (a = = b ) 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
18 
 
 { 
 x = 1.5 ; 
 y = 2.5 ; 
 } 
 
 
B) if (condição) 
 comando 1; (ou bloco) 
 else 
 comando 2; (ou bloco) 
 
Neste caso, se a condição for verdadeira será executado o comando 1 e caso for 
falsa será executado o comando 2. Tanto o comando 1 como o comando 2 po-
dem ser simples ou compostos. 
 
 
 
Exemplos: 
If (a = = b) 
 x = 1.5; 
else 
 x = 2.5 ; 
 
 
if (a == 
b) 
{ x = 
1.5; 
 x := 1.5 ; 
 y = 2.5 ; 
 
else 
{ x = -1.5 ; 
 y = -2.5 ; 
} 
 
 
Exemplo: Faça um programa que leia um número e informe se é igual a 10, maior 
ou menor que 10. 
#include <stdio.h> 
int num; 
void main (void) 
{ printf ("Digite um numero: "); 
 scanf ("%d",&num); 
 if (num==10) 
 { 
 printf ("\n\nVoce acertou!\n"); 
 printf ("O numero e igual a 10.\n"); 
 } 
 else 
 if (num>10) 
 printf ("O numero e maior que 10."); 
 else 
 printf ("O numero e menor que 10."); 
 } 
 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
19 
 
4.1.2 Comando condicional switch 
O comando switch é próprio para testar uma variável em relação a diversos valo-
res pré-estabelecidos. É básicamente usado na implementação de menus. 
Sua forma geral é: 
 
switch (variável) 
{ 
case constante_1: declaração_1; 
 break; 
case constante_2: declaração_2; 
 break; 
case constante_n: declaração_n; 
 break; 
default declaração_default; 
} 
A estrutura switch não aceitacondições, apenas constantes. O switch testa 
a variável e executa a declaração cujo case corresponda ao valor atual da variável. 
A declaração default é opcional e será executada apenas se a variável, que está 
sendo testada, não for igual a nenhuma das constantes. Não há necessidade de 
chaves envolvendo as instruções de cada case, pois estas instruções não são con-
sideradas um bloco, mas deve haver um conjunto de chaves envolvendo todo o 
corpo de cases, incluindo default. 
O comando break, faz com que o switch seja interrompido assim que uma 
das declarações seja executada. Mas ele não é essencial ao comando switch. Se 
após a execução da declaração não houver um break, o programa continuará exe-
cutando os cases do switch, na ordem seqüencial, até o fim do switch. 
Exemplo: Faça um programa que leia um número e informe se é igual ou diferente 
de 9, 10 e 11 . 
 
#include <stdio.h> 
int num; 
int main (void) 
{ printf ("Digite um numero: "); 
 scanf ("%d",&num); 
 switch (num) 
 { 
 case 9: 
 printf ("\n\nO numero e igual a 9.\n"); 
 break; 
 case 10: 
 printf ("\n\nO numero e igual a 10.\n"); 
 break; 
 case 11: 
 printf ("\n\nO numero e igual a 11.\n"); 
 break; 
 default: 
 printf ("\n\nO numero não e nem 9 nem 10 nem 
11.\n"); 
 } 
} 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
20 
 
4.2 Comandos de Repetição 
 
4.2.1 Comando for 
Forma geral: 
for (inicialização;teste;incremento) 
 comando ou bloco; 
 
Havendo um bloco de comandos, este deverá ser envolvido por chaves. 
 
O comando for é uma instrução de múltiplos usos, não precisando essas três partes 
separadas pelo operador ; (ponto-e-vírgula). O que deve ser sempre lembrado é a 
interpretação da condição de teste. Tal deve ser pensada com a seguinte frase: 
“faça o laço enquanto o teste for verdadeiro”. 
 
Exemplo 1: Faça um programa que imprima os 100 primeiros números naturais, 
exceto o zero 
 
#include <stdio.h> 
int n; 
int main () 
{ 
 for (n=1; n<=100; n++) 
 printf ("%d ",n); 
 return 0; 
} 
 
Exemplo 2: Faça um programa que imprima os primeiros 20 números pares. 
 
#include <stdio.h> 
int main () 
{ 
 int n=2; 
 for (; n<=40; n+=2) 
 printf ("%d ",n); 
} 
 
No exemplo acima, a parte de inicialização foi omitida para exemplificar que não é 
necessária, desde que essa parte seja realizada em alguma outra parte do código. 
Expandindo esse conceito, pode-se realizar um loop infinito com a instrução for da 
seguinte forma: 
 
#include <stdio.h> 
int main () 
{ int n=2; 
 for (;;) 
 { printf ("%d ",n); 
 n=n*2; 
 } 
 return 0; 
} 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
21 
 
O exemplo exposto implementa um laço (loop) infinito. Observe que não há a parte 
de condição de saída da instrução for. Essa condição de saída, nesse caso, deve 
ser colocada dentro do bloco de instrução do loop, por meio de uma instrução con-
dicional if, por exemplo. 
 
 
4.2.2 Comando while 
 
Forma Geral : 
 while (condição) 
 comando ou bloco; 
 
Exemplo: 
Faça um programa que imprima os 100 primeiro números naturais, exceto o 
zero 
#include <stdio.h> 
int n; 
int main() 
{ 
 n= 1; 
 while (n<=100) 
 { printf(“%d”,n); 
 n++; 
 } 
 return 0; 
} 
 
 
 
4.2.3 Comando do - while 
Forma geral: 
do 
{ 
instrução; 
} while (condição); 
Mesmo que a declaração seja apenas um comando é uma boa prática deixar as 
chaves. O ponto-e- vírgula final é obrigatório. 
A estrutura do-while executa a instrução, testa a condição e, se esta for verdadeira, 
volta para a instrução. Este comando, ao contrário do for e do while, garante que a 
instrução será executada pelo menos uma vez. 
 
4.3 Listas de Exercícios dos Comandos Condicionais e de Repetição 
 
 
1- Faça um programa que, dado um par de valores, que representa as coordena-
das de um ponto no plano, determine o quadrante ao qual pertence o ponto, ou 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
22 
 
então se está na origem ou sobre um dos eixos cartesianos. Permitir a repetição 
da leitura e do cálculo até que o usuário deseje encerrar o programa. 
 
2- Uma empresa decidiu dar uma gratificação especial a seus funcionários, base-
ada no número de horas extras e no número de horas que o empregado faltou 
ao trabalho. O valor do prêmio é obtido pela consulta à tabela abaixo, em que 
H é o número de horas extras subtraído do número de horas faltas. 
H( horas) Prêmio (R$) 
[0,10] 50,00 
(10,20] 80,00 
(20,30] 110,00 
(30,40] 180,00 
(40,100] 250,00 
Considere que o prêmio deverá ser acrescentado ao salário bruto do funcionário 
e sobre este total deve ocorrer um desconto de 8.5% relativo a impostos. 
Dados o salário bruto do funcionário, o número de horas que ele faltou e o nú-
mero de horas-extras que fez (considerar horas e minutos do tipo real ex: 8.30), 
imprimir o salário bruto, o prêmio obtido pelo funcionário e seu salário líquido. 
 
3- Faça um programa que lendo idade em anos e sexo de um associado de um 
clube, conceda desconto na mensalidade a ser paga, observando: 
sexo feminino, até 30 anos desconto de 20% 
sexo “ 31 a 40 anos desconto de 30% 
sexo “ acima de 41 anos desconto de35% 
sexo masculino até 25 anos sem desconto 
sexo masculino acima de 25 anos desconto de 25%. 
Forneça idade e mensalidade a pagar. 
O programa deverá ser encerrando quando o usuário digitar ‘F’ respondendo a 
pergunta: Repetir o cálculo (s/n)? 
 
4- Faça um programa que, tendo como dados de entrada o custo de 5 produtos e 
seus códigos, escreva os seus preços finais (com acréscimo de imposto) e suas 
origens, conforme tabela abaixo: 
Código Origem Imposto 
1 Sul 10% 
2 Sudeste 12% 
3 Leste 11% 
 
5- Faça um programa que escreva de quantas maneiras diferentes pode-se obter 
cada um dos diferentes totais de pontos resultantes do lançamento de dois da-
dos. 
 
6- Faça um programa que leia um valor n, inteiro e positivo, repetindo a leitura caso 
o valor esteja fora do estabelecido, calcula e escreve o valor de E, sendo 
 
7- Faça um programa para imprimir na tela os 25 primeiros múltiplos de um número 
dado 
 
!
1
...
!3
1
!2
1
!1
1
1
n
E 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
23 
 
8- Faça um programa que simula o lançamento de um dado por 10 vezes e fornece 
o número de vezes que saiu cada face do dado. Utilize para simular o lança-
mento as funções rand( ) e srand(). 
 
9- Faça um programa para calcular a soma: 
S = 1 -1/2 + ¼ - 1/6 + 1/8 + ... + 1/200 
 
10- Faça um programa que lê uma seqüência indeterminada de dois valores inteiros 
positivos e forneça o máximo divisor comum pelo processo das divisões suces-
sivas dos dois valores. A leitura encerra quando um dos valores (ou os dois) 
for igual a zero. 
Cálculo do M.D.C. pelo processo das divisões sucessivas: 
Nesse processo efetuamos várias divisões até chegar a uma divisão exata. O 
divisor desta divisão é o m.d.c. Acompanhe o cálculo do m.d.c.(48,30). 
Regra prática: 
1º) dividimos o número maior pelo número menor; 
48 / 30 = 1 (com resto 18) 
2º) dividimos o divisor 30, que é divisor da divisão anterior, por 18, que é o resto 
da divisão anterior, e assim sucessivamente;30 / 18 = 1 (com resto 12) 
18 / 12 = 1 (com resto 6) 
12 / 6 = 2 (com resto zero - divisão exata) 
3º) O divisor da divisão exata é 6. Então m.d.c.(48,30) = 6. 
 
 
4.4 Exercícios Resolvidos 
// Exercicio 5 
#include <stdio.h> 
 
int t,d1,d2,m; 
int main() 
{ 
 for(t=2;t<13;t++) 
 { 
 m=0; 
 for(d1=1;d1<7;d1++) 
 for(d2=1;d2<7;d2++) 
 if (d1+d2==t) 
 m++; 
 printf("total %2d = %2d maneiras\n",t,m); 
 } 
 return 0; 
} 
 
 
 
// Exercício 8 
#include <stdio.h> 
#include <stdlib.h> 
 
int r, x, s1,s2,s2,s3,s4,s5,s6; 
 
int main() 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
24 
 
{ 
 s1=s2=s3=s4=s5=s6=0; 
 srand( time(NULL) ); 
 /* a função time() retorna a hora corrente, 
 ou -1 se ocorrer um erro. Se for passado 'time'como argumento 
 a hora corrente é armazenada em 'time'.*/ 
 
/* srand( ) estabelece um ponto de partida para a sequencia 
gerada por rand() e utiliza a hora do sistema como semente. 
*/ 
 for(x=1;x<11;x++) 
 { 
 r=1+rand()%6; 
/* A função rand() retorna um valor inteiro aleatório entre 
0 e 32767, usamos o resto da divisão por seis mais 1 para 
garantir no. entre 1 e 6 */ 
 printf("gerou %d\n",r); 
 switch (r) 
 { 
 case 1: s1++; break; 
 case 2: s2++; break; 
 case 3: s3++; break; 
 case 4: s4++; break; 
 case 5: s5++; break; 
 case 6: s6++; break; 
 } 
 } 
 printf("1 saiu %d vezes\n",s1); 
 printf("2 saiu %d vezes\n",s2); 
 printf("3 saiu %d vezes\n",s3); 
 printf("4 saiu %d vezes\n",s4); 
 printf("5 saiu %d vezes\n",s5); 
 printf("6 saiu %d vezes\n",s6); 
 return 0; 
} 
 
 
 
5.0 Tipo Ponteiro 
 
Um endereço de memória é como se fosse um número inteiro que serve para es-
pecificar um byte específico de memória. Podemos imaginar a memória do compu-
tador como sendo um enorme vetor onde cada elemento é um byte, acessível atra-
vés de um número inteiro que é seu “endereço”. 
 
Uma diferença básica entre um inteiro qualquer e um inteiro que representa um 
endereço está nas operações que podem ser efetuadas com eles. Enquanto intei-
ros comuns podem ser adicionados, multiplicados, etc., os endereços servem ape-
nas para referenciar posições específicas da memória. 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
25 
 
Normalmente, usamos variáveis para armazenar dados (caracteres, reais, inteiros, 
etc.). Se um endereço é como se fosse um número inteiro, nada impede que pos-
samos criar também variáveis para armazenar endereços de memória. Estas vari-
áveis especiais são denominadas ponteiros. 
 
“Uma variável do tipo ponteiro serve para armazenar um endereço de memória”. 
 
 
5.1 Declaração de variáveis do tipo ponteiro 
 
Variáveis Estáticas - O seu valor é referido através do nome da variável, ou seja, 
“o nome da variável é considerado uma expressão designatória do seu valor”. 
Sua vida útil é: 
Variáveis globais: durante toda execução do programa. 
Variáveis Locais: durante a execução do subprograma. 
Variáveis Dinâmicas - Uma variável dinâmica pode ser criada ou destruída dina-
micamente em qualquer ponto durante a execução de um programa. 
O valor de uma variável dinâmica não é referido através de seu nome, mas sim 
através de uma ligação ou ponteiro para outra variável em que este valor está 
armazenado. 
 
Ao passo que com uma variável estática estamos interessados no valor da variável, 
com uma variável do tipo ponteiro estamos interessados no valor para o qual ela 
aponta. 
 
Variável Estática : 
 
num 5 
 
Variável Ponteiro: 
 
p 27 
Antes de criarmos uma variável ponteiro, é preciso definir que tipo de ponteiro va-
mos usar. Note que, para acessar uma informação na memória, ter apenas o seu 
Variável Anônima - aquela cujo 
valor não é obtido diretamente 
através do seu nome, mas sim 
através de uma variável do tipo 
ponteiro. 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
26 
 
endereço não é suficiente pois é necessário conhecer também o seu tamanho 
(quantos bytes devemos acessar a partir do endereço). 
 
Sintaxe da declaração de um ponteiro: 
 
É preciso definir para que tipo de dado o ponteiro vai apontar: 
 
 tipo * identificador_da variável; 
 
Exemplos: 
 uma variável denominada p e que aponta para inteiro: 
 int *p 
 dois ponteiros para char: 
 char *temp,*pt2 
 
Para armazenar o endereço de uma variável ponteiro o compilador reservará 2 
bytes (dependendo da máquina). 
 
O valor de uma variável ponteiro não é referido através de seu nome, mas sim 
através de uma ligação ou ponteiro para outra variável em que este valor está ar-
mazenado. 
 
 
5.2 Operadores de ponteiros 
 
5. 2.1 Existem dois operadores especiais para ponteiros: 
 
 & operador unário que devolve o endereço do seu operando 
 
* operador unário que devolve o valor da variável localizada no 
endereço apontado (é o complemento de &) 
 
Tanto & como * têm precedência maior que qualquer operador aritmético, ex-
ceto o menos unário. 
 
Exemplos de declaração, atribuição e operadores em ponteiros: 
int *p, c, q, *px, *py; 
 
 
c=100; 
p=&c; 
q=*p; 
 
 
*px=5; 
 
 
*py=*py 
/* as variáveis p, px e py são do tipo pon-
teiro para inteiros, as variáveis c e q são 
do tipo inteiro*/ 
//c recebe 100 
/* p armazena o endereço que a variável c 
ocupa na memória, logo p aponta para c*/ 
/*q armazena o valor que esta armazenado no 
 // ende-
reço para o qual p aponta (100) 
endereço para onde p aponta*/ 
 
/* armazena o valor 5 na variável apontada 
pelo ponteiro px */ 
 
*/armazena na variável apontada por py o 
mesmo valor que está na variável apontada 
por px (5) */ 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
27 
 
 
Observação: Na declaração, o símbolo * indica o “tipo apontado” em outras 
instruções indica “a variável apontada por”. 
 
Um exemplo: 
#include <stdio.h> 
int main () 
{ int a, *pa; 
 double b, *pb; 
 char c, *pc; 
// atribuições de endereços 
 pa = &a; pb = &b; pc = &c; 
// atribuição de valores 
 a = 1; b = 2.34; c = '@'; 
printf("\n valores:%5d %5.2lf %c", a, b, 
c); 
printf("\n ponteiros:%5d %5.2lf %c", *pa, 
*pb, *pc); 
printf("\n enderecos:%p %p %p", pa, pb, 
pc); 
/* mais atribuições de valores usando os pontei-
ros*/ 
 *pa = 77; *pb = 0.33; *pc = '#'; 
 printf("\n valores :%5d %5.2lf %c", a, b, 
c); 
 printf("\n ponteiros:%5d %5.2lf %c", *pa, 
*pb, *pc); 
printf("\n enderecos:%p %p %p\n", pa, pb, 
pc); 
 return 0; 
} 
 
 
 
 
 
 
 
 
 
Ponteiros também são variáveis e, portanto, ocupam posições na memória: 
#include <stdio.h> 
int main() 
{ int a, *pa; 
 double b, *pb; 
 char c, *pc; 
 // atribuições de endereços 
 pa = &a; pb = &b; pc = &c; 
 // mostra o endereço das variáveis 
 printf("\nendereço de a, b e c: %p %p %p", pa, pb, pc); 
 // mostra o endereço das variáveis de outra forma 
 printf("\nendereço de a, b e c (outra forma): %p %p %p", &a, 
&b, &c); 
 // mostra o endereço dos ponteiros 
 printf("\nendereço dos ponteiros: %p %p %p\n", &pa, &pb, 
&pc); 
 return 0; 
} 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
28 
 
 
 
 
5.2.2 Operações com Ponteiros 
 
5.2.2.1 Atribuição entre ponteiros 
 
Se temos dois ponteiros, p1 e p2 podemos fazer 
 p1=p2. 
 
 Repareque estamos fazendo com que p1 aponte para o mesmo lugar 
que p2 aponta. 
 Se quisermos que a variável apontada por p1 tenha o mesmo conteúdo 
da variável apontada por p2 devemos fazer *p1=*p2. 
 
 
 
5.2.2.2 Operações aritméticas com Ponteiros: apenas duas 
 
 Incremento de um ponteiro 
Quando incrementamos um ponteiro ele passa a apontar para o próximo valor do 
mesmo tipo para o qual o ponteiro aponta. Isto é, se temos um ponteiro para um 
inteiro e o incrementamos, ele passa a apontar para o próximo inteiro. 
 
Esta é mais uma razão pela qual o compilador precisa saber o tipo de um pon-
teiro: se você incrementa um ponteiro char* ele anda 1 byte na memória e se você 
incrementa um ponteiro double* ele anda 8 bytes na memória. 
 
Considere ptr um ponteiro para inteiro que contém o valor atual 2000 e 2 bytes o 
tamanho necessário para um inteiro. 
Após a expressão: 
 
 ptr++ 
 
ptr conterá 2002 (e não 2001) 
 
Cada vez que ptr for incrementado, ele apontará para a posição do próximo 
inteiro. 
Em outras palavras, os ponteiros são incrementados relativamente ao tamanho do 
tipo base. 
 
 Decremento de um ponteiro 
O decremento funciona de forma semelhante ao incremento 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
29 
 
Supondo que p, p1 e p2 sejam ponteiros para inteiros: 
 
p++; // p aponta para o próximo inteiro 
p--; // p aponta para o inteiro anterior 
p1=p2+3; // p1 aponta para o terceiro inteiro após o inteiro apontado por p2 
 
 
 
5.2.2.3 Operadores relacionais 
Considerando ponteiros de mesmo tipo, é possível utiliza-los em expressões que 
contenha operadores relacionais: 
 
 podemos saber se dois ponteiros são iguais ou diferentes (== e !=). 
 no caso de operações do tipo >, <, >= e <= estamos comparando qual pon-
teiro aponta para uma posição mais alta na memória. Então uma compara-
ção entre ponteiros pode nos dizer qual dos dois está "mais adiante" na me-
mória. 
 A comparação entre dois ponteiros se escreve como a comparação entre ou-
tras duas variáveis quaisquer: 
 
If (p1<p2) 
 printf(“p1 aponta para uma memória mais baixa que p2\n”); 
 
 
5.2.2.4 Operações não permitidas com ponteiros 
 
Não é possível: 
 dividir ou multiplicar ponteiros, 
 adicionar dois ponteiros, 
 adicionar ou subtrair floats ou doubles de ponteiros. 
 
 
5.3 Ponteiros para Ponteiros 
 
Um ponteiro para ponteiro pode ser imaginado com a situação de anotarmos em 
um papel o local onde está guardado o endereço da casa de um amigo. 
 
Declaração de um ponteiro para um ponteiro: 
tipo_da_variável **nome_da_variável; 
 
onde: 
 **nome_da_variável é o conteúdo final da variável apontada; 
 *nome_da_variável é o conteúdo do ponteiro intermediário. 
 
Um exemplo: 
#include <stdio.h> 
int main() 
{ 
 float fpi = 3.1416, *pf, **ppf; 
 pf = &fpi; /* pf armazena o endereco de fpi */ 
 ppf = &pf; /* ppf armazena o endereco de pf */ 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
30 
 
 /* imprime o valor armazenado no endereço apontado por pf */ 
printf("valor armazenado no endereço apontado por pf: %f\n", 
*pf); 
 /* Imprime o valor armazenado no endereço apontado pelo ponteiro 
(pf) para o qual ppf aponta */ 
 printf("Valor armazenado no endereço apontado por ppf: %f\n", 
**ppf); 
 return 0; 
} 
 
 
5.4 Inicialização de ponteiros – a constante “NULL” 
A biblioteca stdio.h define uma macro especialmente para que façamos a iniciali-
zação de um ponteiro, informando que ele não tem um endereço associado 
 
É muito importante que saibamos para onde o ponteiro está apontando, ou seja: 
nunca use um ponteiro que não foi inicializado. 
O exemplo abaixo ilustra esta situação: 
int main () 
/* Nao Execute!!! */ 
{ int n,*p; 
 n=22; 
 *p=n; 
 Return 0; 
} 
Este programa compilará e rodará. Mas o ponteiro p pode estar apontando para 
qualquer lugar. 
Estamos gravando o número 22 em um lugar desconhecido. 
Com um número apenas, não vamos ver nenhum defeito. Porém se tivermos por 
ábito gravar números em posições aleatórias no computador, o micro poderá tra-
var. 
 
!! Inicialize sempre os seus ponteiros com o valor NULL !! 
 
 
 
5.5 Alocação dinâmica de memória 
 
Considerando a declaração abaixo: 
int *p 
 
identificamos que p é uma variável que aponta para valores inteiros (ou seja, arma-
zena seu endereço). 
 
No início da execução de um bloco em que esta variável é declarada, a variável p 
é criada (tal como acontece com as varáveis estáticas). Depois de sua criação p 
existe, embora não exista ainda a variável do tipo int para onde ela aponta, 
situação que pode ser representa como no esquema abaixo: 
 
 p ? 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
31 
 
Para que p possua um endereço (aponte para um endereço), é preciso que faça-
mos uma alocação dinâmica de memória (um pedido de memória do tamanho cor-
reto para armzenar um valor inteiro). 
 
 
A alocação dinâmica permite ao programador alocar memória para variáveis 
quando o programa está sendo executado. Assim, poderemos definir, por exemplo, 
um vetor ou uma matriz cujo tamanho descobriremos em tempo de execução. A 
memória alocada pelas funções de alocação dinâmica é obtida do heap. 
 
 
 
 
O heap é a região de memória livre que 
se encontra entre o programa (com a 
área de armazenamento permanente) 
e a pilha (stack). 
O tamanho do heap é, a princípio, des-
conhecido do programa. 
 
 
 
Existe uma função especial em C para alocarmos memória no heap, a função 
malloc(). 
 
 
5.5.1 Função malloc 
A função malloc() serve para alocar memória de forma dinâmica. 
Sintaxe: void malloc (int size); 
Biblioteca: stdlib.h 
 
A função recebe o número de bytes que queremos alocar (size), aloca na memó-
ria e retorna um ponteiro void * para o primeiro byte alocado. 
 
O ponteiro void * pode ser atribuído a qualquer tipo de ponteiro por isso, deve ser 
utilizado sempre um typecasting (conversão para o tipo apropriado). 
 
Se a memória for alocada no topo do heap, o heapPointer é atualizado (incremen-
tado de size). 
 
Ex: sendo p um ponteiro para inteiro fazemos o typecasting para inteiro 
p= (int *) malloc( sizeof(int) ); 
 
 como não sabemos necessariamente o comprimento de um inteiro (2 ou 4 
bytes dependendo do compilador), usamos como parâmetro sizeof(int). 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
32 
 
Se não houver memória suficiente para alocar a memória requisitada a função 
malloc() retorna NULL. 
 
 
Após realizar a alocação de um endereço, nosso ponteiro p já possuirá uma variá-
vel anônima a ele associada: 
 
p ? 
 
 
Porém, a variável anônima associada a p não está armazenando ainda nenhum 
valor. Para isso fazemos uma atribuição (ou uma leitura): 
 
*p = 97; 
 
o que pode ser graficamente representado como: 
 
p 97 
 
 
Exemplo e esquema representativo da memória durante a alocação dinâmica de 
memória: 
 
 
#include <stdlib.h> 
int *pi; (1) 
int main () 
{ 
 pi = (int *) malloc (sizeof(int)); (2) 
 *pi=97; (3) 
 return 0; 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
(1) (2) (3) 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
33 
 
5.5.2 Função free() 
 
 A função free(p) libera a região de memória apontada por p para uso. 
 O tamanho liberado está implícito, isto é, é igual ao que foi alocado anterior-
mente por malloc. 
 Caso p seja um ponteironulo nenhuma ação é executada. 
 
Declaração: void free(void *p); 
Biblioteca: stdlib.h 
 
O trecho de código abaixo aloca dinâmicamente um inteiro e depois o libera: 
 
#include <stdlib.h> 
int main(int) 
{ 
 int *pi; 
 pi = (int *) malloc (sizeof(int)); 
 ... 
 … 
 free(pi); 
} 
 
 
6.0 Modularização (subprogramas) 
 
6.1 Introdução ao conceito de modularização 
 
Exemplos de modularização, i.e., sistemas que são compostos por módulos com 
funções bem definidas e tão independentes quanto possível, são bem conheci-
dos. Um destes exemplos que pode ser citado, são os sistemas (domésticos ou 
não) de som, onde há um módulo responsável pela amplificação, outro para sinto-
nizar rádio, outro para amplificar o som, ler CDs e assim por diante. 
 
A divisão de um sistema em módulos tem várias vantagens. Para o fabricante, a 
modularização tem a vantagem de reduzir a complexidade do problema, dividindo-
o em subproblemas mais simples, que podem inclusive ser resolvidos por equipes 
independentes. Sob o ponto de vista da fabricação, é mais simples alterar a com-
posição de um módulo, por exemplo, porque se desenvolveram melhores circuitos 
para o amplificador, do que alterar a composição de um sistema integrado. Por 
outro lado, é mais fácil detectar problemas e resolvê-los, pois os módulos são, em 
princípio, razoavelmente independentes. Claro que os módulos muitas vezes não 
são totalmente independentes. Por exemplo, o sistema de controle à distância de 
uma aparelhagem implica interação com todos os módulos simultaneamente. 
 
A arte da modularização está em identificar claramente que módulos devem existir 
no sistema, de modo a garantir que as ligações entre os módulos sejam minimiza-
das e que a sua coesão interna seja máxima. Isto significa que, no caso de um 
bom sistema de alta fidelidade, os cabos entre os módulos são simplificados ao 
máximo e que os módulos contenham apenas os circuitos que garantem que o mó-
dulo faça sua função. A coesão tem, portanto, a ver com as ligações internas a 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
34 
 
um módulo, que idealmente devem ser maximizadas. Normalmente, um módulo é 
coeso se tiver uma única função, bem definida. 
 
Para quem utiliza, por outro lado, a modularização tem como vantagem principal 
permitir a alteração de um único módulo sem ter de comprar um sistema 
novo. Claro que para isso acontecer o novo módulo tem de (1) ter a mesma função 
do módulo substituido e (2) possuir uma interface idêntica (os mesmo tipo de cabos 
com o mesmo tipo de sinal eléctrico). Isto é, os módulos, do ponto de vista do 
utilizador, funcionam como "caixas pretas" com uma função bem definida e com 
interfaces bem conhecidas. Para o utilizador o interior de um módulo é irrelevante. 
 
Mas a modularização tem outras vantagens: o amplificador pode no futuro ser reu-
tilizado num sistema de vídeo, por exemplo, evitando a duplicação de circuitos com 
a mesma função. 
 
As vantagens da modularização são muitas e foi introduzida na programação a 
partir das linguagens como o C e o Pascal. É um dos métodos usados em progra-
mação para desenvolvimento de programas de grande escala mas é útil mesmo 
para pequenos programas, quanto mais não seja pelo treino que proporciona. 
Vantagens da modularização para a programação: 
1. Facilita a detecção de erros, pois é em princípio simples verificar qual é o 
módulo responsável pelo erro. 
2. É mais fácil testar os módulos individualmente do que o programa com-
pleto. 
3. É mais fácil fazer a manutenção (correcção de erros, melhoramentos, etc.) 
módulo por módulo do que no programa total. Além disso, a modulariza-
ção aumenta a probabilidade dessa manutenção não ter consequências 
nefastas nos outros módulos do programa. 
4. Permite o desenvolvimento independente dos módulos. Isto simplifica o 
trabalho em equipe, pois cada elemento, ou cada sub-equipe, tem a seu 
cargo apenas alguns módulos do programa. 
5. A mais evidente vantagem da modularização em programas de pequena 
escala, mas também nos de grande escala, é a possibilidade de reutiliza-
ção do código desenvolvido. 
Um programador assume, ao longo do desenvolvimento de um programa, os dois 
papeis descritos acima: por um lado é fabricante, pois é sua responsabilidade de-
senvolver módulos; por outro é utilizador, pois fará com certeza uso de outros mó-
dulos, desenvolvidos por outrem ou por ele próprio no passado. Esta é uma noção 
muito importante. É conveniente que um programador possa ser um mero utilizador 
dos módulos já desenvolvidos, sem se preocupar com o seu funcionamento interno: 
ele sabe qual a interface do módulo e qual a sua função, e usa-o. Isto permite 
reduzir substancialmente a complexidade da informação que o programador tem 
de ter presente na sua memória, conduzindo por isso a substanciais ganhos de 
produtividade e a uma menor taxa de erros. 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
35 
 
Em nosso estudo, até agora, já entramos em contato com o uso de módulos pron-
tos. São as funções que utilizamos para limpar a tela, escrever na tela, fazer en-
trada de dados e outras. 
 
Existem basicamente duas formas de criar subprogramas: utilizar procedimentos 
ou funções. A linguagem C só permite a utilização de funções , por isso enfocare-
mos basicamente funções em nossas aulas. 
Um procedimento é um conjunto de instruções, com interface bem definida, que 
pode receber e enviar dados para quem o acionou, normalmente o programa prin-
cipal. 
 
Uma função por sua vez, também segue a definição acima, com a diferença de que 
devem ter obrigatóriamente um tipo definido para o valor que a função retorna. Em 
outras palavras, funções só não retornam um valor se as definirmos como void. 
 
Uma vez definida ("fabricada"), uma função, ou um procedimento, podem ser utili-
zados sem que se precise conhecer o seu funcionamento interno, da mesma forma 
que o usuário da aparelhagem de som não está muito interessado nos circuitos 
dentro do amplificador, mas simplesmente nas suas características. Claro, para que 
funcuione adequadamente, é preciso saber conectar o equipamento ao sistema. O 
mesmo acontece com as funções e os procedimentos. 
Tomemos como exemplo uma função que é utilizada para gerar automáticamente 
números aleatórios, a função rand. Para poder utilizá-la devemos conhecer primeiro 
seu protótipo (cabeçalho da função). O protótipo irá nos mostrar qual o tipo e os 
parâmetros de rand. Onde procurar esta informação? Tenha sempre a mão um bom 
livro de C ou utilize o help do turbo C. O protótipo é: 
 
 
 int rand(void) 
int informa que a função retorna um valor inteiro 
rand é seu nome 
e (void) indica que ela não requer parâmetros. 
 
 
Outro exemplo é a função matemática sqrt. Esta função, como já estudamos, in-
forma como resultado (retorna) a raiz quadrada de um número. Para fazer este 
cálculo devemos colocar entre parênteses (como parâmetro) o valor ou a variável 
que servirá para fazer o cálculo da raiz quadrada e devemos declarar uma variável 
apropiada para armazenar o resultado. Veja na tabela 4. 
 
 
Exemplo: 
#include math.h 
float r,n; 
int main () 
{ r=sqrt(16); // r armazena o retorno da função cujo parâmetro 
é 16*/ 
 ------; 
 ------; 
 return 0; 
} 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
36 
 
 
 
Para usarmos funções prontas, portanto, não necessitamos conhecer o seu código, 
porém é importante conhecer seu protótipo (tipo que retorna, nome da função e 
parâmetros que requer). 
 
 
Mas nem sempre utilizaremos apenas funções prontas, muitas vezes “fabricare-
mos” nós mesmos nossas funções. 
 
6.2 Definiçãode funções em C 
 
 
 
Outra observação: Se não declaramos o tipo de uma função ela será considerada 
int. 
 
 
6.3 Escopo de uma variável (região de validade) tipos de parâmetros e retorno 
de funções 
 
 Variáveis Globais (Estáticas): são declaradas fora das funções e são reco-
nhecidas em todo o programa (em main e inclusive nos demais subprogra-
mas). 
 
 Variáveis Locais: são declaradas no bloco da função e são válidas apenas 
na função. São alocadas através da requisição de espaço na pilha (stack) 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
37 
 
e permanecem na memória somente durante a execução da função, deixando 
de existir quando a função é encerrada. 
 
 
 
Exemplo2: Faça um programa que leia três valores reais que representam a base 
maior, base menor e altura de um trapézio, calcule e informe a área do trapézio. 
 
 
#include <stdio.h> 
 
 
int main () 
{ 
 float bmai,bmen,h,area; 
 printf("Digite a base 
maior\n"); 
 printf("Digite a base me-
nor\n"); 
 printf("Digite altura do tra-
pezio\n"); 
 
scanf("%f%f%f",&bmai,&bmen,&h); 
 area=(bmai+bmen)/2*h; 
 printf("area do trapezio: 
5.2f\n",area); 
 return 0; 
} 
 
#include <stdio.h> 
 
void calculo (float ma, float me, 
float altura); 
int main () 
{ 
 float bmai,bmen,h; 
 printf("Digite a base maior\n"); 
 printf("Digite a base menor\n"); 
 printf("Digite altura do trape 
zio\n"); 
 scanf("%f%f%f",&bmai,&bmen,&h); 
 calculo(bmai,bmen,h); 
} 
void calculo (float ma, float me, 
float altura) 
{ 
 float area; 
 area=(ma+me)/2*altura; 
 printf("Area: %5.2f",area); 
} 
Ex2: sem função Ex2: com função e parâmetros, sem retorno 
 
É importante observar que, antes da função main, foi feita a declaração do protótipo 
da função, que consiste em colocar seu cabeçalho seguido de ponto e vírgula. Isto 
é feito para informar ao compilador a existência do código da função após main. 
Para evitar a declaração do protótipo, a função poderia ser implementada antes de 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
38 
 
main, colocando exatamente as mesmas instruções que foram colocadas após 
main, sem o ponto e vírgula ao final da linha do cabeçalho. 
Portanto, sempre que implementarmos o código de funções após main, deveremos 
fazer a declaração de seu protótipo antes de main. Apenas as funções que tiverem 
como retorno o tipo int não precisarão seguir esta regra. 
 
A função calculo foi implementada com 4 variáveis locais: 
bma, bme, alt: são declaradas entre parênteses, pois são parâmetros da função. 
area: declarada no corpo da função porque não é parâmetro 
 
A função calculo não precisa retornar nada para quem a chamou, logo seu tipo é 
void. 
 
Ao ser acionada uma função com parâmetros, devemos informar os valores, entre 
parênteses e estes ficarão armazrnados nas variáveis locais declaradas dentro dos 
parênteses, na mesma ordem em que são colocados. 
No exemplo teremos a variável bma passando seu valor para o parâmetro ma, te-
remos a variável bme passando seu valor para o parâmetro me e a variável h pas-
sando seu valor para o parâmetro altura. 
 
Assim, existirá uma comunicação de informações entre main e a função calculo que 
é a passagem destes valores, lidos em main e sem os quais a função não poderia 
efetuar o calculo. 
 
Esta comunicação se dá somente no sentido de main para função (e não vice-
versa) e é conhecida como passagem de parâmetros por valor. 
Neste exemplo a função nada retorna, visto que ela mesma informa o resultado do 
cálculo, mas poderíamos entender que seria melhor se a função retornasse a área 
calculada para quem a acionou. 
O exemplo abaixo apresenta uma forma de resolução onde a área calculada é o 
retorno da função . 
 
#include <stdio.h> 
float calculo (float ma, float me, float altura); 
int main () 
{ 
 float bmai,bmen,h,a; 
 printf("Digite a base maior\n"); 
 printf("Digite a base menor\n"); 
 printf("Digite altura do trapezio\n"); 
 scanf("%f%f%f",&bmai,&bmen,&h); 
 a=calculo(bmai,bmen,h); 
 printf("Area: %5.2f",area); 
 return 0; 
} 
 
float calculo (float ma, float me, float altura) 
{ float area; 
 area=(ma+me)/2*altura; 
 return(area) 
} 
Ex3: resolução com retorno da função 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
39 
 
Observe autilização do comando return antes de encerrar a função. Através deste 
comando estamos informando qual o retorno desta função, no caso o valor arma-
zenado na variável local área, que por isso deve ser do mesmo tipo da função. 
 
Outra forma de passarmos valores para “fora” de uma função é através dos parâ-
metros. Podemos declarar parâmetros de forma que eles não só recebam um valor 
de quem aciona a função mas ao mesmo tempo retornem um valor para a variável 
que se corresponde com o parâmetro. 
 
 
Esta forma de passagem de parâmetros é chamada de passagem por referência 
e consiste em informarmos o endereço da variável no acionamento da função. Por 
sua vez, o parâmetro correspondente deverá ser declarado como tipo ponteiro, 
para poder armazenar este endereço. 
 
 
Exemplo: Faça um programa que leia 3 valores inteiros (a,b e c) e escreva-os or-
denados, de forma que em a esteja o menor valor e em c o maior. 
 
#include <stdio.h> 
int main () 
{ 
 int a,b,c,aux; 
 printf("Informe os tres inteiros\n"); 
 scanf("%d %d %d",&a,&b,&c); 
 if (a>b) 
 {aux=a; 
 a=b; 
 b=aux; 
 } 
 if (a>c) 
 {aux=a; 
 a=c; 
 c=aux; 
 } 
 if (b>c) 
 {aux=b; 
 b=c; 
 c=aux; 
 } 
 printf("a=%d b=%d c=%d",a,b,c); 
 return 0; 
} 
 
 
Percebe-se que a cada vez que o teste entre as variáveis for verdadeiro será reali-
zado um mesmo bloco de instruções, que troca as variáveis envolvidas no teste. 
Este trecho de código pode ser implementado em uma função que receba os valo-
res e devolva-os trocados, como é mostrado abaixo, realizando uma passagem de 
parâmetros por referência. 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
40 
 
#include <stdio.h> 
void troca(int *x, int *y); 
int main () 
{ 
 int a,b,c; 
 printf("Informe os tres inteiros\n"); 
 scanf("%d %d %d",&a,&b,&c); 
 if (a>b) 
 troca(&a,&b); 
 if (a>c) 
 troca(&a,&c); 
 if (b>c) 
 troca(&b,&c); 
 printf("a=%d b=%d c=%d\n",a,b,c); 
 return 0; 
} 
void troca (int *x, int *y) 
{ 
 int aux; 
 aux=*x; 
 *x=*y; 
 *y=aux; 
} 
 
 
Variáveis Locais Estáticas 
 
É possível, quando da declaração de variáveis prefixá-las com o qualificador static. 
 As variáveis locais estáticas são inicializadas uma só vez e não desapare-
cem quando a função a que pertencem termina, podendo no entanto ser 
acessadas apenas dentro da função. 
 As variáveis locais estáticas também mantêm o seu valor de umas chama-
das para as outras, como se vê nos exemplos seguinte: 
 
Exemplo: 
 
#include <stdio.h> 
void func (int x); 
int main () // função principal 
{ func (10); 
 func (20); 
 func (30); 
 return 0; 
} 
 
void func (int x) 
{ /* declaração de 1variável local, porém estática, 
 e por isso, permanece com o valor da chamada anterior*/ 
 static int s = 0; 
 printf("\n valor de s no inicio da funcao = %5d", s); 
 s = s + x; 
 printf("\n valor de s no final da funcao = %5d", s); 
} 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
41 
 
 6.4Inclusão de arquivos de cabeçalho com funções criadas pelo usuário 
 
Podemos criar um arquivo cabeçalho (*.h) com as funções que acharmos apropri-
adas, geralmente aquelas que são muito utilizadas. Abaixo apresenta-se o mesmo 
exemplo utilizado para demonstrar passagem de parâmetros por referência, visto 
anteriormente. Agora, porém, a função que faz a troca entre os valores está imple-
mentada em um arquivo externo, chamado uteis. h. Veja abaixo: 
 
#include <stdio.h> 
#include"d:\tc\bin\A09_01\ 
Ex_incl\uteis.h" 
 
int main () 
{ 
 int a,b,c,aux; 
 printf("Informe os 
tres inteiros\n"); 
 scanf("%d %d 
%d",&a,&b,&c); 
 if (a>b) 
 troca(&a,&b); 
 if (a>c) 
 troca(&a,&c); 
 if (b>c) 
 troca(&b,&c); 
 printf("a=%d b=%d 
c=%d",a,b,c); 
 return 0; 
} 
//arquivo .h que possui uma funcao 
para trocar dois inteiros 
 
//----------------------------------- 
//cabeçalho da função 
 
void troca(int *x, int *y); 
 
//----------------------------------- 
// desenvolvimento da função 
 
void troca(int *x, int *y) 
{ int aux; 
 aux=*x; 
 *x=*y; 
 *y=aux; 
} 
 
OBS: quando delimitamos o arquivo cabeçalh < > estamos direcionando sua 
busca no diretorio padrao de inclusao (a pasta include do diretorio tc), quando uti-
lizamos " " significa o diretorio corrente, ou podemos especificar um caminho. 
Para criar um arquivo header acione o menu File - New e depois File outra vez. 
Escolha header: 
 
 
 
 
 
 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
42 
 
6.5 Exercícios propostos 
 
1. Escreva uma função que dadas as notas de prova p1 e p2 e as notas dos exer-
cícios-programa ep1, ep2 e ep3 de um aluno, devolve o valor da média final 
deste aluno. A média final do aluno é dada por (3p+ep)/4, onde p = (p1+2p2)/3 
e ep = (ep1+2ep2+3ep3)/6. 
 
2. Idem, acrescentando se p<5 ou ep<6 a média final é o mínimo entre 4.5, p e 
ep. 
 
3. Fazer um programa que possibilite várias opções de cálculos a partir de um 
menu. O programa chamará a função correspondente a cada cálculo. 
a- S = 1/1 + 3/2 + 5/3+........+ 99/50 
b- S = 1/1 - 2/2 + 3/3 -..........- 10/10 
c- S = 1000/1 - 997/2 + 994/3......... 
d- S = 480/10 - 475/11 + 470/12 - ....... 
e- Sair 
Obs.: Nas opções c e d fazer os cálculos para os 20 primeiros termos. 
O menu deverá ficar disponível até ser escolhida a opção e. 
 
4. Faça uma função que receba como argumento os valores dos lados de um tri-
ângulo, a função deverá retornar 0 se triângulo for equilátero, 1 se for isósce-
les ou 2 se for escaleno. 
 
5. Fazer um programa em C que solicita o total gasto pelo cliente de uma loja, 
imprime as opções de pagamento, solicita a opção desejada e imprime o valor 
total das prestações (se houverem). 
a - Opção a vista com 10% de desconto 
b- Opção em duas vezes (preço da etiqueta) 
c- Opção de 3 até 10 vezes com 3% de juros ao mês (somente para compras 
acima de R$ 100,00). 
OBS: fazer uma função que imprime as opções, solicita a opção desejada e 
retorna a opção escolhida. 
 No programa principal, testar a opção escolhida e ativar a função correspon-
dente (uma função para cada opção). 
 
6. Faça um programa para ler valores inteiros até ser digitado o valor -1 (tarefa 1) 
e fornecer o fatorial de cada valor lido (tarefa2). 
 
7. Faça um programa que verifica quais dentre os 1000 primeiros números natu-
rais são número perfeito. Número perfeito é todo número que, somando seus 
divisores, esta soma resulta nele mesmo. Utilize uma fção para a verificação 
de cada um dos números. A função main deve informar o resultado. 
 Ex: 6 é divisível por 1 6 é divisível por 2 6 é divisível por 3 
 1+2+3 = 6 é quadrado perfeito. 
 
8. Faça um programa que lê os seguintes dados relativos a 30 alunos de uma 
escola de futebol: altura; data de nascimento (tarefa de main). O programa de-
verá fornecer como saída: a idade média dos alunos (tarefa2); a altura média 
dos alunos (tarefa 3). 
 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
43 
 
9. A prefeitura de uma cidade fez uma pesquisa entre seus habitantes, coletando 
dados sobre o salário e o número de filhos. A prefeitura deseja saber: 
 média do salário da população (utilize 1 função); 
 média do número de filhos ((utilize 1 função); 
 maior salário (utilize 1 função); 
 percentual de pessoas com salário até R$920,00 (utilize 1 função). 
Encerrar a leitura dos dados com salário negativo. 
 
10. Faça um programa onde main imprima na tela os ‘n’ primeiros números primos, 
onde ‘n’ será fornecido pelo usuário. Utilize uma função para verificar se o nú-
mero é primo. 
 
11. Dado n e p inteiros, n,p >= 0, calcular as combinações de n elementos p a p, 
isto é: n! / (p! * (n-p)! ). Utilize funções. 
 
12. A sequência de Fibonacci é a seguinte: 1, 1, 2, 3, 5, 8, 13, 21, ... 
os dois primeiros termos são iguais a 1. Cada termo seguinte é igual `a soma 
dos dois anteriores. Escreva um programa onde main solicita ao usuário o nú-
mero do termo e calcule através de uma função o valor do termo. Main deverá 
escrever o valor do termo. Por exemplo: se o número fornecido pelo usuário for 
igual a 7, main deverá imprimir 13. 
 
13. Escreva um programa em que main solicite ao usuário três números inteiros a, 
b, e c onde a é maior que 1. Uma outra função deve somar todos os inteiros 
entre b e c que sejam divisíveis por a. Main deve informar a soma. 
 
 
6.6 Exercícios Resolvidos 
 
Exercício 1 
#include <stdio.h> 
#include <stdlib.h> 
 
float media(float p1,float p2,float p3,float ep1,float ep2,float ep3); 
 
int main() 
{ float p1,p2,p3,ep1,ep2,ep3; 
 printf("Informe as notas das tres provas:\n"); 
 scanf("%f%f%f",&p1,&p2,&p3); 
 printf("Informe as notas dos tres exercícios:\n"); 
 scanf("%f%f%f",&ep1,&ep2,&ep3); 
 printf("A media eh: %.2f",media(p1,p2,p3,ep1,ep2,ep3)); 
 return 0; 
} 
 
float media(float p1,float p2,float p3,float ep1,float ep2,float ep3) 
{ float p,ep,m; 
 p=(p1+2*p2)/3; 
 ep=(ep1+2*ep2+3*ep3)/6; 
 m=(3*p+ep)/4; 
 return(m); 
} 
 
Exercício 4 
#include <stdio.h> 
#include <stdlib.h> 
int triangulo (float a, float b, float c); 
int main() 
Notas de aula de Programação Estruturada 
Professoes Beatriz Lux e Rolf F. Molz 
 
44 
 
{ float a,b,c; 
 int tipo; 
 printf("Informe os lados do triangulo\n"); 
 scanf("%f%f%f",&a,&b,&c); 
 tipo=triangulo(a,b,c); 
 switch(tipo) 
 { case 0: printf("\n Equilatero"); 
 break; 
 case 1: printf("\n Isosceles"); 
 break; 
 case 2: printf("\n Escaleno"); 
 break; 
 case 3: printf("\n Não formam um triangulo"); 
 break; 
 
 } 
 return 0; 
} 
int triangulo (float a, float b, float c) 
{ int r; 
 if(a<=b+c && b<=a+c && c<= a+b) // teste para saber se podem formar 
triangulo 
 if(a==b && b==c) 
 r=0; 
 else 
 if(a!=b && b!=c && a!=c) 
 r=2; 
 else 
 r=1; 
 else 
 r=3; 
 return (r); 
} 
 
Exercício 8 
#include <stdio.h> 
#include <time.h> 
 
int idade(int day, int month, int year,int d,int m,int a); 
float acum_altura(float a); 
int acum_idade(int i); 
 
 
int main() 
{ const max= 3; 
 char nome[15]; 
 int x,dia,mes,ano,d,m,a,i; 
 float alt,sh,si; 
 struct tm *local; 
 time_t t; 
 t= time(NULL); 
 local = localtime(&t);

Outros materiais