Logo Passei Direto
Buscar

PROGRAMACAO_DE_COMPUTADORES_Utilizando_L

Ferramentas de estudo

Questões resolvidas

PROGRAMAÇÃO DE COMPUTADORES Utilizando Linguagem C-ANSI. What is the topic covered in chapter 1.8 of this book?


a. Compiladores e Interpretadores
b. Tipos de Dados
c. Linguagem de Programação
d. Paradigma de Programação: Programação Estruturada

What are the topics covered in this text?
Variables
Operators
Control Flow
Input and Output
Arrays and Matrices
String Manipulation
Structures, Enumerations, and Unions
Pointers

null
Ponteiros, Vetores e Matrizes
Funções
Alocação Dinâmica
Manipulação de Arquivos
Ordenação
Estruturas de Dados
O conteúdo apresentado no texto é um sumário de um material de estudo.
O texto apresenta exercícios para fixação do conteúdo.
O texto apresenta apenas teoria, sem exemplos práticos.
O texto apresenta apenas exemplos práticos, sem teoria.
a) Apenas a afirmativa I está correta.
b) As afirmativas I e II estão corretas.
c) As afirmativas II e III estão corretas.
d) As afirmativas III e IV estão corretas.

What is the purpose of this text?

a) To explain the basics of the C programming language.
b) To provide a summary of data structures and programming techniques.
c) To present a list of ASCII codes and numerical systems.
d) To discuss the importance of logic in decision making.

What is a diagram of flow?
A graphical representation of an algorithm that details the logical steps of a particular processing.
A hierarchical and structured view of the program logic.
A representation of algorithms using a programming language or through structured Portuguese.
I - A diagram of flow is a graphical representation of an algorithm that details the logical steps of a particular processing.
II - A diagram of Chapin is a diagram in which the arcs are removed, presenting a hierarchical and structured view of the program logic.
III - Portuguese structured is a way of representing algorithms that is similar to the way programs are written.
a) Only I is correct.
b) Only II is correct.
c) Only III is correct.
d) I and II are correct.
e) I, II, and III are correct.

What are the four types of data that can be classified according to the text?

I - Integer types are characterized by positive or negative numerical data, excluding any fractional number.
II - Real types are characterized by positive and negative numerical data and fractional numbers.
III - Character types are characterized by sequences containing letters, numbers, and special symbols.
IV - Logical types are characterized by data with true and false values, and can only represent one of the two values.
a) Only I and II are correct.
b) Only II and III are correct.
c) Only III and IV are correct.
d) I, II, III, and IV are correct.

todo de interpretar um padrão de bits é freqüentemente chamado tipo de dado, portanto, qualquer significado pode ser atribuído a determinado padrão de bits, desde que seja feito com coerência. É a interpretação de um padrão de bits que dá o seu significado. Por exemplo, a seqüência de bits 00100110 pode ser interpretada como o número 38 decimal, o número 26 hexadecimal ou o caractere ‘&’ no código ASCII. A figura 1.11 apresenta um exemplo. Qual é a finalidade deste texto?


a) Explicar como interpretar padrões de bits.
b) Demonstrar a flexibilidade da linguagem C.
c) Apresentar exemplos de cálculos com números binários.
d) Descrever a criação da linguagem C.
e) Nenhuma das alternativas anteriores.

What are the 32 reserved keywords in the ANSI C standard?

A linguagem C é classificada como linguagem de alto nível somando-se as funcionalidades de linguagens de baixo nível.
A linguagem C é uma linguagem estruturada.
O padrão C ANSI determina 32 palavras-chave ou palavras reservadas que, combinadas com a sintaxe formal de C, formam a linguagem de programação C.
a) Apenas a afirmativa I está correta.
b) Apenas a afirmativa II está correta.
c) Apenas a afirmativa III está correta.
d) As afirmativas I, II e III estão corretas.

Em C, há cinco tipos básicos de dados: caractere, inteiro, ponto flutuante, ponto flutuante de precisão dupla e sem valor: char, int, float, double e void, respectivamente. O tamanho e a faixa desses tipos de dados variam de acordo com o tipo de processador e com a implementação do compilador em C. O padrão C ANSI estipula apenas a faixa mínima de cada tipo de dado, não o seu tamanho em bytes (tabela 2.2). O tipo void declara explicitamente uma função que não retorna valor algum ou cria ponteiros genéricos. Em algumas situações é necessário modificar um tipo básico para atender às necessidades de diversas situações. Isto é conseguido através do uso de modificadores que alteram o significado de um tipo básico. Exceto o tipo void, todos os demais tipos básicos podem ter vários modificadores precedendo-os. Os modificadores podem ser: signed unsigned long short. Tabela 2.2 Tipos de dados definidos no padrão C ANSI. Tipo Tamanho (bits) Faixa mínima char 8 -127 a 127 unsigned char 8 0 a 255 signed char 8 -127 a 127 int 16 -32.767 a 32.767 unsigned int 16 0 a 65.535 signed int 16 -32.767 a 32.767 short int 16 -32.767 a 32.767 unsigned short int 16 0 a 65.535 signed short int 16 -32.767 a 32.767 long int 32 -2.147.483.647 a 2.147.483.647 signed long int 32 -2.147.483.647 a 2.147.483.647 unsigned long int 32 0 a 4.294.967.295 float 32 Seis dígitos de precisão double 64 Dez dígitos de precisão long double 80 Dez dígitos de precisão. 2.5 Variáveis Variável é uma posição nomeada de memória utilizada para armazenar um valor que pode ser modificado pelo programa. As variáveis devem ser declaradas da seguinte forma: ; int x;. 2.5.1 Classe de Variáveis As variáveis podem ser declaradas em três lugares básicos: dentro de funções, na definição dos parâmetros das funções e fora de todas as funções, ou seja, variáveis locais, parâmetros formais e variáveis globais. Por exemplo: 23 1. #include 2. #include 3. 4. float g; /*g é variável global*/ 5. 6. float soma10(float c); /*c é parâmetro formal*/ 7. 8. int main(void) 9. { 10. float x; /*x é variável local*/ 11. x=15; 12. g=soma10(x); 13. printf(“g=%f”,g); 14. return(0); 15. } 16. 17. float soma10(float c) 18. { 19. return(c+10); 20. } 2.6 Operadores 2.6.1 Atribuição O operador de atribuição pode ser utilizado dentro de qualquer expressão válida em C. A forma geral do operador de atribuição é: nome_da_variavel = expressão; x = 10; A atribuição é válida para variáveis de tipos diferentes, ou seja, é possível converter os tipos de forma automática. Esta conversão é conhecida como conversão de tipos, porém deve-se observar que poderá ocorrer uma possível perda de informação. Em C, é permitido atribuição do mesmo valor para muitas variáveis em uma única expressão: var1 = var2 = var3 = expressão; x = y = z = 0; 2.6.2 Aritméticos Os operadores aritméticos de C são: - Subtração + Adição * Multiplicação / Divisão % Módulo da divisão (resto). 2.6.3 Incremento e Decremento C inclui dois operadores que geralmente não são encontrados em outras linguagens: -- Decremento ++ Incremento radores relacionais e lógicos. Operadores relacionais Operadores lógicos > Maior que && AND >= Maior ou igual || OR < Menor ! NOT <= Menor ou igual == Igual != Diferente. É permitido combinar diversas operações em uma expressão, por exemplo: 10>5&&!(10<9)||3<=4 Verdadeiro. Tabela 2.4 Tabela verdade operadores lógicos. p q p&&q p||q !p 0 0 0 0 1 0 1 0 1 1 1 1 1 0 0 0. 2.6.5 Bit a Bit A linguagem C oferece um completo conjunto de operadores bit a bit, isto é, testar, atribuir ou deslocar os bits efetivos em um byte (tabela 2.5). A tabela 2.6 apresenta a tabela verdade dos operadores bit a bit. Tabela 2.5 Operadores bit a bit. & AND | OR ^ XOR ~ Complemento de um >> Deslocamento à esquerda << Deslocamento à direita.
Quais são os cinco tipos básicos de dados em C?
O que é o tipo void em C?
O que são modificadores em C?
O que é uma variável em C?
Quais são as três classes de variáveis em C?
O que é o operador de atribuição em C?
Quais são os operadores aritméticos em C?
O que são os operadores relacionais e lógicos em C?
O que são os operadores bit a bit em C?

Qual é a função da biblioteca stdio.h que é utilizada para abrir um arquivo?

A função fopen() é utilizada para abrir um arquivo.

Qual é o modo de abertura de arquivo que é utilizado para criar um arquivo texto para escrita?

O modo de abertura de arquivo utilizado para criar um arquivo texto para escrita é o 'w'.

Qual é a função da biblioteca stdio.h que é utilizada para fechar um arquivo?

A função fclose() é utilizada para fechar um arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para escrever argumento em um arquivo?

A função fprintf() é utilizada para escrever argumento em um arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para posicionar o arquivo em um byte específico?

A função fseek() é utilizada para posicionar o arquivo em um byte específico.

Qual é a macro definida em stdio.h que é utilizada para posicionar o arquivo no início do arquivo?

A macro SEEK_SET é utilizada para posicionar o arquivo no início do arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para ler argumento de um arquivo?

A função fscanf() é utilizada para ler argumento de um arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para ler count blocos de num_bytes de arq para buffer?

A função fread() é utilizada para ler count blocos de num_bytes de arq para buffer.

PROGRAMAÇÃO DE COMPUTADORES Utilizando Linguagem C-ANSI. What is the topic covered in section 1.8 of this material?

a. Tipos de compiladores.
b. Tipos de paradigmas de programação.
c. Tipos de dados.
d. Tipos de linguagens de programação.

Material
páginas com resultados encontrados.
páginas com resultados encontrados.
left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Questões resolvidas

PROGRAMAÇÃO DE COMPUTADORES Utilizando Linguagem C-ANSI. What is the topic covered in chapter 1.8 of this book?


a. Compiladores e Interpretadores
b. Tipos de Dados
c. Linguagem de Programação
d. Paradigma de Programação: Programação Estruturada

What are the topics covered in this text?
Variables
Operators
Control Flow
Input and Output
Arrays and Matrices
String Manipulation
Structures, Enumerations, and Unions
Pointers

null
Ponteiros, Vetores e Matrizes
Funções
Alocação Dinâmica
Manipulação de Arquivos
Ordenação
Estruturas de Dados
O conteúdo apresentado no texto é um sumário de um material de estudo.
O texto apresenta exercícios para fixação do conteúdo.
O texto apresenta apenas teoria, sem exemplos práticos.
O texto apresenta apenas exemplos práticos, sem teoria.
a) Apenas a afirmativa I está correta.
b) As afirmativas I e II estão corretas.
c) As afirmativas II e III estão corretas.
d) As afirmativas III e IV estão corretas.

What is the purpose of this text?

a) To explain the basics of the C programming language.
b) To provide a summary of data structures and programming techniques.
c) To present a list of ASCII codes and numerical systems.
d) To discuss the importance of logic in decision making.

What is a diagram of flow?
A graphical representation of an algorithm that details the logical steps of a particular processing.
A hierarchical and structured view of the program logic.
A representation of algorithms using a programming language or through structured Portuguese.
I - A diagram of flow is a graphical representation of an algorithm that details the logical steps of a particular processing.
II - A diagram of Chapin is a diagram in which the arcs are removed, presenting a hierarchical and structured view of the program logic.
III - Portuguese structured is a way of representing algorithms that is similar to the way programs are written.
a) Only I is correct.
b) Only II is correct.
c) Only III is correct.
d) I and II are correct.
e) I, II, and III are correct.

What are the four types of data that can be classified according to the text?

I - Integer types are characterized by positive or negative numerical data, excluding any fractional number.
II - Real types are characterized by positive and negative numerical data and fractional numbers.
III - Character types are characterized by sequences containing letters, numbers, and special symbols.
IV - Logical types are characterized by data with true and false values, and can only represent one of the two values.
a) Only I and II are correct.
b) Only II and III are correct.
c) Only III and IV are correct.
d) I, II, III, and IV are correct.

todo de interpretar um padrão de bits é freqüentemente chamado tipo de dado, portanto, qualquer significado pode ser atribuído a determinado padrão de bits, desde que seja feito com coerência. É a interpretação de um padrão de bits que dá o seu significado. Por exemplo, a seqüência de bits 00100110 pode ser interpretada como o número 38 decimal, o número 26 hexadecimal ou o caractere ‘&’ no código ASCII. A figura 1.11 apresenta um exemplo. Qual é a finalidade deste texto?


a) Explicar como interpretar padrões de bits.
b) Demonstrar a flexibilidade da linguagem C.
c) Apresentar exemplos de cálculos com números binários.
d) Descrever a criação da linguagem C.
e) Nenhuma das alternativas anteriores.

What are the 32 reserved keywords in the ANSI C standard?

A linguagem C é classificada como linguagem de alto nível somando-se as funcionalidades de linguagens de baixo nível.
A linguagem C é uma linguagem estruturada.
O padrão C ANSI determina 32 palavras-chave ou palavras reservadas que, combinadas com a sintaxe formal de C, formam a linguagem de programação C.
a) Apenas a afirmativa I está correta.
b) Apenas a afirmativa II está correta.
c) Apenas a afirmativa III está correta.
d) As afirmativas I, II e III estão corretas.

Em C, há cinco tipos básicos de dados: caractere, inteiro, ponto flutuante, ponto flutuante de precisão dupla e sem valor: char, int, float, double e void, respectivamente. O tamanho e a faixa desses tipos de dados variam de acordo com o tipo de processador e com a implementação do compilador em C. O padrão C ANSI estipula apenas a faixa mínima de cada tipo de dado, não o seu tamanho em bytes (tabela 2.2). O tipo void declara explicitamente uma função que não retorna valor algum ou cria ponteiros genéricos. Em algumas situações é necessário modificar um tipo básico para atender às necessidades de diversas situações. Isto é conseguido através do uso de modificadores que alteram o significado de um tipo básico. Exceto o tipo void, todos os demais tipos básicos podem ter vários modificadores precedendo-os. Os modificadores podem ser: signed unsigned long short. Tabela 2.2 Tipos de dados definidos no padrão C ANSI. Tipo Tamanho (bits) Faixa mínima char 8 -127 a 127 unsigned char 8 0 a 255 signed char 8 -127 a 127 int 16 -32.767 a 32.767 unsigned int 16 0 a 65.535 signed int 16 -32.767 a 32.767 short int 16 -32.767 a 32.767 unsigned short int 16 0 a 65.535 signed short int 16 -32.767 a 32.767 long int 32 -2.147.483.647 a 2.147.483.647 signed long int 32 -2.147.483.647 a 2.147.483.647 unsigned long int 32 0 a 4.294.967.295 float 32 Seis dígitos de precisão double 64 Dez dígitos de precisão long double 80 Dez dígitos de precisão. 2.5 Variáveis Variável é uma posição nomeada de memória utilizada para armazenar um valor que pode ser modificado pelo programa. As variáveis devem ser declaradas da seguinte forma: ; int x;. 2.5.1 Classe de Variáveis As variáveis podem ser declaradas em três lugares básicos: dentro de funções, na definição dos parâmetros das funções e fora de todas as funções, ou seja, variáveis locais, parâmetros formais e variáveis globais. Por exemplo: 23 1. #include 2. #include 3. 4. float g; /*g é variável global*/ 5. 6. float soma10(float c); /*c é parâmetro formal*/ 7. 8. int main(void) 9. { 10. float x; /*x é variável local*/ 11. x=15; 12. g=soma10(x); 13. printf(“g=%f”,g); 14. return(0); 15. } 16. 17. float soma10(float c) 18. { 19. return(c+10); 20. } 2.6 Operadores 2.6.1 Atribuição O operador de atribuição pode ser utilizado dentro de qualquer expressão válida em C. A forma geral do operador de atribuição é: nome_da_variavel = expressão; x = 10; A atribuição é válida para variáveis de tipos diferentes, ou seja, é possível converter os tipos de forma automática. Esta conversão é conhecida como conversão de tipos, porém deve-se observar que poderá ocorrer uma possível perda de informação. Em C, é permitido atribuição do mesmo valor para muitas variáveis em uma única expressão: var1 = var2 = var3 = expressão; x = y = z = 0; 2.6.2 Aritméticos Os operadores aritméticos de C são: - Subtração + Adição * Multiplicação / Divisão % Módulo da divisão (resto). 2.6.3 Incremento e Decremento C inclui dois operadores que geralmente não são encontrados em outras linguagens: -- Decremento ++ Incremento radores relacionais e lógicos. Operadores relacionais Operadores lógicos > Maior que && AND >= Maior ou igual || OR < Menor ! NOT <= Menor ou igual == Igual != Diferente. É permitido combinar diversas operações em uma expressão, por exemplo: 10>5&&!(10<9)||3<=4 Verdadeiro. Tabela 2.4 Tabela verdade operadores lógicos. p q p&&q p||q !p 0 0 0 0 1 0 1 0 1 1 1 1 1 0 0 0. 2.6.5 Bit a Bit A linguagem C oferece um completo conjunto de operadores bit a bit, isto é, testar, atribuir ou deslocar os bits efetivos em um byte (tabela 2.5). A tabela 2.6 apresenta a tabela verdade dos operadores bit a bit. Tabela 2.5 Operadores bit a bit. & AND | OR ^ XOR ~ Complemento de um >> Deslocamento à esquerda << Deslocamento à direita.
Quais são os cinco tipos básicos de dados em C?
O que é o tipo void em C?
O que são modificadores em C?
O que é uma variável em C?
Quais são as três classes de variáveis em C?
O que é o operador de atribuição em C?
Quais são os operadores aritméticos em C?
O que são os operadores relacionais e lógicos em C?
O que são os operadores bit a bit em C?

Qual é a função da biblioteca stdio.h que é utilizada para abrir um arquivo?

A função fopen() é utilizada para abrir um arquivo.

Qual é o modo de abertura de arquivo que é utilizado para criar um arquivo texto para escrita?

O modo de abertura de arquivo utilizado para criar um arquivo texto para escrita é o 'w'.

Qual é a função da biblioteca stdio.h que é utilizada para fechar um arquivo?

A função fclose() é utilizada para fechar um arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para escrever argumento em um arquivo?

A função fprintf() é utilizada para escrever argumento em um arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para posicionar o arquivo em um byte específico?

A função fseek() é utilizada para posicionar o arquivo em um byte específico.

Qual é a macro definida em stdio.h que é utilizada para posicionar o arquivo no início do arquivo?

A macro SEEK_SET é utilizada para posicionar o arquivo no início do arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para ler argumento de um arquivo?

A função fscanf() é utilizada para ler argumento de um arquivo.

Qual é a função da biblioteca stdio.h que é utilizada para ler count blocos de num_bytes de arq para buffer?

A função fread() é utilizada para ler count blocos de num_bytes de arq para buffer.

PROGRAMAÇÃO DE COMPUTADORES Utilizando Linguagem C-ANSI. What is the topic covered in section 1.8 of this material?

a. Tipos de compiladores.
b. Tipos de paradigmas de programação.
c. Tipos de dados.
d. Tipos de linguagens de programação.

Prévia do material em texto

PROGRAMAÇÃO DE 
COMPUTADORES 
Utilizando Linguagem C-ANSI 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Versão 2.1 - 2007 
 2
SUMÁRIO 
Sumário................................................................................................................................................2 
Prefácio................................................................................................................................................6 
1. Introdução ...................................................................................................................................7 
1.1 Dados, Informações e Conhecimento.................................................................................................7 
1.2 Lógica de Programação ......................................................................................................................7 
1.3 Algoritmos e Estrutura de Dados.......................................................................................................8 
1.4 Representação da Lógica ....................................................................................................................9 
1.4.1 Diagrama de Fluxo........................................................................................................................10 
1.4.2 Diagrama de Chappin ou Nassi-Schneiderman (NS).................................................................11 
1.4.3 Português Estruturado .................................................................................................................12 
1.5 Linguagem de Programação.............................................................................................................13 
1.6 Compiladores e Interpretadores ......................................................................................................14 
1.7 Paradigma de Programação: Programação Estruturada..............................................................14 
1.8 Tipos de Dados...................................................................................................................................15 
1.8.1 Tipo Inteiro....................................................................................................................................15 
1.8.1.1 Sistema de Numeração Binária....................................................................................................16 
1.8.1.2 Decimal Codificado em Binário ...................................................................................................17 
1.8.2 Tipo Real........................................................................................................................................17 
1.8.3 Tipo Caractere ..............................................................................................................................17 
1.8.4 Tipo Lógico ....................................................................................................................................18 
1.8.5 Observações Finais........................................................................................................................18 
1.9 Exercícios ...........................................................................................................................................18 
2. A Linguagem C..........................................................................................................................20 
2.1 Introdução..........................................................................................................................................20 
2.2 Sintaxe da Linguagem C...................................................................................................................20 
2.3 Identificadores ...................................................................................................................................21 
2.4 Tipos de Dados...................................................................................................................................22 
2.5 Variáveis.............................................................................................................................................22 
 3
2.5.1 Classe de Variáveis .......................................................................................................................22 
2.6 Operadores.........................................................................................................................................23 
2.6.1 Atribuição ......................................................................................................................................23 
2.6.2 Aritméticos.....................................................................................................................................23 
2.6.3 Incremento e Decremento ............................................................................................................23 
2.6.4 Relacionais e Lógicos ....................................................................................................................24 
2.6.5 Bit a Bit ..........................................................................................................................................24 
2.6.6 Outros Operadores .......................................................................................................................25 
2.6.7 Precedência....................................................................................................................................25 
3. Fluxo de Controle......................................................................................................................26 
3.1 Comando de Seleção: if...else/switch................................................................................................26 
3.2 Comando de Iteração: for/while/do...while .....................................................................................26 
3.3 Comando de Desvio...........................................................................................................................27 
3.4 Outros Comandos..............................................................................................................................28 
4. Entrada e Saída .........................................................................................................................29 
4.1 Exercícios ...........................................................................................................................................29 
5. Vetores e Matrizes .....................................................................................................................34 
5.1 Exercícios ...........................................................................................................................................34 
6. Manipulação de “Strings” ........................................................................................................38 
6.1 Exercícios ...........................................................................................................................................38 
7. Estruturas, Enumerações e Uniões ..........................................................................................40 
7.1 Estruturas ..........................................................................................................................................40 
7.2 Enumerações......................................................................................................................................41 
7.3 Uniões .................................................................................................................................................41 
7.4 Exercícios ...........................................................................................................................................42 
8. Ponteiros....................................................................................................................................44 
8.1 Exercícios ...........................................................................................................................................45 
9. Ponteiros, Vetores e Matrizes....................................................................................................46 
9.1 Vetores e Matrizes de Ponteiros.......................................................................................................46 
 4
9.2 Exercícios ...........................................................................................................................................47 
10. Funções......................................................................................................................................48 
10.1 Ponteiros para Funções.....................................................................................................................48 
10.2 Recursividade ....................................................................................................................................49 
10.3 Função main.......................................................................................................................................50 
10.4 Funções de String ..............................................................................................................................50 
10.5 Funções Matemáticas ........................................................................................................................52 
10.6 Funções de Hora e Data ....................................................................................................................55 
10.7 Outras Funções..................................................................................................................................56 
10.8 Exercícios ...........................................................................................................................................56 
11. Alocação Dinâmica ...................................................................................................................59 
11.1 Exercícios ...........................................................................................................................................60 
12. Manipulação de Arquivos .........................................................................................................62 
12.1 “Streams” e Arquivos .......................................................................................................................62 
12.2 Tipos de Acesso..................................................................................................................................63 
12.3 Funções Manipulação de Arquivos..................................................................................................63 
12.4 Exercícios ...........................................................................................................................................66 
13. Ordenação..................................................................................................................................68 
13.1 Ordenação por Troca........................................................................................................................68 
13.2 Ordenação por Seleção .....................................................................................................................69 
13.3 Ordenação por Inserção ...................................................................................................................69 
13.4 “Shell Sort” ........................................................................................................................................70 
13.5 “Quicksort”........................................................................................................................................70 
14. Estruturas de Dados ..................................................................................................................72 
14.1 Pilhas ..................................................................................................................................................72 
14.2 Filas.....................................................................................................................................................73 
14.2.1 Filas Circulares .............................................................................................................................73 
14.3 Listas Ligadas ....................................................................................................................................74 
14.3.1 Listas Singularmente Ligadas......................................................................................................74 
 5
14.3.2 Listas Duplamente Ligadas..........................................................................................................77 
14.4 Árvores Binárias................................................................................................................................79 
14.5 Exercícios...............................................................................................................................81 
15. Bibliografia................................................................................................................................82 
16. APÊNDICE ...............................................................................................................................83 
16.1 Tabela ASCII .....................................................................................................................................83 
16.2 Sistema Numérico..............................................................................................................................84 
16.3 Conversão entre Bases ......................................................................................................................85 
 
 
 
 6
PREFÁCIO 
Esta apostila é destinada aos alunos das disciplinas de Programação de Computadores I 
e II do curso de Ciência da Computação. Neste texto, encontra-se, de forma resumida, os conceitos 
básicos da linguagem de programação C, estruturas de dados e técnicas de programação baseado no 
livro texto e nas referências bibliográficas complementares. 
Quaisquer dúvidas, críticas e sugestões serão bem vindas. 
 
Prof. Me. Francisco Yastami Nakamoto 
emaito: yastami@unifieo.br 
Atualizado em: 01/02/2007 
 7
1. INTRODUÇÃO 
1.1 Dados, Informações e Conhecimento. 
O homem possui a capacidade de analisar as informações fornecidas pelos seus 
sentidos, abstrair os problemas do mundo real e criar um modelo desse problema. Além disso, 
possui a capacidade de estudar e aplicar as possíveis soluções a este modelo, de acordo com o 
conhecimento anteriormente adquirido, e implementá-lo no mundo real modificando o meio em que 
vive e, consequentemente, enriquecendo o seu conhecimento através dos resultados obtidos. 
De acordo com Aristóteles (384-322 a.C.), baseado na teoria das idéias de Platão (427-
347 a.C.), a idéia não existe antes da experiência vivida, ou seja, não existe nada na consciência que 
não tenha sido sentido pelos nossos cinco sentidos. Todas as idéias e pensamentos entram em nossa 
consciência através da vivência através dos sentidos tornando-se conhecimento. 
O conhecimento é individual e único que criamos a partir da interação com outros seres 
humanos e o meio em que vivemos, consequentemente, o conhecimento não é transmissível e sim 
um conjunto de informações, representadas por dados, que descrevem o conhecimento. Desta 
forma, pode-se definir que: 
• Dados são entidades matemáticas, compostas por uma seqüência de símbolos 
quantificados ou quantificáveis e puramentesintática, ou seja, os dados podem ser 
descritos através de representações formais; 
• Informações são abstrações que não podem ser formalizadas através de uma teoria 
matemática ou lógica, ou seja, possui uma carga semântica que representa algo para 
alguém; 
• Conhecimento é uma abstração pessoal de algum fato experimentado ou vivenciado por 
alguém. É a vivência do objeto do conhecimento e não uma interpretação pessoal. 
Dado um problema computacional, o programador deve possuir o conhecimento do 
assunto em questão, dominar a sintaxe (dados) da linguagem de programação para elaborar a 
melhor semântica (informação) que represente no mundo computacional o conhecimento aplicado 
para a solução do problema, ou seja, programar é a arte de elaborar soluções computacionais 
eficazes, eficientes e elegantes. 
 
1.2 Lógica de Programação 
Todos os dias tomamos decisões das mais variadas possíveis. Muitas destas decisões 
são resultado de um conjunto de ações que visam um resultado almejado. A lógica faz parte de 
 8
nossas decisões. Entende-se por lógico o que não permite questionamento, o que é coerente, o que é 
óbvio e certo. A lógica de programação em processamento de dados é a forma pela qual se 
representa em uma linguagem, ou símbolos que expressam essa linguagem, instruções que são 
executados por um computador. 
A lógica de programação é diretamente influenciada pela forma como raciocinamos, ou 
seja, dado um problema de processamento de dados os passos realizados para a análise podem 
deve-se realizar uma análise seguindo os seguintes passos: 
a) Entender o problema proposto; 
b) Definir os objetivos a serem alcançados; 
c) Verificar todos os dados disponíveis para resolvê-lo; 
d) Estabelecer uma seqüência de ações para resolução do problema; 
e) Dividir o problema em partes menores, se necessário; 
f) Rever os passos anteriores caso o objetivo não seja atingido. 
 
1.3 Algoritmos e Estrutura de Dados 
Um computador é uma máquina que manipula dados. Segundo a teoria da informação: 
 
“...a informação é a medida da redução da incerteza sobre um determinado estado de coisas por 
intermédio de uma mensagem. Neste sentido, a informação não deve ser confundida com o significado e 
apresenta-se como função direta do grau de originalidade, imprevisibilidade ou valor-surpresa da 
mensagem, sendo quantificada em bits de informação...” 
 
A unidade básica que representa a informação é o bit, cujo valor compreende um entre 
duas possibilidades mutuamente exclusivas. Um bit é uma contração das palavras binary digit ou 
dígitos binários. Os dígitos binários 0 e 1 são usados para representar os dois possíveis estados de 
determinado bit. 
Um programa processa dados, isto é, entra-se com os dados no programa que os 
processa e, disponibiliza a informação processada. Um programa é constituído de algoritmos e 
estrutura de dados, ou seja, a estrutura de dados recebe as informações e o algoritmo processa-os. 
As estruturas de dados são organizações conceituais de informações, isso é, organizam 
as informações que representam uma situação real. Uma estrutura de dados permite apresentar uma 
forma mais compreensível de se observar as informações, oferecendo, assim, um nível de abstração 
na solução de problemas, porém, de acordo com a forma da organização, pode comprometer a 
eficiência do algoritmo que manipula essa informação. 
Um algoritmo é descrito na literatura como: 
 9
 
“ ...uma série de passos organizados que descrevem um processo que se deseja seguir para dar solução a 
um problema específico... ” 
 
considerando-se que: 
 
“ ...é uma seqüência finita de instruções, cada uma das quais possuem um significado claro e pode ser 
executada com uma quantidade finita de esforço ao longo de um tempo também finito... ” 
 
Desta foram, defini-se que os algoritmos são instruções que descrevem um padrão de 
comportamento expresso em termos de um conjunto finito de ações, ou seja, é um conjunto 
seqüencial de ações executáveis ao longo de um tempo finito para obtenção de uma solução para 
um determinado tipo de problema. 
 
1.4 Representação da Lógica 
O algoritmo é a representação da resolução lógica de um problema de processamento de 
dados. Considerando-se as definições apresentadas anteriormente, um algoritmo é um conjunto 
finito instruções seqüenciais, executados num determinado período de tempo, que atinge um 
objetivo pré-estabelecido. 
Por exemplo, um encontro de amigos na residência do casal Leila e Francisco. Sendo 
anfitrião do evento, o casal está preparando café para servir aos convidados. 
As seguintes perguntas devem ser respondidas: 
a) Qual é o problema? 
b) Qual é o objetivo? 
c) Como atingir o objetivo? 
O problema é servir o café aos convidados, mas para isso é preciso do café, então o 
objetivo principal é fazer o café. Então, determina-se os passos seqüenciais para fazer o café: 
Encher água na chaleira; 
Colocar a chaleira para ferver; 
Preparar porta-filtro com filtro sobre o bule; 
Colocar café em pó no filtro; 
Se a água ferver, acrescentar aos poucos a água no filtro; 
Aguardar o processo de coar; 
Adoçar o café. 
Seguindo os passos apresentados, certamente o objetivo será alcançado. Entretanto, 
observando-se a seqüência proposta, é possível prever passos essenciais que podem comprometer a 
resolução do problema. Por exemplo: 
1. Encher água na chaleira; 
2. Colocar a chaleira para ferver; 
 10
3. Enquanto a chaleira está no fogo: 
.Preparar porta-filtro com filtro sobre o bule; 
.Se houver café em pó: 
.Colocar café em pó no filtro; 
.Do contrário: 
Desligue o fogo; 
Providenciar o café em pó; 
Se não houver café em pó: 
Encerrar o preparo do café; 
Do contrário: 
Voltar para o item 1.; 
4. Se a água ferver, acrescentar aos poucos a água no filtro; 
5. Aguardar o processo de coar; 
6. Adoçar o café. 
Definido a seqüência de passos, determina-se o que é preciso para executar a seqüência. 
Desta forma, tem-se: 
Pó de café, água, chaleira, fogão, açúcar, porta-filtro, filtro e bule 
Finalmente, com os dados de entrada e a execução da seqüência, o resultado é o café 
pronto. Desta descrição é o algoritmo “fazer café”. Um algoritmo é escrito utilizando uma 
linguagem de programação ou por meio de diagrama de fluxo, diagrama de Chapin ou português 
estruturado. 
 
1.4.1 Diagrama de Fluxo 
Um diagrama de fluxo é uma representação gráfica de um algoritmo, ou seja, é 
realizado um detalhamento dos passos lógicos de um determinado processamento de forma gráfica. 
Os símbolos para a representação gráfica são padronizados pela ANSI (figura 1.1). A figura 1.2 
apresenta um exemplo de um programa. 
 
 
 
 
 
 
 
 
 
 
 
Figura 1.1 - Principais formas geométricas usadas em diagrama de fluxo. 
 
 
 
Indica início ou final do 
diagrama de fluxo 
Operação de atribuição e 
chamada ou retorno de 
subalgoritmo 
Operação de saída de dados 
em vídeo 
Decisão 
Arco de fluxo 
de dados Conector de fluxo Operação de entrada de dados
Conectores de páginas
 11
 
 
 
 
 
 
 
 
 
 
 
 
 
Figura 1.2 - Exemplo de um diagrama de fluxo. 
 
 
1.4.2 Diagrama de Chappin ou Nassi-Schneiderman (NS) 
O diagrama de Chapin (Nassi-Schneiderman) é um diagrama em que se retiram-se os 
arcos, apresentando-se uma visão hierárquica e estruturada da lógica do programa. A grande 
vantagem de usar este tipo de diagrama é a representação das estruturas que tem um ponto de 
entrada e um ponto de saída e são compostas pelas estruturas básicas de controle de seqüência, 
seleção e repartição. Enquanto é difícil mostrar a recursividade no diagrama de fluxo, torna-se mais 
simples mostrá-lo com o diagrama de Chapin, bem como codificá-lo futuramente na conversão de 
código português estruturado ou pseudocódigos. A figura 1.3 apresenta os diagramas de Chapin. 
 
 
 
 
 
 
 
 
 
Figura 1.3 - Os diagramas de Chapin (Nassi-Schneiderman). 
 
<Comando> 
N S 
<?><Condição>
<Condição>
Seqüência 
Seleção 
Interação 
<?>
1 2 3 4 
Início 
M = (N1 + N2)/2 
M>=6 
Fim 
S 
N
Leia N1 e 
N2
Imprima 
“Reprovado” 
Imprima 
“Aprovado” 
 12
A figura 1.4 apresenta um exemplo do tipo de diagrama de Chapin para o algoritmo de 
cálculo da média de um aluno. 
 
 
 
 
 
 
 
 
Figura 1.4 - Exemplo de um diagrama Chapin (Nassi-Schneiderman). 
 
1.4.3 Português Estruturado 
Esta forma de representação de algoritmos, também conhecida como “portugol” ou 
pseudo-código, é bastante rica em detalhes e, por assemelhar-se bastante à forma em que os 
programas são escritos, encontra muita aceitação. De fato, esta representação é suficientemente 
geral para permitir que a tradução de um algoritmo nela representado para uma linguagem de 
programação específica seja praticamente direta. 
A representação de um algoritmo na forma de pseudo-código é a seguinte: 
Algoritmo <nome_do_algoritmo> 
<declaração_de_variáveis> 
<subalgoritmos> 
Início 
<corpo_do_algoritmo> 
Fim. 
Onde: 
 Algoritmo é uma palavra que indica o início da definição de um algoritmo em forma de 
pseudocódigo. 
 <nome_do_algoritmo> é um nome simbólico dado ao algoritmo com a finalidade de distinguí-
lo dos demais. 
 <declaração_de_variáveis> consiste em uma porção opcional onde são declaradas as variáveis 
globais usadas no algoritmo principal e, eventualmente, nos subalgoritmos. 
 <subalgoritmos> consiste de uma porção opcional do pseudocódigo onde são definidos os 
subalgoritmos. 
 Início e Fim são respectivamente as palavras que delimitam o início e o término do conjunto de 
instruções do corpo do algoritmo. 
A figura 1.5 apresenta um exemplo utilizando pseudo-código. 
Início 
Leia N1, N2 
Média = (N1+N2)/2 
Média >=7? 
Escreva 
“Aprovado” 
Escreva 
“Aprovado” 
Fim 
S N
 13
 
 
 
 
 
 
 
 
 
Figura 1.5 - Exemplo de um programa em pseudo-código. 
 
1.5 Linguagem de Programação 
Um programa de computador é um conjunto instruções que representam um algoritmo 
para a resolução de algum problema. Estas instruções são escritas através de um conjunto de 
códigos (símbolos e palavras). Este conjunto de códigos possui regras de estruturação lógica e 
sintática própria. Dizemos que este conjunto de símbolos e regras formam uma linguagem de 
programação. Podemos dividir, genericamente, as linguagens de programação em dois grandes 
grupos: as linguagens de baixo nível e as de alto nível. 
Linguagens de baixo nível são linguagens voltadas para a máquina, isto é, são escritas 
usando as instruções do microprocessador do computador. São genericamente chamadas de 
linguagens Assembly. A principal vantagem é que os programas são executados com maior 
velocidade de processamento ocupando menos espaço na memória. A desvantagem é que em geral, 
os programas em Assembly tem pouca portabilidade, isto é, um código gerado para um tipo de 
processador não serve para outro. Além disso, os códigos Assembly não são estruturados, tornando 
a programação mais difícil. 
Linguagens de alto nível são linguagens voltadas para o ser humano. Em geral utilizam 
sintaxe estruturada tornando seu código mais legível. Necessitam de compiladores ou 
interpretadores para gerar instruções do microprocessador. Interpretadores fazem a interpretação de 
cada instrução do programa fonte executando-a dentro de um ambiente de programação, Basic e 
AutoLISP por exemplo. Compiladores fazem a tradução de todas as instruções do programa fonte 
gerando um programa executável. Estes programas executáveis (*.exe) podem ser executados 
fora dos ambientes de programação. Um programa executável contém uma seqüência de instruções 
que podem ser executados pelo processador. Neste formato executável, as instruções são bem 
primitivas, basicamente soma e subtração e funções de leitura e armazenamento. A linguagem de 
Algoritmo Média 
Declare N1, N2, Média Real 
Início 
Leia N1, N2 
Média ← (N1+N2)/2 
Se Média >=7 
 Então 
 Escreva “Aprovado” 
 Do contrário 
 Escreva “Reprovado” 
Fim 
 14
máquina é complexa para maioria das pessoas, dessa forma usamos uma linguagem de um nível 
maior para escrever nossos programas. 
As linguagens de alto nível podem se distinguir quanto a sua aplicação em genéricas 
como C, Pascal e Basic ou específicas como Fortran (cálculo matemático), GPSS (simulação), LISP 
(inteligência artificial) ou CLIPPER (banco de dados). A principal vantagem é que os programas 
podem ser compiladas ou interpretadas tornando-os portáveis, isto é, podem ser executados em 
varias plataformas com pouquíssimas modificações. Em geral, a programação torna-se mais fácil 
por causa do maior ou menor grau de estruturação de suas linguagens. A desvantagem é que em 
geral, as rotinas geradas (em linguagem de maquina) são mais genéricas e portanto mais complexas 
e por isso são mais lentas e ocupam mais memória. 
 
1.6 Compiladores e Interpretadores 
Os termos compiladores e interpretadores referem-se à maneira como um programa é 
executado. 
Um interpretador lê o código fonte do programa linha por vez e executando a instrução 
específica contida nesta linha. Desta forma, a execução do programa depende da presença do 
interpretador na máquina. 
Um compilador lê o programa inteiro e converte-o em um código objeto (código binário 
ou código de máquina), que é uma tradução do código fonte do programa em uma forma que o 
computador possa executar diretamente. 
 
1.7 Paradigma de Programação: Programação Estruturada 
Os recursos computacionais são compostos por hardware e software. As inovações em 
hardware permitem desenvolver softwares cada vez mais sofisticados, permitindo-se elevar o nível 
de abstração para o desenvolvimento de soluções mais eficientes. Softwares sofisticados significam 
grandes quantidades de linhas de código, acarretando como conseqüência um árduo trabalho na 
manutenção do código. 
Dentro deste contexto, surgiu-se no início dos anos 70 o conceito de modularização de 
código que permitiu desenvolver o paradigma de programação estruturada. A linguagem estruturada 
tem como característica principal a modularização do código e dos dados, isto é, possibilita a 
criação de sub-rotinas que empregam variáveis locais. Os módulos ou sub-rotinas se interligam 
através de três mecanismos básicos: 
 15
 Seqüência: Implementa os passos de processamento necessários para descrever qualquer 
programa; 
 Seleção: Especifica a possibilidade de selecionar o fluxo de execução do processamento 
baseado em ocorrências lógicas; 
 Iteração: Permite a execução repetitiva de segmentos do programa. 
Em linguagem C, o principal componente estrutural é a função, isto é, são sub-rotinas 
ou blocos de construção em que são realizadas as atividades pré-estabelecidas. A função tem como 
objetivo conceitual realizar essas atividades adequadamente sem criar efeitos inesperados em outras 
partes do programa. Outra forma de estruturar e modularizar o código em linguagem C é pelo uso 
de blocos de código. Um bloco de código é um grupo de comandos que é tratado como uma 
unidade. 
Portanto, a modularização do código permite que os programas possam: 
 Compartilhar seções de códigos; 
 Realizar facilmente manutenções no código; 
 Facilitar a compreensão de programas através do número restrito sub-rotinas. 
 
1.8 Tipos de Dados 
O trabalho realizado por um computador é basicamente manipular os dados contidos em 
sua memória. Estes dados podem ser classificados em: 
 Instruções, que comandam o funcionamento da máquina e determinam a maneira como devem 
ser tratados os dados. 
 Dados propriamente ditos, que correspondem à porção das informações a serem processadas 
pelo computador. 
Os tipos de dados podem ser classificados em: 
 Tipos Inteiros; 
 Tipos Reais; 
 Tipos Caracteres; 
 Tipos Lógicos. 
 
1.8.1 Tipo Inteiro 
São caracterizados como tipos inteiros, os dados numéricos positivos ou negativos. 
Excluindo-se destes qualquernúmero fracionário. Como exemplo deste tipo de dado, tem-se os 
valores: 35, 0, -56, 1024 entre outros. Existe duas formas para representar números inteiros em 
binário: Sistema de numeração binária e Decimal codificado em binário. 
 
 16
1.8.1.1 Sistema de Numeração Binária 
Neste sistema, cada posição de bit representa uma potência de 2. O inteiro é 
representado por uma soma de potências de 2. Se o valor for 1 em determinada posição, a potência 
de 2 representada por essa posição de bit será incluída na soma porém, se o valor for 0, essa 
potência de 2 não será incluída na soma. A figura 1.6 apresenta um exemplo. Portanto, uma 
seqüência de bits de tamanho n pode representar um número inteiro não negativo entre 0 a 2(n-1). 
 
 
 
 
 
Figura 1.6 - Exemplo de sistema de numeração binária. 
 
A representação de inteiros negativos pode ser realizada baseado em dois métodos: 
 Notação de complemento de um: Um número negativo é representado mudando-se cada bit em 
seu valor absoluto para a definição do bit oposto (figura 1.7). Isto significa que o bit da extrema 
esquerda de um número não é mais usado para representar uma potência de 2, mas é reservado 
para o sinal do número. Portanto, uma seqüência de bits de tamanho n pode representar um 
número inteiro entre -2(n-1)+1 a 2(n-1)-1; 
 
 
 
 
Figura 1.7 - Exemplo de notação de complemento de um. 
 
 Notação de complemento de dois: Um número negativo é representado somando-se 1 à 
representação de complemento de um de um número negativo (figura 1.8). Portanto, uma 
seqüência de bits de tamanho n pode representar um número inteiro entre -2(n-1) a 2(n-1)-1. 
 
 
 
 
 
Figura 1.8 - Exemplo notação de complemento de dois. 
 
 
00100110 
1ª posição 
2ª posição 
5ª posição 
21 + 22 + 25 = 38 
(00100110)2=(38)10 (-38)10=(11011001)2 
(-38)10=(11011001)2 11011001+1=11011010=(-38)10 
 17
1.8.1.2 Decimal Codificado em Binário 
 Neste sistema, uma seqüência de bits pode ser usada para representar inteiros da 
seguinte forma: cada quatro bits representa um dígito decimal entre 0 e 9. Desta forma, uma 
seqüência representa o número formado por esses dígitos decimais na notação decimal 
convencional (figura 1.9). 
 
 
 
 
 
 
Figura 1.9 - Exemplo decimal codificado em binário. 
 
1.8.2 Tipo Real 
São caracterizados como tipos reais, os dados numéricos positivos e negativos e 
números fracionários. Como exemplo deste tipo de dado, tem-se os valores: 35, 0, -56, 1.2, -45.987 
entre outros. O método usado pelos computadores para representar números reais é a notação de 
ponto flutuante. Um número real é representado por uma mantissa vezes uma base elevada a uma 
potência de inteiro, chamada expoente. Um número real representado por uma seqüência de 32 bits 
consiste de uma mantissa de 24 bits seguida por um expoente de 8 bits de base 10 (figura 1.10). 
 
 
 
 
 
 
Figura 1.10 - Representação de ponto flutuante. 
 
1.8.3 Tipo Caractere 
São caracterizados como tipos caracteres, as seqüências contendo letras, números e 
símbolos especiais. Uma seqüência de caracteres deve ser indicada entre aspas (” ”). Este tipo de 
dado também é conhecido como alfanumérico, string, literal ou cadeia. Como exemplo deste tipo de 
dado, tem-se os valores: ”Programação”, ”Rua Alfa, 52 Apto 1”, ”Fone 574-9988”, ”04387- 030”, ” 
”, ”7” entre outros. Um caractere é representado por 8 bits. 
00100110 
6
0010 0110 
2
26 
Mantissa*baseexpoente 387,53=38753*10-2 
1111 1111 0110 1000 1001 1111 1111 1110 
 18
1.8.4 Tipo Lógico 
São caracterizados como tipos lógicos os dados com valor verdadeiro e falso, sendo 
que este tipo de dado poderá representar apenas um dos dois valores. Ele é chamado por alguns de 
tipo booleano, devido à contribuição do filósofo e matemático inglês George Boole na área da 
lógica matemática. 
 
1.8.5 Observações Finais 
A classificação apresentada acima não se aplica a nenhuma linguagem de programação 
específica; pelo contrário, ela sintetiza os padrões utilizados na maioria das linguagens. Outro 
aspecto a ser considerado é com relação à interpretação da informação. Um método de interpretar 
um padrão de bits é freqüentemente chamado tipo de dado, portanto, qualquer significado pode ser 
atribuído a determinado padrão de bits, desde que seja feito com coerência. É a interpretação de um 
padrão de bits que dá o seu significado. Por exemplo, a seqüência de bits 00100110 pode ser 
interpretada como o número 38 decimal, o número 26 hexadecimal ou o caractere ‘&’ no código 
ASCII. A figura 1.11 apresenta um exemplo. 
 
 
 
 
 
Figura 1.11 - Representação binária, hexadecimal e decimal de caracteres. 
 
1.9 Exercícios 
Construir algoritmos em português estruturado, diagrama de blocos e português 
estruturado para os seguintes exercícios: 
1. Construa um algoritmo detalhado para trocar uma lâmpada. 
2. Construa um algoritmo para fazer uma ligação telefônica. 
3. Construa um algoritmo para comer uma barra de chocolate. 
4. Construa um algoritmo para fazer o cálculo das suas despesas do mês. 
5. Calcular o número de dias existentes entre dois anos digitados pelo usuário. 
6. Dados o consumo em m3 de água dos três últimos meses, elaborar um algoritmo que calcule a 
estimativa da conta do próximo mês, sabendo-se que o preço por m3 é de R$ 3,50. 
1011001 10000001 1010011 1010100 10000001 1001101 1001001 
59 41 53 54 41 4D 49 
89 65 83 84 65 77 73 
Y A S T A M I 
 19
7. Calcular e mostrar o tempo em anos, meses, dias, horas, minutos e segundos de um ano digitado 
pelo usuário em relação ao ano atual. 
8. Elabore um algoritmo que calcule a hipotenusa de um triângulo retângulo dados as medidas dos 
dois catetos. 
9. Um automóvel tem um consumo médio de 1 litro de gasolina para cada 16 km rodados. Dados: 
Distância percorrida. Calcule a quantidade de gasolina consumida. 
10. Calcular o custo de um bolo de aniversário, sabendo-se que o preço por quilo de bolo é R$ 
16,00. Dado: Peso total do bolo. 
11. A velocidade de um ponto material é regida pela equação apresentada a seguir. Faça um 
algoritmo que calcule a velocidade v (m/s), dado uma entrada t (s). 
 
 
12. Dado: Nome, Endereço e Telefone. Construa um programa para ler e mostrar os dados digitados 
pelo usuário. 
13. Elabore um algoritmo que dado dois número fornecidos pelo usuário, fazer uma calculadora que 
pode realizar as seguintes operações: soma, subtração, multiplicação e divisão. 
14. Elabore um algoritmo que dados três números, verifique qual é o maior, o menor e a média. 
15. Elabore um algoritmo que dados 10 números reais, calcule a média aritmética. 
16. Elabore um algoritmo que apresente a tabuada de multiplicação de um número fornecido pelo 
usuário. 
17. Em uma distribuidora, sabe-se que os vinhos tipo tinto custam R$ 8,50, os de tipo branco R$ 
8,00 e o rosê R$ 9,00. Dado o tipo do vinho e a quantidade comprada, elabore um algoritmo que 
calcule o valor que o cliente vai pagar. 
18. Elabore um algoritmo que calcule a soma de dez números pares fornecidos pelo usuário. Se o 
número for ímpar, emitir mensagem informando o usuário. Emitir o resultado da soma. 
19. Construa um algoritmo para somar e contar os números pares e ímpares de 30 números inteiros 
inseridos pelo usuário. 
20. Dados: sexo e idade dos alunos. Construa um algoritmo para verificar em uma classe com 50 
alunos quantos são do sexo feminino e masculino e, quantos da classe toda são maiores que 18 
anos. Ao final mostre os resultados. 
21. Construa um algoritmo para o funcionamento de uma máquina de lavar roupa. 
22. Construa um algoritmo para o funcionamento de uma máquina de refrigerante. 
 
tv *510 +=
 20
2. A LINGUAGEM C 
2.1 Introdução 
A linguagem C é uma linguagem de altonível, genérica. O C foi criada no centro de 
pesquisas da Bell Laboratories em 1972 por Dennis Ritchie tendo como meta características de 
flexibilidade e portabilidade. Em 1983 a ANSI (American National Standards Institute) 
estabeleceu um padrão C ANSI. A linguagem C é classificada como linguagem de alto nível 
somando-se as funcionalidades de linguagens de baixo nível, isto é, C permite a manipulação de 
bits, bytes e endereços e, ao mesmo tempo, suportam o conceito de tipos de dados. 
A linguagem C é uma linguagem estruturada. 
 Outro aspecto a ser considerado, é que o padrão C ANSI estabelece 32 palavras-
chaves. São palavras reservadas que são os comandos que compõem a linguagem C. As linguagens 
de alto nível tipicamente possuem várias vezes esse número de palavras reservadas. 
A linguagem C é uma linguagem compilada. A geração do programa executável a partir 
do programa fonte obedece a uma seqüência de operações: 
 Criar o programa; 
 Compilar o programa; 
 Linkeditar o programa. 
 
2.2 Sintaxe da Linguagem C 
A sintaxe são regras detalhadas para um construção válida em linguagem C. Estas 
regras estão relacionadas com os tipos, as declarações, as funções e as expressões. 
Os tipos definem as propriedades dos dados manipulados em um programa. 
As declarações expressam as partes do programa, podendo dar significado a um 
identificador, alocar memória, definir conteúdo inicial, definir funções. 
As funções especificam as ações que um programa executa quando roda. A 
determinação e alteração de valores, e a chamada de funções de I/O são definidas nas expressões. 
As funções são as entidades operacionais básicas dos programas em C, que por sua vez 
são a união de uma ou mais funções executando cada qual o seu trabalho. Há funções básicas que 
estão definidas na biblioteca C. As funções printf() e scanf() por exemplo, permitem 
respectivamente escrever na tela e ler os dados a partir do teclado. O programador também pode 
definir novas funções em seus programas, como rotinas para cálculos, impressão, etc. Todo 
programa C inicia sua execução chamando a função main(), sendo obrigatória a sua declaração no 
 21
programa principal. Comentários no programa são colocados entre /* e */ não sendo considerados 
na compilação. Cada instrução encerra com ; (ponto e vírgula) que faz parte do comando. 
A forma geral de um programa em C é: 
 
 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int x=20; 
void func(void); 
 
int main(void) 
{ 
 int y=10; 
 printf(“Variável global x=%d\n”, x); 
 printf(“Variável y=%d\n”, y); 
 func(); 
 return(0); 
} 
 
void func(void) 
{ 
 printf(”Fim\n”); 
} 
O padrão C ANSI determina 32 palavras-chave ou palavras reservadas que, combinadas 
com a sintaxe formal de C, foram a linguagem de programação C (tabela 2.1). 
 
Tabela 2.1 Lista de palavras-chave em C ANSI 
1. auto double int struct 
break else long switch 
case enum register typedef 
char extern return union 
const float short unsigned 
continue for signed void 
default goto sizeof volatile 
do if static while 
 
Muitos compiladores acrescentam outras palavras-chaves para explorar melhor os 
recursos dos processadores e otimização da utilização da memória. 
 
2.3 Identificadores 
Identificadores são os nomes usados para referenciar objetos definidos pelos usuário, 
isto é, nomes de variáveis, funções, rótulos, entre outros. O primeiro caractere deve ser uma letra ou 
um sublinhado e os caracteres subseqüentes devem ser letras, números ou sublinhados. O padrão C 
ANSI determina que identificadores podem ter qualquer tamanho, porém em geral, dependendo do 
compilador utilizado, considera-se apenas os 31 primeiros caracteres. 
Os identificadores não podem ser igual a uma palavra-chave de C ou nome de funções 
criadas pelo usuário ou que estão nas bibliotecas C. 
Em C, letras maiúsculas e minúsculas são tratadas diferentemente. Por exemplo: 
int count, Count, COUNT; 
Logo, count, Count e COUNT são três identificadores distintos. 
Componentes Iniciais: arquivos de 
cabeçalho, declaração de constantes, 
protótipos e variáveis globais. 
Função main(): Variáveis locais e instruções 
do programa. 
Implementação de Funções: Variáveis locais 
e definição das funções 
 22
2.4 Tipos de Dados 
Em C, há cinco tipos básicos de dados: caractere, inteiro, ponto flutuante, ponto 
flutuante de precisão dupla e sem valor: char, int, float, double e void, respectivamente. O 
tamanho e a faixa desses tipos de dados variam de acordo com o tipo de processador e com a 
implementação do compilador em C. O padrão C ANSI estipula apenas a faixa mínima de cada tipo 
de dado, não o seu tamanho em bytes (tabela 2.2). O tipo void declara explicitamente uma função 
que não retorna valor algum ou cria ponteiros genéricos. 
Em algumas situações é necessário modificar um tipo básico para atender às 
necessidades de diversas situações. Isto é conseguido através do uso de modificadores que alteram o 
significado de um tipo básico. Exceto o tipo void, todos os demais tipos básicos podem ter vários 
modificadores precedendo-os. 
Os modificadores podem ser: 
signed unsigned long short 
 
Tabela 2.2 Tipos de dados definidos no padrão C ANSI. 
Tipo Tamanho (bits) Faixa mínima 
char 8 -127 a 127 
unsigned char 8 0 a 255 
signed char 8 -127 a 127 
int 16 -32.767 a 32.767 
unsigned int 16 0 a 65.535 
signed int 16 -32.767 a 32.767 
short int 16 -32.767 a 32.767 
unsigned short int 16 0 a 65.535 
signed short int 16 -32.767 a 32.767 
long int 32 -2.147.483.647 a 2.147.483.647 
signed long int 32 -2.147.483.647 a 2.147.483.647 
unsigned long int 32 0 a 4.294.967.295 
float 32 Seis dígitos de precisão 
double 64 Dez dígitos de precisão 
long double 80 Dez dígitos de precisão 
 
2.5 Variáveis 
Variável é uma posição nomeada de memória utilizada para armazenar um valor que 
pode ser modificado pelo programa. As variáveis devem ser declaradas da seguinte forma: 
<tipo> <nome_da_variavel>; int x; 
 
2.5.1 Classe de Variáveis 
As variáveis podem ser declaradas em três lugares básicos: dentro de funções, na 
definição dos parâmetros das funções e fora de todas as funções, ou seja, variáveis locais, 
parâmetros formais e variáveis globais. Por exemplo: 
 23
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. float g; /*g é variável global*/ 
5. 
6. float soma10(float c); /*c é parâmetro formal*/ 
7. 
8. int main(void) 
9. { 
10. float x; /*x é variável local*/ 
11. x=15; 
12. g=soma10(x); 
13. printf(“g=%f”,g); 
14. return(0); 
15. } 
16. 
17. float soma10(float c) 
18. { 
19. return(c+10); 
20. } 
 
2.6 Operadores 
2.6.1 Atribuição 
O operador de atribuição pode ser utilizado dentro de qualquer expressão válida em C. 
A forma geral do operador de atribuição é: 
nome_da_variavel = expressão; x = 10; 
A atribuição é válida para variáveis de tipos diferentes, ou seja, é possível converter os 
tipos de forma automática. Esta conversão é conhecida como conversão de tipos, porém deve-se 
observar que poderá ocorrer uma possível perda de informação. 
Em C, é permitido atribuição do mesmo valor para muitas variáveis em uma única 
expressão: 
var1 = var2 = var3 = expressão; x = y = z = 0; 
 
2.6.2 Aritméticos 
Os operadores aritméticos de C são: 
- Subtração 
+ Adição 
* Multiplicação 
/ Divisão 
% Módulo da divisão (resto) 
 
2.6.3 Incremento e Decremento 
C inclui dois operadores que geralmente não são encontrados em outras linguagens: 
-- Decremento 
++ Incremento 
 
 
 24
2.6.4 Relacionais e Lógicos 
O operador relacional refere-se à relação que os valores podem ter uns com os outros. O 
operador lógico refere-se à maneira como essas relações podem ser conectadas. A idéia de 
verdadeiro e falso é a base dos conceitos dos operadores lógicos e relacionais. Em C, verdadeiro é 
qualquer valor diferente de zero. Falso é zero. As expressões que usam operadores relacionais ou 
lógicos devolvem zero para falso e 1 para verdadeiro(tabela 2.3). A tabela 2.4 apresenta a tabela 
verdade dos operadores lógicos utilizando 1s e 0s. 
 
Tabela 2.3 Operadores relacionais e lógicos. 
Operadores relacionais Operadores lógicos 
> Maior que && AND 
>= Maior ou igual || OR 
< Menor ! NOT 
<= Menor ou igual 
== Igual 
!= Diferente 
 
É permitido combinar diversas operações em uma expressão, por exemplo: 
10>5&&!(10<9)||3<=4 Verdadeiro 
 
Tabela 2.4 Tabela verdade operadores lógicos. 
p q p&&q p||q !p 
0 0 0 0 1 
0 1 0 1 1 
1 1 1 1 0 
1 0 0 1 0 
 
2.6.5 Bit a Bit 
A linguagem C oferece um completo conjunto de operadores bit a bit, isto é, testar, 
atribuir ou deslocar os bits efetivos em um byte (tabela 2.5). A tabela 2.6 apresenta a tabela verdade 
dos operadores bit a bit. 
Tabela 2.5 Operadores bit a bit. 
& AND 
| OR 
^ XOR 
~ Complemento de um 
>> Deslocamento à esquerda 
<< Deslocamento à direita 
 
Tabela 2.6 Tabela verdade operadores bit a bit. 
p q p&q p|q p^q 
0 0 0 0 0 
0 1 0 1 1 
1 1 1 1 0 
1 0 0 1 1 
 
 25
2.6.6 Outros Operadores 
Tabela 2.7 Outros operadores. 
?: Exp1 ? Exp2 : Exp3 
& “o endereço de” 
* “o valor do endereço de” 
sizeof(f) Retorna o tamanho em bytes de f 
, Separa seqüência de operações 
. 
-> 
Referência a elementos 
individuais de estruturas e 
uniões. 
() Organizar precedência. 
[] Indexação de matrizes. 
 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. int x, y; 
7. printf(“Digite valor de x=”); 
8. scanf(&x); 
9. printf(“Digite valor de y=”); 
10. scanf(&y); 
11. print((x>y)? “x>y\n”:((x=y)? “x=y\n”: “x<y\n”) 
12. return(0); 
13. } 
 
2.6.7 Precedência 
Tabela 2.8 Precedência dos operadores em C. 
Maior () [] -> 
 ! ~ ++ -- * & sizeof 
 * / % 
 + - 
 << >> 
 < <= > >= 
 == != 
 & 
 ^ 
 | 
 && 
 ?: 
Menor = += -= *= 
 
 
 
 
 26
3. FLUXO DE CONTROLE 
3.1 Comando de Seleção: if...else/switch 
if (<condicao>) 
 <expressão>; 
else 
 <expressão>; 
switch (<expressão>) 
{ 
case constante1 : 
 <seq. de comandos> 
break; 
case constante2 : 
 <seq. de comandos> 
break; 
. 
. 
. 
default : 
 <seq. de comandos> 
} 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 int x, y; 
 printf(“Digite valor de x=”); 
 scanf(“%d”,&x); 
 printf(“Digite valor de y=”); 
 scanf(“%d”,&y); 
 if (x>y) 
 printf(“x>y\n”); 
 else 
 { 
 if (x=y) 
 printf(“x=y\n”); 
 else 
 printf(“x<y\n”); 
 } 
 return(0); 
} 
 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 int x; 
 printf(“Digite valor de x=”); 
 scanf(“%d”,&x); 
 switch (x) 
 { 
 case 0: 
 printf(“x=0\n”); 
 break; 
 case 1: 
 printf(“x=1\n”); 
 break; 
 case 2: 
 printf(“x=2\n”); 
 break; 
 case 3: 
 printf(“x=3\n”); 
 break; 
 default: 
 printf(“3<x<0\z”); 
 } /*Fim switch*/ 
 return(0); 
} 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 char y; 
 printf(“Escolha a, b, c ou d:”); 
 y=getchar(); 
 switch (x) 
 { 
 case ’a’: 
 printf(“Escolhido a\n”); 
 break; 
 case ’b’: 
 printf(“Escolhido b\n”); 
 break; 
 case ’c’: 
 printf(“Escolhido c\n”); 
 break; 
 case ’d’: 
 printf(“Escolhido d\n”); 
 break; 
 default: 
 printf(“Escolha invalida\n”); 
 } /*Fim switch*/ 
 return(0); 
} 
 
3.2 Comando de Iteração: for/while/do...while 
for (<inicialização>, <condição>, <incremento>) 
 <seq. de comando> 
while (<condição>) 
{ 
 <seq. de comando> 
} 
do 
{ 
 <seq. de comando> 
} while (<condição>); 
 
 27
 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 int i; 
 for (i=0; i<10; i++) 
 printf(“%d ”,i); 
 return(0); 
} 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 int i; 
 i=0; 
 while (i<10) 
 { 
 printf(“%d ”,i); 
 } 
 return(0); 
} 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 int i; 
 i=0; 
 do 
 { 
 printf(“%d ”,i); 
 } while (i<10); 
 return(0); 
} 
 
3.3 Comando de Desvio 
Na linguagem C há quatro comandos que realizam um desvio incondicional: 
• return: É usado para retorno de uma função. A função será finalizada tão logo encontre o 
primeiro return; 
• goto: É um comando de desvio que deve ser utilizado com precaução pois pode causar 
vazamento do fluxo de informação; 
• break: Este comando possui duas formas de uso. A primeira é utilizada para terminar um case 
em um comando switch. A segunda forma é utilizada para forçar uma terminação imediata de 
um laço. O comando break provoca uma saída apenas do laço mais interno; 
• exit: Este comando provoca uma terminação imediata do programa inteiro, forçando um retorno 
ao sistema operacional; 
• continue: É um comando similar ao break porém em vez de forçar a terminação do laço, 
continue força que ocorra a próxima iteração do laço, pulando qualquer código intermediário. 
Para o laço for, continue faz com que o teste condicional e a porção de incremento do laço 
sejam executados. Para os laços while e do-while, o controle do programa passa para o teste 
condicional. 
return (<expressão>); goto <rótulo>; 
... 
<rótulo>: 
void exit(int codigo_de_retorno); 
 
 28
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 int x; 
 x=1; 
 volta1: 
 x++; 
 if (x<50) 
 { 
 printf(”%d\n”,x); 
 goto volta1; 
 } 
 return(0); 
} 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 int x; 
 for (x=0; x<50; x++) 
 { 
 printf(”%d\n”,x); 
 if (x==25) break; 
 } 
 return(0); 
} 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 char s[80], *str; 
 int esp; 
 printf("Digite uma string:"); 
 gets(s); 
 str=s; 
 for (espaco=0; *str; str++) 
 { 
 if (*str!=' ') continue; 
 esp++; 
 } 
 printf("%d espacos\n", esp); 
 return (0); 
} 
3.4 Outros Comandos 
Um comando de expressão é uma expressão válida em C seguida por ponto-e-vírgula, 
por exemplo: 
soma(); /* Chamada de função */ 
a=sqrt(pow(b,2)+pow(c,2)); /* Comando de atribuição */ 
b+raiz(z); /* Comando válido, que não faz nada */ 
; /* Comando vazio */ 
 
 
 
 
 
 
 
 29
4. ENTRADA E SAÍDA 
As funções printf() e scanf() realizam entrada e saída formatada, isto é, permite a 
leitura e a escrita de dados em vários formatos. 
O printf() é uma função de I/O, que permite escrever no dispositivo padrão (tela). A 
expressão de controle pode conter caracteres que serão exibidos na tela e os códigos de formatação 
(tabela 3.1) que indicam o formato em que os argumentos devem ser impressos. Cada argumento 
deve ser separado por vírgula. 
O scanf() também é uma função de I/O implementada em todos compiladores C. Ela é o 
complemento de printf() e nos permite ler dados formatados (tabela 4.1) da entrada padrão 
(teclado). Sua sintaxe é similar a printf(). 
int printf(const char *str, ...); int scanf(const char *str, ...); 
 
Tabela 4.1 Comandos de formato para printf() e scanf(). 
Código Formato 
%c Caractere 
%d Inteiros decimais com sinal 
%i Inteiros decimais com sinal 
%e Notação científica 
%f Ponto flutuante decimal 
%o Octal sem sinal 
%s String de caracteres 
%u Inteiros decimais sem sinal 
%x Hexadecimal sem sinal 
%p Apresenta um ponteiro 
 
1. #include <stdlib.h> 
#include <stdio.h> 
 
int main(void) 
{ 
 char c; 
 int x; 
 float y; 
 c=’d’; 
 x=c; 
 y=19.234; 
 printf(’%c\n’, c); 
 printf(’%d\n’, x); 
 printf(’%f\n’, y); 
 printf(’%.3f\n’, y); 
 printf(’%.2f\n’, y); 
 printf(’%.1f\n’, y); 
 return(0); 
} 
 
4.1 Exercícios 
1. Faça um programa que receba três números inteiros, calcule e mostre a soma desses números. 
2. Faça um programa que receba três notas, calcule e mostre a média aritmética dessas notas. 
3. Faça um programa que receba três notas e seus respectivos pesos, calcule e mostre a média 
ponderada dessas notas. As notas deverão estar na faixa entre 0 e 10. 
 30
4. Faça um programa que receba o valor de um depósitoe o valor da taxa de juros, calcule e 
mostre o valor do rendimento e o valor total depois do rendimento. 
5. Faça um programa que calcule e mostre a área de um triângulo. Sabe-se que: Área = (base * 
altura)/2. 
6. Faça um programa que calcule e mostre a área de um círculo. Sabe-se que: Área = π * R2. 
(π=3,14) 
7. Faça um programa que calcule e mostre a área de um trapézio. Sabe-se que: Área = ((base maior 
+ base menor)*altura)/2. 
8. Faça um programa que calcule e mostre a área de um losango. Sabe-se que: Área = (diagonal 
maior * diagonal menor)/2. 
9. Faça um programa para calcular a área de um triângulo. Esse programa não pode permitir a 
entrada de dados inválidos, ou seja, medidas menores ou iguais a 0. 
10. Faça um programa que receba um número positivo e maior que zero, calcule e mostre: 
a) O número digitado ao quadrado; 
b) O número digitado ao cubo; 
c) a raiz quadrada do número digitado. 
11. Faça um programa que receba dois números maiores que zero, calcule e mostre um elevado ao 
outro. 
12. Faça um programa que calcule e mostre a tabuada de um número digitado pelo usuário. 
13. Faça um programa que receba o número de horas trabalhadas e o valor do salário mínimo. 
Calcule e mostre o salário a receber seguindo as regras abaixo: 
a) A hora trabalhada vale a metade do salário mínimo; 
b) O salário bruto equivalente ao número de horas trabalhadas multiplicado pelo valor da hora 
trabalhada; 
c) O imposto eqüivale a 3% do salário bruto; 
d) O salário a receber eqüivale ao salário bruto menos o imposto. 
14. Um trabalhador recebeu seu salário e o depositou em sua conta corrente bancária. Esse 
trabalhador emitiu dois cheques e agora deseja saber seu saldo atual. Sabe-se que cada operação 
bancária de retirada paga CPMF de 0,38% e o saldo inicial da conta está zerado. Elabore um 
programa que apresente os lançamentos, o total de impostos descontados e o saldo atual. 
15. Pedro comprou um saco de ração com peso em quilos. Pedro possui dois gatos para os quais 
fornece a quantidade de ração em gramas. Faça um programa que receba o peso do saco de 
ração e a quantidade de ração fornecida para cada gato. Calcule e mostre quanto restará de ração 
no saco após cinco dias. 
 31
16. Cada degrau de uma escada tem X de altura. Faça um programa que receba essa altura e a altura 
que o usuário deseja alcançar subindo a escada. Calcule e mostre quantos degraus o usuário 
deverá subir para atingir seu objetivo, sem se preocupar com a altura do usuário. 
17. Faça um programa que receba o preço de um produto, calcule e mostre o novo preço sabendo-se 
que este sofreu um desconto de 10%. 
18. Faça um programa que receba o salário-base de um funcionário, calcule e mostre o salário a 
receber, sabendo-se que esse funcionário tem gratificação de 5% sobre o salário-base e paga 
imposto de 7% sobre o salário-base. 
19. Sabe-se que um quilowatt de energia custa um quinto do salário mínimo. Faça um programa que 
receba o valor do salário mínimo e a quantidade de quilowatts consumida por uma residência. 
Calcule e mostre: 
a) O valor (R$) de cada quilowatt; 
b) O valor (R$) a ser pago por essa residência; 
c) O valor (R$) a ser pago com desconto de 15%. 
20. Faça um programa que receba o salário de um funcionário e o percentual de aumento., calcule e 
mostre o valor do aumento e o novo salário. 
21. A nota final de um estudante é calculada a partir de três notas atribuídas respectivamente a um 
trabalho de laboratório, a avaliação semestral e a um exame final. A média das três notas 
mencionadas anteriormente obedece aos pesos a seguir: 
NOTA PESO 
Trabalho de laboratório 2 
Avaliação semestral 3 
Exame final 5 
 
22. Faça um programa que receba as três notas, calcule e mostre a média ponderada e o conceito 
que segue a tabela abaixo. 
MÉDIA PONDERADA CONCEITO 
10,0 <= media <= 8,0 A 
8,0< media <= 7,0 B 
7,0 < media <= 6,0 C 
6,0 < media <= 5,0 D 
5,0 < media E 
 
23. Faça um programa que receba três notas de um aluno, calcule e mostre a médias aritmética e a 
mensagem que segue a tabela abaixo. Para alunos de exame, calcule e mostre a nota que deverá 
ser tirada no exame para a aprovação, considerando que a média no exame é 6,0. 
MÉDIA ARITMÉTICA MENSAGEM 
3,0 > media Reprovado 
3,0 <= media < 7,0 Exame 
7,0 <= media Aprovado 
24. Faça um programa que receba dois números e mostre o maior. 
25. Faça um programa que receba três números e mostre-os em ordem crescente. 
 32
26. Faça um programa que receba três números inteiros em ordem crescente e um quarto número 
também inteiro que não siga esta regra. Mostre, em seguida, os quatro números em ordem 
decrescente. Deve-se verificar se os três primeiros números estão em ordem crescente 
27. Faça um programa que receba um número inteiro e verifique se esse número é par ou ímpar. 
28. Elabore um programa que calcule as raízes de uma equação a segundo grau. 
 
 
 
 
 
 
29. Faça um programa que mostre o menu de opções a seguir, receba a opção do usuário e os dados 
necessários para executar cada operação. 
Menu de opções: 
1: Somar dois números 
2: Raiz quadrada de um número 
Digite a opção desejada: 
 
30. Faça um programa que determine a data cronologicamente maior de duas datas fornecidas pelo 
usuário. Cada data deve ser fornecida por três valores inteiros, onde o primeiro representa o dia, 
o segundo o mês e o terceiro o ano. 
31. Faça um programa que receba o código correspondente ao cargo de um funcionário e seu salário 
atual e mostre o cargo, o valor do aumento e seu novo salário. Os cargos estão na tabela a 
seguir: 
CÓDIGO CARGO PERCENTUAL 
1 Escriturário 50% 
2 Secretário 35% 
3 Caixa 20% 
4 Gerente 10% 
5 Diretor Não tem aumento 
 
32. Faça um programa que receba o salário de um funcionário, calcule e mostre o novo salário desse 
funcionário, acrescido de bonificação e de auxílio-escola. 
SALÁRIO BONIFICAÇÃO SALÁRIO AUXÍLIO-ESCOLA 
Até R$ 500,00 5% Até R$ 600,00 R$ 150,00 
Entre R$ 500,00 e R$ 1200,00 12% Mais que R$ 600,00 R$ 100,00 
Acima de R$ 1200,00 Sem bonificação 
 
33. Faça um programa que leia um número indeterminado de valores para m, todos inteiros e 
positivos, um de cada vez. Se m for par, verifique quantos divisores possui. Se m for ímpar, 
calcule a soma dos números inteiros de 1 até m (m não deve entrar nos cálculos). Mostre os 
cálculos realizados. 
a
b
x
cab
xf
cxbxaxf
*2
**4
0)(
**)(
2,1
2
2
∆±−
=
−=∆
=
++=
 33
34. Faça um programa que calcule o fatorial de um número inteiro fornecido pelo usuário. 
 
 
 
 
35. Faça um programa que leia o número de termos n e um valor positivo para x, calcule e mostre o 
valor da série a seguir: 
 
 
36. Faça um programa que monte os n primeiros termos da seqüência de Fibonacci. 
 
 
37. Faça um programa que leia o número de termos e um valor positivo para X, calcule e mostre o 
valor da série a seguir: 
 
 
38. Faça um programa que calcule a soma dos primeiros 50 números pares iniciando de 2. 
39. Faça um programa que mostre os primeiros 50 números múltiplos de 2 iniciando de 2. 
40. Faça um programa que calcule a soma dos primeiros 50 números ímpares iniciando de 3. 
41. Faça um programa que mostre os primeiros 50 números múltiplos de 3 iniciando de 3. 
42. Faça um programa que leia dois valores inteiros e positivos: x e y, calcule e mostre a potência 
x
y, utilizando uma estrutura de repetição. 
43. Faça um programa que receba o ângulo de incidência dos raios solares, a altura de uma pessoa 
em metros e retorne o comprimento da sombra dessa pessoa conforme a figura abaixo. 
 
 
 
 
 
 
 
 
!
...
!7!6!5!4!3!2!1
7654321
n
xxxxxxxx
S
n
++++++++=
...553421138532110 −−−−−−−−−−−
!
...
!9!8!7!6!5!4!3
1
18765432
n
xxxxxxxx
S
n−
+++++++++=
1!0 :0 se
1!1 :1 se
1*2*3*...*)2(*)1(* :1 se
===
===
−−=>
n!n
n!n
nnnn!n
 34
5. VETORES E MATRIZES 
Matriz é uma coleção de variáveis do mesmo tipo referenciada por um nome comum. Oacesso aos elementos é realizado mediante um índice ou pelo endereço. O endereço mais baixo ou 
índice (0) corresponde ao primeiro elemento e o mais alto, ao último elemento. As matrizes podem 
possuir várias dimensões. 
Matrizes unidimensionais, ou vetores, são matrizes que possuem apenas uma dimensão. 
Os vetores são, essencialmente, listas de informações do mesmo tipo, que são armazenadas em 
posições contíguas da memória em uma ordem de índice. A figura 5.1 apresenta um exemplo de 
matriz unidimensional. Considerando-se que cada bloco armazena um único caractere, a matriz no 
exemplo pode armazenar nove caracteres seqüenciais. 
 
 
 
 
 
 
Figura 5.1 - Exemplo notação de complemento de dois. 
 
Matrizes multidimensionais são matrizes que possuem duas ou mais dimensões. A 
forma mais simples é a matriz bidimensional ou matriz linha-coluna, onde o primeiro índice indica 
a linha e o segundo, a coluna. 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. int v[10], i; 
7. for (i=0; i<10; i++) 
8. { 
9. printf("Digite v[%d]=",i); 
10. scanf("%d",&v[i]); 
11. } 
12. for (i=0; i<10; i++) 
13. { 
14. printf("Endereco: %p, ",v[i]); 
15. printf("v[%d]=%d\n",i,v[i]); 
16. } 
17. return(0); 
18. } 
2. #include <stdlib.h> 
3. #include <stdio.h> 
4. 
5. int main(void) 
6. { 
7. int v[3][3], i, j; 
8. for (i=0; i<3; i++) 
9. for (j=0; j<3; j++) 
10. { 
11. printf("Digite [%d,%d]=",i ,j); 
12. scanf("%d",&v[i][j]); 
13. } 
14. for (i=0; i<3; i++) 
15. { 
16. printf("\n"); 
17. for (j=0; j<3; j++) 
18. printf("%d ",v[i][j]); 
19. } 
20. printf("\n"); 
21. return(0); 
22. } 
 
5.1 Exercícios 
1. Faça um programa que carregue uma matriz 2x2, calcule e mostre uma matriz resultante que 
será a matriz digitada multiplicada pelo maior elemento da matriz. 
 35
2. Faça um programa que carregue uma matriz 10x3 com as notas de dez alunos em três provas. 
Mostre um relatório com o número do aluno (número da linha) e a prova em que cada aluno 
obteve menor nota. Ao final do relatório, mostre quantos alunos tiveram menor nota na prova 1, 
quantos alunos tiveram menor nota na prova 2 e quantos alunos tiveram menor nota na prova 3. 
3. Faça um programa que carregue uma matriz 10x20 com números inteiros e some cada uma das 
linhas, armazenando o resultado das somas em um vetor. A seguir, multiplique cada elemento 
da matriz pela soma da linha e mostre a matriz resultante. 
4. Na teoria dos sistemas define-se o elemento MINMAX de uma matriz como sendo o maior 
elemento da linha onde se encontra o menor elemento da matriz. Faça um programa que 
carregue uma matriz 4x7 com números reais, calcule e mostre seu MINMAX e sua posição 
(linha e coluna). 
5. Faça um programa que carregue uma primeira matriz de ordem 4x5 e uma segunda matriz 5x2, 
calcule e mostre a matriz resultante do produto matricial das duas matrizes anteriores, 
armazenando-o em uma terceira matriz de ordem 4x2. 
6. Faça um programa que carregue uma matriz 15x5 com números inteiros, calcule e mostre quais 
os elementos da matriz que se repetem e quantas vezes cada um está repetido. 
7. Faça um programa que carregue uma matriz 6x4 com números inteiros, calcule e mostre 
quantos elementos dessa matriz são maiores que 30 e, em seguida, mostre uma segunda matriz 
com os elementos diferentes de 30. No lugar do número 30 da segunda matriz coloque o número 
zero. 
8. Faça um programa que carregue uma matriz 10x10 com números inteiros, execute as trocas 
especificadas a seguir e mostre a matriz resultante. 
• A linha 2 com a linha 8; 
• A coluna 4 com a coluna 10; 
• A diagonal principal com a diagonal secundária; 
• A linha 5 com a coluna 10. 
9. Faça um programa que carregue uma matriz 8x8 com números inteiros e mostre o maior e 
menor número com as respectivas posições (linha, coluna). 
10. Faça um programa que carregue uma matriz 8x8 com números inteiros e mostre a quantidade de 
números pares e ímpares. 
11. Faça um programa que carregue uma matriz 8x8 com números reais, calcule a média de todos 
os elementos e mostre a quantidade de números que são maiores ou iguais a média e sua 
respectiva posição. 
 36
12. Faça um programa que carregue uma matriz 5x5 de números reais, calcule a média aritmética 
dos elementos e mostre todos elementos maiores ou iguais à media e sua respectiva posição na 
matriz. 
13. Faça um programa que construa a tabela apresentada a seguir em uma matriz. Dado um número 
digitado pelo usuário, exiba o mês do ano correspondente de acordo com a tabela. Emitir 
mensagem de erro se o código for inválido. 
Código Mês Código Mês 
1 Janeiro 7 Julho 
2 Fevereiro 8 Agosto 
3 Março 9 Setembro 
4 Abril 10 Outubro 
5 Maio 11 Novembro 
6 Junho 12 Dezembro 
 
14. Faça um programa que leia um vetor de 20 números inteiros. Dado uma entrada do usuário, 
verifique se há esse número no vetor, quantos números e em qual posição. 
15. Elabore um programa que calcule o produto de duas matrizes de ordem 3. 
 
 
 
 
 
16. Elabore um programa que calcule a soma e a subtração de duas matrizes A e B. 
 
 
 
17. Elabore um programa que calcule a determinante de uma matriz de ordem 2. 
 
 
 
18. Elabore um programa que calcule a determinante de uma matriz de ordem 3. 
 
 
 
 
19. Considere o triângulo de vértices A(2;1), B(5; 2) e C(3; 4) apresentado na figura a seguir. A 
área do triângulo ABC é calculada de acordo com a fórmula abaixo, onde D é a determinante da 
matriz de ordem 3, onde a primeira coluna é formada pelas abscissas dos pontos A, B e C, a 
segunda coluna é formada pelas respectivas ordenadas e a terceira coluna é unitária. Elabore um 



−
=


+−+
++
=


+


− 88
115
1935
9223
13
91
95
23
cbda
dc
ba
D ** −=


=
payncxmbznazmcypbx
pnm
cba
zyx
D ************ −−−++=








=
 37
programa que receba as coordenadas dos vértices A, B e C e calcule a área do triângulo. 
ATENÇÃO: Se a determinante D=0 então os três pontos não formam um triângulo, portanto, 
são pontos de uma mesma reta!!! 
 
 
 
 
 
 
 
20. Numa matriz quadrada, os elementos aij tais que i=j formam o que chamamos de diagonal 
principal da matriz. Elabore um programa que imprima os elementos da diagonal principal de 
qualquer matriz mxm. 
21. Dada uma matriz A(mxn), a matriz que se obtém trocando ordenadamente as linhas pelas 
colunas chama-se transposta de A, e é indicada por At (ou por A
t). Elabore um programa que 
receba uma matriz A(3x2) e crie a matriz At. 
 
 
 
DS
cc
bb
aa
D
ABC
yx
yx
yx
*
2
1
1
1
1
=








=
 38
6. MANIPULAÇÃO DE “STRINGS” 
String é uma cadeia de caracteres armazenadas uma matriz unidimensional (vetor) de 
caracteres finalizada pelo caractere nulo, ou seja, por meio de ‘\0’, isto é, indica o fim da string. 
Desta forma, deve-se declarar sempre o vetor com uma posição a mais para armazenar o caractere 
nulo. Por exemplo, a seguinte instrução declara um vetor nome que guarda uma string de 10 
caracteres: 
char nome[11]; 
Em programação, é comum o uso de matrizes de string. Para criar uma matriz de 
strings, utiliza-se uma matriz bidimensional de caracteres. O seguinte exemplo apresenta o uso de 
uma matriz de string. 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. #define MAX 10 
5. #define LEN 31 
6. 
7. char lista[MAX][LEN]; 
8. 
9. int main(void) 
10. { 
11. int i; 
12. for (i=0; i<MAX; i++) 
13. { 
14. printf(”Digite um nome:”); 
15. scanf(”%s”,lista[i]); 
16. } 
17. for (i=0; i<MAX; i++) 
18. printf(”%d - %s\n”, i+1, lista[i]); 
19. return(0); 
20. } 
 
6.1 Exercícios 
1. Faça um programa que receba uma palavra, calcule e mostre a quantidade de caracteres. 
2. Faça um programa que receba uma palavra, calcule e mostre a quantidade de vogais. 
3. Faça um programa que receba uma palavra, troquetodas as vogais por * e apresente o resultado 
4. Faça um programa que receba duas palavras e gere uma terceira que represente a combinação 
das duas anteriores. 
5. Faça um programa que receba uma palavra e coloque os caracteres em ordem crescente. 
6. Faça um programa que receba uma palavra e inverta a ordem dos caracteres. 
7. Faça um programa eu receba uma frase, calcule e mostre a quantidade de vezes que o caractere 
a aparece. 
8. Faça um programa que receba uma frase, calcule e mostre a quantidade de consoantes da frase 
digitada. 
9. Faça um programa que receba uma frase, calcule e mostre a quantidade de vogais da frase 
digitada. 
 39
10. Faça um programa que receba uma frase e mostre a quantidade total de cada caractere na frase. 
11. Faça um programa que armazene 10 nomes. 
12. Faça um programa que armazene 10 nomes. Dado uma entrada do usuário, pesquise e apresente 
se encontrado o nome (em que posição do vetor). 
13. Faça um programa que receba uma frase, calcule e mostre a quantidade de palavras da frase 
digitada. 
14. Faça um programa que receba uma frase. Caso a frase possua meses por extenso substitua-os 
pelo seu número correspondente. 
15. Faça um programa que mostre a data do sistema nos seguintes formatos: “dia/mês/ano” e “São 
Paulo, 14 de setembro de 2001”. 
16. Elabore um programa que receba uma frase e mostre a quantidade de palavras, quais os 
caracteres existentes e a quantidade de cada caractere. 
 
 
 
 
 40
7. ESTRUTURAS, ENUMERAÇÕES E UNIÕES 
A linguagem C permite criar tipos de dados utilizando: 
• Estruturas; 
• Uniões; 
• Enumerações. 
 
7.1 Estruturas 
Estrutura (structure) é um tipo de dado formado por um conjunto de variáveis 
referenciadas por um nome. As estruturas permitem organizar os dados na memória e estabelecer 
um inter-relacionamento entre os mesmo de modo que facilite a manipulação dos dados e ofereça 
maior clareza aos programas. 
Em C é declarada uma estrutura da seguinte maneira: 
struct <nome_da_struct> 
{ 
 <tipo> <variável_1>; 
 <tipo> <variável_2>; 
 ... 
 <tipo> <variável_n>; 
}; 
struct cliente 
{ 
 char nome[41]; 
 char sobrenome[41]; 
}; 
A palavra struct define uma declaração, seguida do nome da estrutura e das respectivas 
variáveis delimitadas pelas chaves. As variáveis são denominadas membros da estrutura. A 
declaração de variáveis do tipo estrutura pode ser realizada da seguinte maneira: 
struct cliente 
{ 
 char nome[41]; 
 char sobrenome[41]; 
}*x, y, z[5]; 
struct cliente 
{ 
 char nome[41]; 
 char sobrenome[41]; 
}; 
... 
struct cliente *x, y, z[5]; 
A referência ou o acesso a um determinado membro da estrutura é dado por uma 
construção do tipo para variáveis e ponteiros: 
<nome_da_estrutura>.<membro> <nome_da_estrutura>-><membro> 
Exemplo: 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. struct cliente 
5. { 
6. char nome[41]; 
7. char sobrenome[41]; 
8. }*x, y, z[5]; 
9. 
10. int main(void) 
11. { 
12. x=&y; 
13. printf("Digite seu nome: "); 
14. scanf("%s", &y.nome); 
15. printf("Ola %s!\n", y.nome); 
16. printf("Digite seu nome: "); 
17. scanf("%s", &x->nome); 
18. printf("Ola %s!\n", x->nome); 
19. printf("Digite seu nome: "); 
20. scanf("%s", &z[0].nome); 
21. printf("Ola %s!\n", z[0].nome); 
22. return(0); 
23. } 
 
 41
7.2 Enumerações 
Enumeração é um conjunto de constantes inteiras que especifica todos os valores legais 
que uma variável desse tipo pode ter. Considere o seguinte exemplo: 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. enum dia_da_semana {Segunda, terca, quarta, quinta, sexta, sabado, domingo}; 
5. 
6. int main(void) 
7. { 
8. enum dia_da_semana dia; 
9. printf("Digite um numero de 0 a 6:"); 
10. scanf("%d", &dia); 
11. switch(dia) 
12. { 
13. case Segunda: 
14. printf("Segunda"); 
15. break; 
16. case terca: 
17. printf("terca"); 
18. break; 
19. case quarta: 
20. printf("quarta"); 
21. break; 
22. case quinta: 
23. printf("quinta"); 
24. break; 
25. case sexta: 
26. printf("sexta"); 
27. break; 
28. case sabado: 
29. printf("sabado"); 
30. break; 
31. case domingo: 
32. printf("domingo"); 
33. break; 
34. default: 
35. printf("Fora da faixa!\n"); 
36. } 
37. return(0); 
38. } 
O valor do primeiro elemento do conjunto enum é 0. 
 
7.3 Uniões 
Uniões (union) é uma posição de memória que é compartilhada por duas ou mais 
variáveis diferentes, geralmente de tipos diferentes. A definição e um exemplo é apresentada a 
seguir: 
union <identificador> 
{ 
 <tipo> <nome_da_vairável_01>; 
 <tipo> <nome_da_vairável_02>; 
 ... 
 <tipo> <nome_da_variável_n>; 
}<variáveis union>; 
union cliente 
{ 
 int i; 
 char c; 
}; 
No exemplo acima, tanto o inteiro i como o caractere c compartilham a mesma porção 
de memória, o mesmo endereço. Porém i ocupa 2 bytes e c apenas 1 byte. Quando uma union é 
declarada, o compilador cria automaticamente uma variável grande o bastante para conter o maior 
 42
tipo de variável da union. A utilização de union pode ajudar na produção de código portáveis e na 
utilização de conversões de tipos. 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. union tipoespecial 
5. { 
6. int x; 
7. float y; 
8. }W; 
9. 
10. int main(void) 
11. { 
12. printf("Digite um inteiro:"); 
13. scanf("%d", &W.x); 
14. printf("O endereco da variavel x e: %p\n", &W.x); 
15. printf("Voce digiou inteiro %d\n", W.x); 
16. printf("Digite um ponto flutuante:"); 
17. scanf("%f", &W.y); 
18. printf("O endereco da variavel y e: %p\n", &W.y); 
19. printf("Voce digiou ponto flutuante %f\n", W.y); 
20. return(0); 
21. } 
 
7.4 Exercícios 
1. Elabore um programa que armazene as seguintes informações de 10 alunos de uma turma: 
nome, sobrenome, prontuário, turma e data de nascimento. 
2. Elabore um programa que imprima as seguintes informações de 10 alunos de uma turma: nome, 
sobrenome, prontuário, turma e data de nascimento. 
3. Considerando os exercícios 1 e 2, elabore um programa que edite as informações de um 
determinado aluno escolhido pelo usuário. 
4. Elabore um programa que leia um valor. Este valor pode ser inteiro, ponto flutuante ou 
caractere. 
5. Faça um programa que realize o cadastro de contas bancárias com as seguintes informações: 
número da conta, nome do cliente e saldo. O banco permitirá o cadastramento de apenas 15 
contas e não pode haver mais de uma conta com o mesmo número. Crie o menu de opções a 
seguir: 
Menu de opcoes: 
Cadastrar 
Visualizar todas as contas de um determinado cliente 
Excluir a conta com o menor saldo 
Sair 
Opcao?: 
 
6. Faça um programa de cadastro de clientes. Este programa deve permitir a inserção de novos 
clientes, editar dados de clientes cadastrados, imprimir informações de um determinado cliente, 
excluir um cliente do cadastro, pesquisar clientes e relatorio. São necessários as seguintes 
informações do cliente: nome, sobrenome, rg, sexo, estado civil, data de nascimento, endereço, 
numero, complemento, cep, bairro, cidade, estado, telefone, fax e celular. O relatorio deve 
 43
calcular a média de idade, quantos são do sexo masculino e feminino, quantos são solteiros(as), 
quantos são casados(as) , quantos divorciados(as), listar as cidades e a respectiva quantidade de 
clientes por cidade. 
7. Faça um programa que gerencie uma locadora de vídeo. Este programa deve permitir a inserção 
de novas fitas, editar informações de fitas, pesquisar e imprimir informações de uma 
determinada fita. São necessários as seguintes informações das fitas de vídeo: título, categoria 
(comédia, drama, ação, documentário ou infantil), diretor, ano, com legenda ou sem legenda, 
idioma, descrição e quantidade disponível. 
 
 
 
 
 44
8. PONTEIROS 
Ponteiros são variáveis que contém um endereço de memória, isto é, armazenam a 
posição de uma outra variável namemória. Um ponteiro pode armazenar a posição de uma variável 
de dado, um trecho de código executável ou ainda outro ponteiro. A forma geral para declarar uma 
variável ponteiro é: 
<tipo> *<nome_do_ponteiro>; float *p 
 
O tipo base do ponteiro define que tipo de variáveis o ponteiro pode apontar. É 
importante declarar o ponteiro corretamente pois de acordo com o tipo base pode ser realizado a 
aritmética de ponteiros. 
 Após um ponteiro ser declarado o ponteiro possui um valor desconhecido. Portanto é 
necessário atribuir um valor antes de utilizá-lo. 
Existem dois operadores especiais para ponteiros: 
* = ”No endereço de...” & = ”O endereço de...” 
 
Em geral, as expressões envolvendo ponteiros concordam com as mesmas regras de 
qualquer outra expressão de C. Existem apenas duas operações aritméticas que podem ser usadas 
com ponteiros: adição e subtração. 
Considerando-se o seguinte exemplo: 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. float *p, v[5]; 
7. int i; 
8. p=&v[0]; 
9. printf("p armazenou endereco %p\n",p); 
10. for (i=0; i<5; i++) 
11. { 
12. printf("O endereco armazenado e %p\n",p); 
13. p++; 
14. } 
15. return 0; 
16. } 
 
O ponteiro p armazena inicialmente o primeiro byte do vetor v (Hexa 0063FDE4). No 
primeira iteração do primeiro loop (for), o ponteiro p é incrementado. Sendo p um ponteiro para 
ponto flutuante (float), o novo valor é o antigo mais 4 bytes (0063FDE4 + 4 = 0063FDE8). O 
mesmo ocorre com as demais iterações. O segundo loop (for) o ponteiro q é do tipo é double (8 
bytes), logo, ao ser incrementado, soma-se 8 bytes. 
 
 
 
 45
8.1 Exercícios 
1. Considere o trecho de código a seguir e responda se as seguintes expressões são construções 
válidas ou inválida. Justifique cada uma delas. 
... 
int j, k[10], *r, *s; 
... 
1. r=j; 
2. r=&j; 
3. s=k[0]; 
4. s=&k[0]; 
5. s=k; 
6. *r=&j; 
7. *r=j; 
8. *s=k; 
9. *s=k[5]; 
10. *s=*r; 
 
2. Elabore um programa que um vetor de 10 números reais, apresente o conteúdo e o endereço de 
cada posição do vetor. Utilize um ponteiro. 
3. Elabore um programa que leia três números, calcule e mostre o maior e o menor número. Utilize 
um ponteiro. 
 
 
 
 
 46
9. PONTEIROS, VETORES E MATRIZES 
Ponteiros e matrizes possuem uma estreita relação. A linguagem C permite o acesso aos 
elementos de uma matriz de duas formas: aritmética de ponteiros e indexação de matrizes. 
Por exemplo, é criado um vetor tipo char e um ponteiro para char. Em seguida é 
atribuído ao ponteiro p a posição 0 da variável vetor str. Para x receber o conteúdo do vetor str 
posição 10, as seguintes expressões são válidas: 
x=str[10]; x=*(p+10); 
As duas expressões retornam o valor do décimo primeiro elemento do vetor str. 
Exemplo: 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. int *p, v[10], i; 
7. p=&v[0]; 
8. printf("p armazenou endereco %p\n",p); 
9. for (i=0; i<10; i++) 
10. printf("O endereco de p[%d] e: %p\n", i, &p[i]); 
11. printf("\n\n"); 
12. for (i=0; i<10; i++) 
13. printf("O endereco de p+%d e: %p\n", i, p+i); 
14. return(0); 
15. } 
 
9.1 Vetores e Matrizes de Ponteiros 
Ponteiros podem ser organizados em matrizes como qualquer outro tipo de dado. A 
declaração de uma matriz de ponteiros int, de tamanho 10, é: 
int *x[10]; 
 
Considere o seguinte exemplo: 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. void mostra_erro(int num); 
5. 
6. int main(void) 
7. { 
8. int i; 
9. for(i=0; i<5; i++) 
10. mostra_erro(i); 
11. return 0; 
12. } 
13. 
14. void mostra_erro(int num) 
15. { 
16. /*Inicia um vetor de ponteiros*/ 
17. char *erro[]= 
18. { 
19. "Erro zero\n", 
20. "Erro um\n", 
21. "Erro dois\n", 
22. "Erro tres\n", 
23. "Erro quatro\n", 
24. }; 
25. printf("%s", erro[num]); 
26. } 
 47
9.2 Exercícios 
1. Escreva um programa que inverta a ordem dos caracteres de uma cadeia de caracteres. Use 
ponteiros. 
2. Faça um programa que carregue um vetor 10 de números reais, calcule a média aritmética dos 
elementos e mostre todos elementos maiores ou iguais à media e sua respectiva posição na 
vetor. Utilize ponteiro. 
 
 
 
 
 
 
 48
10. FUNÇÕES 
Funções são blocos de construção em C. A forma geral de uma função é: 
<Tipo_de_retorno> <nome_da_função>(<lista de parâmetros>) 
{ 
 <Corpo da Função> 
} 
 
OBS: <lista de parâmetros> = <tipo> <Var1>, <tipo> <Var2>, ..., <tipo> <Varn> 
 
Cada função é um bloco discreto de código, sendo que é privativo à função e não pode 
ser acessado por nenhum comando em uma outra função, exceto por meio de uma chamada de 
função. O escopo da função é a porção de código e dados (variáveis locais) que constitui o corpo da 
função que é oculto do resto do programa, portanto, a menos que utilize variáveis ou dados globais, 
não pode afetar ou ser afetado por outras partes do programa. Os argumentos são chamados de 
parâmetros formais da função. São variáveis locais que pertencem à função e são criadas na entrada 
e destruídas na saída. Os argumentos podem ser passados de duas maneiras: 
• Chamada por Valor: Este método faz uma cópia do valor de um argumento no parâmetro 
formal. Desta forma, quaisquer alterações feitas no parâmetro não têm nenhum efeito nas 
variáveis usadas para chamá-la; 
• Chamada por Referência: Este método o endereço do argumento é copiado para o parâmetro 
formal. Isto implica que quaisquer alterações no parâmetro afetam a variável usada para chamar 
a rotina. 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. float valor(float x); 
5. float referencia(float *x); 
6. 
7. int main(void) 
8. { 
9. float y=10,z; 
10. printf(”Chamada por valor:\n”); 
11. z=valor(y); 
12. printf(”y=%f, z=%f\n”, y, z); 
13. printf(”Chamada por Referencia:\n”); 
14. z=valor(y); 
15. printf(”y=%f, z=%f\n”, y, z); 
16. return(0); 
17. } 
18. float valor(float x) 
19. { 
20. x=x*x; 
21. return(x); 
22. } 
23. 
24. float referencia(float *x) 
25. { 
26. x=x*x; 
27. return(x); 
28. } 
 
10.1 Ponteiros para Funções 
As variáveis possuem uma posição física na memória assim como o próprio código 
executável do programa. O endereço de uma função é o ponto de entrada da função, portanto, um 
ponteiro de função pode ser usado para chamar uma função. Quando uma função é compilada, o 
código fonte é transformado em código objeto e um ponto de entrada é estabelecido. Quando é feita 
 49
uma chamada de função, enquanto o programa está sendo executado, é efetuada uma chamada em 
linguagem de máquina para o endereço desse ponto de entrada. 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. void mostra_erro1(int num); 
5. void mostra_erro2(int num); 
6. 
7. int main(void) 
8. { 
9. int i; 
10. void (*p)(int); 
11. p=mostra_erro1; 
12. printf("End. da funcao: %p\n", p); 
13. for(i=0; i<5; i++) 
14. p(i); 
15. p=mostra_erro2; 
16. printf("End. da funcao: %p\n", p); 
17. for(i=0; i<5; i++) 
18. p(i); 
19. return 0; 
20. } 
21. void mostra_erro1(int num) 
22. { 
23. char *erro[]= 
24. { 
25. "Primeiro Erro zero\n", 
26. "Primeiro Erro um\n", 
27. "Primeiro Erro dois\n", 
28. "Primeiro Erro tres\n", 
29. "Primeiro Erro quatro\n", 
30. }; 
31. printf("%s", erro[num]); 
32. } 
33. 
34. void mostra_erro2(int num) 
35. { 
36. char *erro[]= 
37. { 
38. "Segundo Erro zero\n", 
39. "Segundo Erro um\n", 
40. "Segundo Erro dois\n", 
41. "Segundo Erro tres\n", 
42. "Segundo Erro quatro\n", 
43. }; 
44. printf("%s", erro[num]); 
45. } 
 
10.2 Recursividade 
Em C, funções podem chamar a si mesmas. A função é recursiva se um comando no 
corpo da função a chama. A recursividade talvez seja a mais importante vantagem das funções em 
C. A recursão é o processo é o processo de definir algo em termos de si mesmo, isto é, uma função 
que chama a si mesma repetidamenteum número finito de vezes. Este recurso é muito útil em 
alguns tipos de algoritmos chamados de algoritmos recursivos. Por exemplo: O cálculo do fatorial 
de um número é definido pela seguinte expressão: 
 
 
onde n é o número inteiro positivo. Uma propriedade dos fatoriais é: 
 
 
Uma função recursiva cria a cada chamada um novo conjunto de variáveis locais. Não 
existe ganho de velocidade ou espaço de memória significativo com o uso de funções recursivas. A 
principal vantagem das funções recursivas é que pode ser utilizadas para criar versões mais claras e 
simples de vários algoritmos. Um exemplo não recursivo: 
int fact(int n) 
{ 
 int t, answer; /*Declaração das variáveis t e answer*/ 
 answer=1; 
 for (t=1; t<=n; t++) 
 answer=answer*(t); 
 return(answer); /*retorna answer*/ 
} 
Um exemplo recursivo: 
!3*41*2*3*4!5
1*2*3*...*)2(*)1(*!
==
−−= nnnn
)!1(*! −= nnn
 50
int fact_r(int n) 
{ 
 int t, answer; /*Declaração das variáveis t e answer*/ 
 if (n==1) return(1); 
 answer=fact_r(n-1)*n; 
 return(answer); /*retorna answer*/ 
} 
 
10.3 Função main 
A função main pode aceitar parâmetros via argumentos da linha de comando. Um 
argumento da linha de comando é a informação que segue o nome do programa na linha de 
comando do sistema operacional. Há dois argumentos internos especiais: argc e argv. 
int main(int argc, char* argv[]) 
O parâmetro argc contém o número de argumentos da linha de comando. Ele é sempre 
pelo menos 1 porque o nome do programa é qualificado como primeiro argumento. O parâmetro 
argv é um ponteiro para uma matriz de ponteiros para caractere. Cada elemento nessa matriz aponta 
para o argumento da linha de comando. 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(int argc, char * argv[]) 
5. { 
6. if (argc!=2) 
7. prinf(”Voce esqueceu de digitar seu nome\n”); 
8. else 
9. printf(”Ola %s!\n”, argv[1]); 
10. return(0); 
11. } 
 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(int argc, char * argv[]) 
5. { 
6. int i; 
7. printf("The value of argc is %d \n\n", argc); 
8. printf("These are the %d command-line arguments passed to main:\n\n", argc); 
9. for (i = 0; i < argc; i++) 
10. printf(" argv[%d]: %s\n", i, argv[i]); 
11. printf("\nThe environment string(s) on this system are:\n\n"); 
12. return(0); 
13. } 
 
10.4 Funções de String 
Função gets(): É utilizada para leitura de uma string através do dispositivo padrão, até que o 
ENTER seja pressionado. A função gets() não testa limites na matriz em que é chamada. 
Sintaxe (conio.h): 
char *gets(char *str); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. char string[80]; 
7. printf("Input a string:"); 
8. gets(string); 
 51
9. printf("The string input was: %s\n", string); 
10. return(0); 
11. } 
 
Função puts(): Escreve o seu argumento no dispositivo padrão de saída (vídeo), coloca um '\n' no 
final. Reconhece os códigos de barra invertida. 
Sintaxe (stdio.h): 
int puts(const char *str); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. char string[] = "This is an example output string\n"; 
7. puts(string); 
8. return(0); 
9. } 
 
Função strcpy(): Copia o conteúdo de uma string. 
Sintaxe (string.h): 
char *strcpy(char *destino, const char *origem); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. char string[10]; 
7. char *str1 = "abcdefghi"; 
8. strcpy(string, str1); 
9. printf("%s\n", string); 
10. return(0); 
11. } 
 
Função strcat(): Concatena duas strings. Não verifica tamanho. 
Sintaxe (string.h): 
char *strcat(char *str1, const char *str2); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. char s1[80], s2[80]; 
7. 
8. gets(s1); 
9. gets(s2); 
10. strcat(s2, s1); 
11. printf("%s\n", s2); 
12. return(0); 
13. } 
 
Função strcmp(): Compara duas strings, se forem iguais devolve 0. Se str1 > str2, devolve > 0. Do 
contrário se str1 < str2, devolve < 0. 
Sintaxe (string.h): 
int strcmp(const char *str1, const char *str2); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. char *buf1 = "aaa", *buf2 = "bbb", *buf3 = "ccc"; 
 52
7. int ptr; 
8. 
9. ptr = strcmp(buf2, buf1); 
10. if (ptr > 0) 
11. printf("buffer 2 is greater than buffer 1\n"); 
12. else 
13. printf("buffer 2 is less than buffer 1\n"); 
14. ptr = strcmp(buf2, buf3); 
15. if (ptr > 0) 
16. printf("buffer 2 is greater than buffer 3\n"); 
17. else 
18. printf("buffer 2 is less than buffer 3\n"); 
19. return(0); 
20. } 
 
10.5 Funções Matemáticas 
Função acos(): Devolve o arco co-seno do argumento. 
Sintaxe (math.h): 
double acos(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result; 
8. double x = 0.5; 
9. result = acos(x); 
10. printf("The arc cosine of %lf is %lf\n", x, result); 
11. return(0); 
12. } 
 
Função asin(): Devolve o arco seno do argumento. 
Sintaxe (math.h): 
double asin(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result; 
8. double x = 0.5; 
9. result = asin(x); 
10. printf("The arc sin of %lf is %lf\n", x, result); 
11. return(0); 
12. } 
 
Função atan(): Devolve o arco tangente do argumento. 
Sintaxe (math.h): 
double atan(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result; 
8. double x = 0.5; 
9. result = atan(x); 
10. printf("The arc tangent of %lf is %lf\n", x, result); 
11. return(0); 
12. } 
 53
Função cos(): Devolve o co-seno do argumento. 
Sintaxe (math.h): 
double cos(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result; 
8. double x = 0.5; 
9. result = cos(x); 
10. printf("The cosine of %lf is %lf\n", x, result); 
11. return(0); 
12. } 
 
Função sin(): Devolve o seno do argumento. 
Sintaxe (math.h): 
double sin(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result, x = 0.5; 
8. result = sin(x); 
9. printf("The sin of %lf is %lf\n", x, result); 
10. return(0); 
11. } 
 
Função tan(): Devolve a tangente do argumento. 
Sintaxe (math.h): 
double tan(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result, x = 0.5; 
8. result = tan(x); 
9. printf("The tan of %lf is %lf\n", x, result); 
10. return(0); 
11. } 
 
Função exp(): Devolve o logaritmo natural e elevado à potência arg. 
Sintaxe (math.h): 
double exp(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result; 
8. double x = 4.0; 
9. result = exp(x); 
10. printf("'e' raised to the power of %lf (e ^ %lf) = %lf\n", x, x, result); 
11. return(0); 
12. } 
 
 54
Função fabs(): Devolve o valor absoluto do argumento. 
Sintaxe (math.h): 
double fabs(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. float number = -1234.0; 
8. printf("number: %f absolute value: %f\n", number, fabs(number)); 
9. return(0); 
10. } 
 
Função fmod(): Devolve o resto de x/y. 
Sintaxe (math.h): 
double fmod(double x, double y); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double x = 5.0, y = 2.0; 
8. double result; 
9. result = fmod(x,y); 
10. printf("The remainder of (%lf / %lf) is %lf\n", x, y, result); 
11. return(0); 
12. } 
 
Função log(): Devolve o logaritmo natural do argumento. 
Sintaxe (math.h): 
double log(double arg);1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double result; 
8. double x = 8.6872; 
9. result = log(x); 
10. printf("The natural log of %lf is %lf\n", x, result); 
11. return(0); 
12. } 
 
Função pow(): Devolve base elevada à potência. 
Sintaxe (math.h): 
double pow(double base, double expoente); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double x = 2.0, y = 3.0; 
8. printf("%lf raised to %lf is %lf\n", x, y, pow(x, y)); 
9. return(0); 
10. } 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
 55
6. { 
7. double x = 2.0, y = 3.0; 
8. printf("%lf raised to %lf is %lf\n", x, y, exp(y*log(x))); 
9. return(0); 
10. } 
 
Função sqrt(): Devolve a raiz quadrada do argumento. 
Sintaxe (math.h): 
double sqrt(double arg); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <math.h> 
4. 
5. int main(void) 
6. { 
7. double x = 4.0, result; 
8. result = sqrt(x); 
9. printf("The square root of %lf is %lf\n", x, result); 
10. return(0); 
11. } 
 
10.6 Funções de Hora e Data 
Função time(): Devolve o horário atual de calendário do sistema. 
Sintaxe (time.h): 
time_t time(time_t *time); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <time.h> 
4. 
5. int main(void) 
6. { 
7. time_t t; 
8. t = time(NULL); 
9. printf("The number of seconds since January 1, 1970 is %ld",t); 
10. return(0); 
11. } 
 
Função ctime(): Devolve um ponteiro para o horário de calendário na forma: 
dia mês ano horas:minutos:segundos ano \n\0 
Sintaxe (time.h): 
char *ctime(const time_t *time); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <time.h> 
4. 
5. int main(void) 
6. { 
7. time_t t; 
8. time(&t); 
9. printf("Hoje é: %s\n", ctime(&t)); 
10. return(0); 
11. } 
 
 
 
 
 56
10.7 Outras Funções 
Função randomize() e rand(): A função rand() devolve um número aleatório entre 0 e 
RAND_MAX. A constante RAND_MAX é definida na biblioteca <stdlib.h>. A função randomize() 
inicia a geração de números aleatórios. 
Sintaxe (time.h e stdlib.h): 
void randomize(void); 
int rand(void); 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #include <time.h> 
4. 
5. int main(void) 
6. { 
7. int i; 
8. randomize(); 
9. printf("Dez números randômicos de 0 a 99\n\n"); 
10. for(i=0; i<10; i++) 
11. printf("%d\n", rand() % 100); 
12. return(0); 
13. } 
 
10.8 Exercícios 
1. Elabore uma função que aceita como parâmetro dois catetos e retorna o valor da hipotenusa. 
2. Elabore uma função que aceita como parâmetro dois números reais e retorna a média aritmética. 
3. Elabore uma função que aceita como parâmetro 5 números reais e retorna o maior número. 
4. Elabore uma função que aceita como parâmetro o número do CPF e retorna 1 para válido e 0 
para inválido. 
 
 
 
 
 
 
 
5. Elabore uma função que receba uma palavra (string) e retorna a quantidade de caracteres. 
6. Elabore uma função que receba uma string e troque todos os caracteres ‘a’ por ‘@’. 
7. Elabore uma função que receba 10 números reais e retorna a média aritmética. 
 
 
 
8. Elabore uma função que receba 10 números reais e a média, retornando o valor do desvio 
padrão. 
InválidoVálidoDígitoKANDDígitoJ
dDígitoDígitod
MODSd
DígitoIHGFEDCBAS
dDígitoDígitod
MODSd
IHGFEDCBAS
JKGHIDEFABC
ELSETHEN02_01_IF
202_ELSE002_THEN102IF
)112(112
2*01_3*4*5*6*7*8*9*10*11*2
101_ELSE001_THEN101IF
)111(111
2*3*4*5*6*7*8*9*10*1
..
==
==>=
−=
+++++++++=
==>=
−=
++++++++=
−
n
X
n
i
i∑
== 1µ
 57
 
 
 
 
9. Elabore uma função que receba como parâmetro um raio de uma esfera e retorne o volume de 
acordo com a fórmula abaixo. 
 
 
10. Elabore uma função que receba como parâmetro um número real e retorne a raiz quadrada. 
11. Elabore uma função que receba como parâmetro um número real e retorne o número elevado a 
potência 2. 
12. Elabore uma função que receba como parâmetro um número real e retorne o número elevado a 
potência 3. 
13. Elabore uma função que receba como parâmetro um número real e retorne o número elevado a 
potência 5. 
14. Elabore uma função que receba como parâmetro um número real e retorne 10% do valor. 
15. Elabore uma função que receba como parâmetro um número inteiro e imprima o valor em 
extenso na tela. 
16. São apresentados as seguintes fórmulas da trigonometria. Elabore um programa e implemente as 
funções para o cálculo da tangente, cotangente, secante e cossecante de um ângulo α. 
 
 
 
 
17. São apresentados as seguintes fórmulas da trigonometria. Elabore um programa e implemente as 
funções para o cálculo de: 
 
 
 
 
 
 
 
 
 
( )
n
X
n
i
i∑
=
−
= 1
2µ
σ
3*π*
3
4
RV =
α
α
α
α
α
α
sen
cos
cotg
cos
sen
tg
=
=
α
α
α
α
sen
1
seccos
cos
1
sec
=
=
( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )
( )
( ) ( )
( ) ( )ba
ba
ba
bababa
bababa
tg*tg1
tgtg
tg
sen*sencos*coscos
cos*sencos*sensen
−
+
=+
−=+
+=+ ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )
( )
( ) ( )
( ) ( )ba
ba
ba
bababa
bababa
tg*tg1
tgtg
tg
sen*sencos*coscos
cos*sencos*sensen
+
−
=−
+=−
−=−
( ) ( )
( ) ( )
( )
( )
( )a
a
a
aa
aa
2
2
2
tg1
tg*2
*2tg
sen*21*2cos
1cos*2*2cos
−
=
−=
−=( ) ( ) ( )
( ) ( ) ( )aaa
aaa
22 sencos*2cos
cos*sen*2*2sen
−=
=
 58
18. Dado um ponto C e uma distância r, o conjunto de pontos formado num plano cuja distância a C 
é igual a r é denominado circunferência de centro C. Se P(x; y) é um ponto qualquer da 
circunferência, a relação entre x e y é dada pela equação abaixo (equação da circunferência). 
Elabore funções que, dado o centro C e a distância r, apresentem a equação da circunferência, 
os pontos em que a circunferência corta o eixo Ox e Oy, e verificar se a circunferência passa 
pela origem. 
 
 
 
 59
11. ALOCAÇÃO DINÂMICA 
Um programa necessita de memória para armazenar informações. Existem duas 
maneiras fundamentais de um programa alocar memória do computador. A primeira forma é através 
de variáveis locais e globais (alocação estática), isto é, cada variável recebe um endereçamento de 
memória e o respectivo tamanho, que é fixo durante todo o tempo de execução do programa, para o 
armazenamento da informação. As variáveis globais são alocadas em uma região pré-definida e as 
variáveis locais são alocadas em uma parte da memória definida como pilha. Para este tipo de 
alocação necessita-se definir de antemão a quantidade de armazenamento necessária. 
A segunda forma é através da alocação dinâmica. A alocação dinâmica é o processo de 
alocar espaço de memória do computador em tempo de execução, ou seja, um programa em 
execução pode, sempre que necessário e houver a disponibilidade de espaço em memória, solicitar a 
alocação do espaço e utilizar convenientemente os dados. O armazenamento é realizado em uma 
região de memória livre, ou heap. 
A figura 11.1 mostra conceitualmente como um programa utiliza a memória (a posição 
e o tamanho variam de acordo com o tipo de processador). 
 
 
 
 
 
 
 
 
 
 
Figura 11.1 Utilização da memória de um programa. 
 
Em C ANSI são definidos quatro funções: 
Função malloc() :Aceita como parâmetro size bytes de memória e retorna um ponteiro para o bloco 
alocado ou nulo (NULL) se indisponível. 
void *malloc(size_t size); 
 
Função calloc() :Aceita como parâmetro num números de elementos de size bytes de memória e 
retorna um ponteiro para o bloco alocado (num*size) ou nulo (NULL) se indisponível. 
void *calloc(size_t num, size_t size); 
 
Pilha 
 
 
 
Heap 
Variáveis Globais 
Código do Programa 
 
 60
Função realloc() :Aceita como parâmetro o ponteiro do bloco de memória já alocada e um novo 
tamanho size bytes. Um ponteiro para o bloco de memória é devolvido porque realloc() pode 
precisar mover o bloco para aumentar seu tamanho. Se isso ocorrer,o conteúdo do bloco antigo é 
copiado para o novo bloco. Se p é nulo, realloc() aloca size bytes de memória e devolve um 
ponteiro para a memória alocada. Se size é zero, a memória apontada por p é liberada. 
void *realloc(void *p, size_t size); 
 
Função free() :Aceita como parâmetro o ponteiro do bloco de memória alocada e devolve ao heap. 
Por exemplo: 
void free(void *p); 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. float *y; 
7. y=(float*)malloc(sizeof(float)); 
8. if (!y) 
9. { 
10. printf(”Memória indisponível!\n”); 
11. exit(0); 
12. } 
13. *y=10; 
14. printf(”O endereço do bloco alocado é %p\n”,y); 
15. printf(”O endereço de y é %p\n”,&y); 
16. printf(”O conteúdo para que y aponta é %f\n”,*y); 
17. free(y); 
18. return(0); 
19. } 
 
11.1 Exercícios 
1. Elabore um programa que aloque dinamicamente um vetor de 10 números reais, apresente o 
conteúdo e o endereço de cada posição do vetor. 
2. Elabore um programa que aloque dinamicamente três números reais, leia, calcule e mostre o 
maior e o menor número. 
3. Elabore um programa que aloque dinamicamente um vetor 10 de números reais, carregue, 
calcule a média aritmética dos elementos e mostre todos elementos maiores ou iguais à media e 
sua respectiva posição na vetor. 
4. Elabore um programa que aloque dinamicamente um vetor de n números reais, carregue, calcule 
e apresente a média aritmética e o desvio padrão. 
5. Faça um programa de cadastro de clientes. Este programa deve permitir a inserção de novos 
clientes, editar dados de clientes cadastrados, imprimir informações de um determinado cliente, 
excluir um cliente do cadastro, pesquisar clientes e relatório. São necessários as seguintes 
informações do cliente: nome, sobrenome, rg, sexo, estado civil, data de nascimento, endereço, 
numero, complemento, cep, bairro, cidade, estado, telefone, fax e celular. 
 61
• relatório deve calcular a média de idade, quantos são do sexo masculino e feminino, quantos são 
solteiros(as), quantos são casados(as) , quantos divorciados(as), listar as cidades e a respectiva 
quantidade de clientes por cidade; 
• Para armazenar as informações dos clientes, utilize um vetor de ponteiros (deve-se iniciar todos 
ponteiros com nulo); 
• Cada novo cliente, aloca-se dinamicamente um registro e atribui o endereço desse bloco a uma 
posição do vetor; 
• Criar também uma função para ordenar os clientes. 
 
6. Faça um programa contendo os serviços que uma oficina mecânica pode realizar: 
• Ordem de serviço (número da OS, data, valor, serviço realizado, cliente); 
• Leia as informações sobre várias ordens de serviço e determine, ao final, a média dos valores, o 
nome do cliente que realizou o serviço mais caro, juntamente com a descrição desse serviço e a 
data de sua realização. 
 
 
 
 
 62
12. MANIPULAÇÃO DE ARQUIVOS 
12.1 “Streams” e Arquivos 
O sistema de E/S do C fornece ao programador uma interface consistente, independente 
do dispositivo real sendo acessado. Isto é, o sistema de E/S do C fornece um nível de abstração 
entre o programador e o dispositivo utilizado. Essa abstração é chamada de stream e o dispositivo 
real é chamado de arquivo. 
O sistema de arquivos do C ANSI foi projetado para trabalhar com uma grande 
variedade de dispositivos de E/S, incluindo terminais, acionadores de discos e acionadores de fita. 
Embora cada um dos dispositivos seja muito diferente, o sistema de arquivos com buffer 
transforma-os em um dispositivo lógico chamado stream. Todos os streams se comportam de 
maneira semelhante. Pelo fato dos streams serem independentes dos dispositivos reais, a mesma 
função pode escrever dados em um arquivo em disco ou em algum outro dispositivo, como o 
console. 
Em C um arquivo pode ser qualquer coisa, desde um arquivo em disco até um terminal 
ou uma impressora. Um stream é associado com um arquivo específico através de uma operação de 
abertura. Uma vez aberto o arquivo, informações podem ser trocadas entre ele e o programa. 
Quando não for mais necessário trocar informações com o arquivo, geralmente no final do 
processamento, devemos desassociar o stream do arquivo através de uma operação de fechamento. 
Nem todos os arquivos apresentam os mesmos recursos. Por exemplo, um arquivo em 
disco pode suportar acesso aleatório enquanto um teclado não pode. Isso revela um ponto 
importante sobre o sistema de E/S do C: todos os streams são iguais, mas não todos os arquivos. 
O sistema de arquivos ANSI é composto de diversas funções para a manipulação de 
arquivos, algumas das quais serão vistas no decorrer deste capítulo. Essas funções exigem que o 
cabeçalho STDIO.H seja incluído nos programas que as utilizem. 
O arquivo STDIO.H fornece protótipos para as funções de E/S e define também os 
tipos size_t e FILE. O tipo size_t é essencialmente o mesmo que um unsigned, enquanto o tipo 
FILE será discutido na próxima seção. Em STDIO.H é definida também a macro EOF (geralmente 
definida como –1), sendo tal valor devolvido quando uma função de entrada tenta ler além do final 
de um arquivo. 
FILE *arq; 
 
 
 
 
 63
12.2 Tipos de Acesso 
Os tipos de acesso aos arquivos podem ser seqüencial ou aleatório. No acesso 
seqüencial, a leitura e a transferência de dados devem ser feitas percorrendo seqüencialmente os 
bytes no arquivo. O acesso aos dados é feito através de um ponteiro indicador da posição corrente 
no arquivo, que indica a localização de início de leitura ou gravação. 
Enquanto que no acesso aleatório é feito em qualquer posição do arquivo sem que 
informações anteriores precisem ser acessadas. Isto pode ser feito através de funções que alteram 
indicador de posição corrente para determinada localização no arquivo. Este posicionamento 
aleatório é feito em relação a três possíveis origens que são passados como argumento de funções: 
Início, posição corrente ou fim. 
 
12.3 Funções Manipulação de Arquivos 
Função fclose() : Fecha um arquivo. 
int fclose(FILE *arq); 
 
Função fopen() : Abre um arquivo. 
FILE *fopen(const char nome_arquivo, const char* modo); 
 
O modo de abertura de arquivo pode ser conforme apresentada na tabela 12.1. 
Tabela 12.1 Os valores para o modo de abertura de arquivo. 
Modo Significado 
r Abre um arquivo texto para leitura 
w Cria um arquivo texto para escrita 
rb Abre um arquivo binário para leitura 
wb Cria um arquivo binário para escrita 
 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. FILE *in, *out; 
7. if ((in = fopen("TESTFILE.DAT", "r"))== NULL) 
8. { 
9. printf("Cannot open input file.\n"); 
10. return 1; 
11. } 
12. if ((out = fopen("TESTFILE.BAK", "w"))== NULL) 
13. { 
14. printf("Cannot open output file.\n"); 
15. return 1; 
16. } 
17. while (!feof(in)) 
18. fputc(fgetc(in), out); 
19. 
20. fclose(in); 
21. fclose(out); 
22. return(0); 
23. } 
 
 64
 
Função fprintf() : Escreve argumento em um arquivo. 
int fprintf(FILE *arq, const char *control_string, ...); 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. FILE *stream; 
7. int i = 100; 
8. char c = 'C'; 
9. float f = 1.234; 
10. stream = fopen("DUMMY.FIL", "w"); 
11. if (!stream) 
12. exit(1); 
13. fprintf(stream, "%d %c %f", i, c, f); 
14. fclose(stream); 
15. return 0; 
16. } 
 
Função fseek() : Posiciona o arquivo em um byte específico. 
int fseek(FILE *arq, long numbytes, int origin); 
O parâmetro origin é uma das seguintes macros definidas em stdio.h: 
Tabela 12.2 Os valores para o modo de abertura de arquivo. 
Macro Origin 
SEEK_SET Início do arquivo 
SEEK_CUR Posição atual 
SEEK_END Final de arquivo 
 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. long filesize(FILE *stream); 
5. 
6. int main(void) 
7. { 
8. FILE *stream; 
9. stream = fopen("MYFILE.TXT", "w+"); 
10. fprintf(stream,"This is a test"); 
11. printf("Tamanho de MYFILE.TXT is %ld bytes\n", filesize(stream)); 
12. fclose(stream); 
13. return 0; 
14. } 
15. 
16. long filesize(FILE *stream) 
17. { 
18. long curpos, length; 
19. curpos = ftell(stream); 
20. fseek(stream, 0L, SEEK_END); 
21. length = ftell(stream); 
22. fseek(stream, curpos, SEEK_SET); 
23. return length; 
24. } 
 
Função ferror() : Devolve verdadeiro se ocorreu um erro durante a última operação no arquivo. 
int ferror(FILE *arq); 
 
Função rewind() : Recoloca o indicador de posição de arquivo no início do arquivo. 
void rewind(FILE *arq); 
 
Função remove() : Apaga um arquivo. 
int remove(const char *nome_arquivo); 
 65
 
Função fflush() : Esvazia um stream. 
int fflush(FILE *arq); 
 
Função fscanf() : Lê argumento de um arquivo. 
int fscanf(FILE *arq, const char *control_string, ...); 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. FILE *stream; 
7. int i; 
8. char c; 
9. float f; 
10. stream = fopen("DUMMY.FIL", "r"); 
11. if (!stream) 
12. exit(1); 
13. fscanf(stream, "%d %c %f", &i, &c, &f); 
14. fclose(stream); 
15. printf("%d %c %f", i, c, f); 
16. return 0; 
17. } 
 
Função fread() : Lê count blocos de num_bytes de arq para buffer. Se não ocorrer erro retorna 
count. 
size_t fread(void *buffer, size_t num_bytes, size_t count, FILE *arq); 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. FILE *stream; 
7. int s[10], i; 
8. if ((stream = fopen("TEST.$$$", "rb")) == NULL) 
9. { 
10. fprintf(stderr, "Cannot open output file.\n"); 
11. return 1; 
12. } 
13. for (i=0; i<10; i++) 
14. { 
15. fread (&s[i], sizeof(int), 1, stream); 
16. printf("x[%d]=%d\n",i, s[i]); 
17. } 
18. fclose(stream); 
19. return 0; 
20. } 
 
Função feof() : Devolve verdadeiro se fim de arquivo for atingido. 
int feof(FILE *arq); 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. FILE *stream; 
7. if ((stream = fopen("DUMMY.FIL", "r")==NULL) 
8. exit(1); 
9. fgetc(stream); 
10. if (feof(stream)) 
11. printf("We have reached end-of-file\n"); 
12. fclose(stream); 
13. return 0; 
14. } 
 
 66
Função fwrite() : Escreve count blocos de num_bytes de buffer para arq. Se não ocorrer erro retorna 
count. 
size_t fwrite(void *buffer, size_t num_bytes, size_t count, FILE *arq); 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. int main(void) 
5. { 
6. FILE *stream; 
7. int s[10], i; 
8. if ((stream = fopen("TEST.$$$", "wb")) == NULL) 
9. { 
10. fprintf(stderr, "Cannot open output file.\n"); 
11. return 1; 
12. } 
13. for (i=0; i<10; i++) 
14. { 
15. printf("x[%d]=",i); 
16. scanf("%d",&s[i]); 
17. fwrite(&s[i], sizeof(int), 1, stream); 
18. } 
19. fclose(stream); 
20. return 0; 
21. } 
 
Função fgetc() : Devolve o próximo caractere da stream de entrada na posição atual e incrementa o 
indicador de posição do arquivo. 
int fgetc(FILE *arq); 
1. #include <string.h> 
2. #include <stdio.h> 
3. 
4. int main(void) 
5. { 
6. FILE *stream; 
7. char string[] = "This is a test"; 
8. char ch; 
9. 
10. /* open a file for update */ 
11. stream = fopen("DUMMY.FIL", "w+"); 
12. 
13. /* write a string into the file */ 
14. fwrite(string, strlen(string), 1, stream); 
15. 
16. /* seek to the beginning of the file */ 
17. fseek(stream, 0, SEEK_SET); 
18. 
19. do 
20. { 
21. /* read a char from the file */ 
22. ch = fgetc(stream); 
23. 
24. /* display the character */ 
25. 
26. putchar(ch); 
27. } while (ch != EOF); 
28. 
29. fclose(stream); 
30. return 0; 
31. } 
 
12.4 Exercícios 
1. Faça um programa de cadastro de clientes. Este programa deve permitir a inserção de novos 
clientes, editar dados de clientes cadastrados, imprimir informações de um determinado cliente, 
excluir um cliente do cadastro, pesquisar clientes e relatório. São necessários as seguintes 
 67
informações do cliente: nome, sobrenome, rg, sexo, estado civil, data de nascimento, endereço, 
numero, complemento, cep, bairro, cidade, estado, telefone, fax e celular. 
• relatório deve calcular a média de idade, quantos são do sexo masculino e feminino, quantos são 
solteiros(as), quantos são casados(as) , quantos divorciados(as), listar as cidades e a respectiva 
quantidade de clientes por cidade; 
• Para armazenar as informações dos clientes, utilize um vetor de ponteiros (deve-se iniciar todos 
ponteiros com nulo); 
• Cada novo cliente, aloca-se dinamicamente um registro e atribui o endereço desse bloco a uma 
posição do vetor; 
• Criar também uma função para ordenar os clientes; 
• Implementar operações para manipular arquivos. 
 
2. Faça um programa contendo os serviços que uma oficina mecânica pode realizar: 
• Ordem de serviço (número da OS, data, valor, serviço realizado, cliente - ler informações de um 
arquivo); 
• Leia as informações sobre várias ordens de serviço e determine, ao final, a média dos valores, o 
nome do cliente que realizou o serviço mais caro, juntamente com a descrição desse serviço e a 
data de sua realização. 
 
3. Faça um programa que gerencia os produtos armazenados em uma farmácia. Deve-se criar um 
arquivo que armazene as informações dos produtos e a quantidade disponível. 
4. Faça um programa que gerencie a venda de produtos de uma farmácia. O programa consulta um 
arquivo (exercício 3) que contém a disponibilidade dos produtos. A cada venda deve-se 
atualizar a quantidade no arquivo. 
 
 
 
 
 68
13. ORDENAÇÃO 
Ordenação é o processo de arranjar um conjunto de informações semelhantes numa 
ordem crescente ou decrescente. Geralmente, quando a informação é ordenada, apenas uma porção 
dessa informação é usada como chave da ordenação. Essa chave é utilizada nas comparações, mas, 
quando uma troca se torna necessária, toda a estrutura de dados é transferida. 
Existem três método básicos para ordenar matrizes: 
• Troca; 
• Seleção; 
• Inserção. 
Considerando-se o seguinte exemplo são apresentados os algoritmos de ordenação a 
seguir: 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. 
4. void selecao(int *p, int count); 
5. void insercao((int *p, int count); 
6. void troca(int *p, int count); 
7. void shakesort(int *p, int count); 
8. void shell(int *p, int count); 
9. void quicksort((int *p, int count); 
10. void qs(int *p, int left, int right); 
11. void print(int *p, int count); 
12. 
13. int main(void) 
14. { 
15. int *q, n, i; 
16. printf("Quantos números deseja:"); 
17. scanf("%d", &n); 
18. q=(int*)malloc(n*sizeof(int)); 
19. if (!q) 
20. exit(1); 
21. for (i=0; i<n; i++) 
22. { 
23. printf("x[%d]=",i); 
24. scanf("%d", &q[i]); 
25. } 
26. print(q,n); 
27. shakesort(q,n); 
28. printf("\nOrdenando...\n"); 
29. print(q,n); 
30. free(q); 
31. return 0; 
32. } 
33. 
34. void print(int *p, int count) 
35. { 
36. int i; 
37. printf("\n"); 
38. for (i=0; i<count; i++) 
39. printf("%d ", p[i]); 
40. printf("\n"); 
41. } 
42. ... 
 
13.1 Ordenação por Troca 
A ordenação por troca envolve repetidas comparações e, se necessário, a troca de dois 
elementos adjacentes. Consiste em dois loops, um dentro do outro (i e j). O loop j é o loop interno, 
e ele passa por cada item da tabela (do fim para o início), e compara a si próprio (j) com o anterior 
(j+1). Caso seja maior que o próximo, estes dois são trocados. Após j ter passado por toda a tabela, 
ele volta ao final e i é incrementado. Essa operação é repetida tantas vezes quantas sejam o número 
de registros da tabela. 
void troca(int *p, int count) 
{ 
 int a, b, temp; 
 print(p, count); 
 for (a=1; a<count; a++) 
 for (b=count-1; b>=a; b--) 
 { 
 if (p[b-1]>p[b]) 
 { 
 temp=p[b-1]; 
void shakesort(int *p, int count){ 
 int a, exchange, temp; 
 do 
 { 
 exchange=0; 
 for (a=count-1; a>0; a--) 
 { 
 if (p[a-1]>p[a]) 
 { 
 69
 p[b-1]=p[b]; 
 p[b]=temp; 
 } 
 } 
} 
 temp=p[a-1]; 
 p[a-1]=p[a]; 
 p[a]=temp; 
 exchange=1; 
 } 
 } 
 for (a=1; a<count; a++) 
 { 
 if (p[a-1]>p[a]) 
 { 
 temp=p[a-1]; 
 p[a-1]=p[a]; 
 p[a]=temp; 
 exchange=1; 
 } 
 } 
 } while (exchange); 
} 
 
13.2 Ordenação por Seleção 
A ordenação por seleção consiste, em cada etapa, em selecionar o maior (ou o 
menor)elemento e alocá-lo em sua posição correta dentro da futura lista ordenada. Durante a 
aplicação do método de seleção a lista com n registros fica decomposta em duas sub listas, uma 
contendo os itens já ordenados e a outra com os restantes ainda não ordenados. No início a sub lista 
ordenada é vazia e a outra contém todos os demais.No final do processo a sub lista ordenada 
apresentará (n-1) itens e a outra apenas 1. As etapas(ou varreduras) como já descrito acima consiste 
em buscar o maior elemento da lista não ordenada e colocá-lo na lista ordenada. 
void selecao(int *p, int count) 
{ 
 int a, b, c, exchange, temp; 
 for (a=0; a<count-1; a++) 
 { 
 exchange=0; 
 c=a; 
 temp=p[a]; 
 for(b=(a+1); b<count; b++) 
 { 
 if (p[b]<temp) 
 { 
 c=b; 
 temp=p[b]; 
 exchange=1; 
 } 
 } 
 if (exchange) 
 { 
 p[c]=p[a]; 
 p[a]=temp; 
 } 
 } 
} 
 
13.3 Ordenação por Inserção 
O algoritmo de ordenação por inserção é bastante simples e eficiente para uma 
quantidade pequena de números. A idéia de funcionamento é semelhante ao ordenamento de cartas 
de baralho na mão de um jogador. A mão esquerda começa "vazia" e a mão direita insere uma 
"carta" de cada vez na posição correta. Ao final, quando todas as "cartas" foram inseridas, elas já 
 70
estão ordenadas. Durante o processo de ordenação por inserção a lista fica dividida em duas sub 
listas, uma com os elementos já ordenados e a outra com elementos ainda por ordenar. No início, a 
sub lista ordenada é formada trivialmente apenas pelo primeiro elemento da lista. Nos métodos de 
ordenação por inserção, a cada etapa i, o i-ésimo elemento é inserido em seu lugar apropriado entre 
os(i-1) elementos já ordenados. 
void insercao(int *p, int count) 
{ 
 int a, b, temp; 
 for (a=1; a<count; a++) 
 { 
 temp=p[a]; 
 for (b=(a-1); b>=0 && temp<p[b]; b--) 
 p[b+1] = p[b]; 
 p[b+1]=temp; 
 } 
} 
 
13.4 “Shell Sort” 
O algoritmo de ordenação shell é um algoritmo de ordenação por inserção. O algoritmo 
foi criado por Donald L. Shell em 1959. Neste algoritmo, ao invés dos dados serem comparados 
com os seus vizinhos, é criado um gap. O gap, no início, é igual à parte inteira da divisão do 
número de elementos da lista por 2. Por exemplo, se a nossa lista tem 15 elementos, o gap inicial é 
igual a 7. São então comparados os elementos 1o. e 8o., 2o. e 9o., e assim por diante. A maior parte 
dos elementos já vão para suas posições aproximadas. Ao terminar de passar por todos os elementos 
da lista, o gap é diminuído em 1 e é feita uma nova passagem. Isso é repetido até que o gap seja 
igual a 0. 
void shell(int *p, int count) 
{ 
 int i, j, gap, k, x, a[5]={9,5,3,2,1}; 
 print(p, count); 
 for (k=0; k<5; k++) 
 { 
 gap = a[k]; 
 for (i=gap; i<count; i++) 
 { 
 x=p[i]; 
 for (j=i-gap; x<p[j] && j>=0; j=j-gap) 
 p[j+gap] = p[j]; 
 p[j+gap] = x; 
 } 
 } 
} 
 
13.5 “Quicksort” 
O algoritmo de ordenação quicksort é um algoritmo de ordenação por troca. Baseia-se 
na escolha de um elemento central. A partir da posição 0, começamos a procurar um elemento 
maior do que x, até encontrarmos. O mesmo processo ocorre a partir da posição n-1, procurando um 
elemento menor do que x. 
 71
Quando o índice da esquerda (i) for menor do que o índice da direita (j), trocamos estes 
valores, até que i>=j. O processo se repete de forma recursiva para cada subconjunto (esquerda e 
direita do elemento x), até termos um subconjunto com um único elemento. 
void quicksort(int *p, int count) 
{ 
 qs(p, 0, count-1); 
} 
 
void qs(int *p, int left, int right) 
{ 
 int i, j, x, y; 
 i=left; 
 j=right; 
 x=p[(left+right)/2]; 
 do 
 { 
 while ((p[i]<x) && (i<right)) 
 i++; 
 while ((x<p[j]) && (j>left)) 
 j--; 
 if (i<=j) 
 { 
 y=p[i]; 
 p[i]=p[j]; 
 p[j]=y; 
 i++; 
 j--; 
 } 
 }while (i<=j); 
 if (left<j) 
 qs(p, left, j); 
 if (i<right) 
 qs(p, i, right); 
} 
 
 
 
 
 72
14. ESTRUTURAS DE DADOS 
Um programa consiste de duas coisas: algoritmos e estruturas de dados. A estrutura de 
dados é importante para armazenar os dados e recuperá-los, quando necessário, de forma 
automática em uma ordem predeterminada. De acordo com a forma de acesso (armazenamento e 
recuperação) aos dados, existem basicamente quatro tipos de estruturas: 
• Pilha; 
• Filas; 
• Listas; 
• Árvores Binárias. 
 
14.1 Pilhas 
Pilhas são estruturas de armazenagem e recuperação de dador em ordem LIFO (Last-in, 
First-out), isto é, o último item colocado na pilha será o primeiro a ser removido. As duas operações 
básicas (armazenar e recuperar) são tradicionalmente chamadas de push e pop, respectivamente. 
 
 
 
 
 
 
 
 
 
Figura 14.1 Ilustração exemplo da função push. 
 
 
 
 
 
 
 
 
 
Figura 14.2 Ilustração exemplo da função pop. 
G 
U 
P 
A 
 
W 
G 
 
P 
A 
 
U 
P
A
G 
A
P 
 
 
 
 
 
A 
 
 
 
 
 
 
 
 
A 
 
P
A
G
P
A
G 
U 
P 
A 
 
G
U
P
A
W
A P G U W
 73
 
14.2 Filas 
Filas são estruturas de armazenagem e recuperação de dados em ordem FIFO (First In, 
First Out), isto é, o primeiro item colocado na fila será o primeiro a ser removido. A fila opera 
utilizando duas funções: entra e sai. As filas podem ser utilizadas em simulações, distribuição de 
eventos, entre outros. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Figura 14.3 Ilustração função entra e função sai de uma fila. 
 
14.2.1 Filas Circulares 
Quando uma Fila atinge o limite do vetor de armazenamento, não é mais possível 
colocar nenhum item na fila. Um melhoramento das Filas simples seria a Fila Circular. Desta forma, 
 
 X 
 YX 
Z YX 
X 
Y 
Z 
Z YX
Z Y X 
Z Y 
Z 
 74
qualquer número de itens poderia ser colocado na fila, desde que itens também estejam sendo 
retirados (Fig. 14.4). 
 
 
 
 
 
 
 
 
 
 
 
Figura 14.4 Ilustração de uma fila circular. 
 
14.3 Listas Ligadas 
São estruturas de armazenagem e recuperação de dados de forma randômica. Cada 
porção de informação é armazenada em um item de informação e que carrega consigo um elo ao 
próximo item de informação, ou seja, uma lista encadeada. As listas encadeadas podem ser 
singularmente (simples) ou duplamente encadeadas. 
 
14.3.1 Listas Singularmente Ligadas 
Uma lista singularmente encadeada requer que cada item de informação contenha um 
elo com o próximo item da lista. Cada item de informação consiste em uma estrutura que inclui 
campos de informação e ponteiro de enlace. 
A adição de um nó pode ser realizada no início ou ao longo de uma lista ligada. A 
adição de um nó no início de uma lista ligada é realizada em quatro etapas: 
a) Um nó vazio é criado. Ele está vazio no sentido de que o programa que realiza a inserção 
não atribui quaisquer valores aos campos de dados do nó; 
b) O campo info do nó é inicializado com um valor em particular; 
c) Devido ao nó ser incluído no início da lista, o elo proximo se torna um ponteiro para o 
primeiro nó da lista, isto é, o valor corrente de topo; 
A 
B 
 75
d) O novo nó precede todos os nós da lista, mas esse fato tem que ser refletido no valor do 
Primeiro. Consequentemente, o ponteiro Primeiro é atualizado para se tornar o ponteiro 
para o novo nó. 
O processode adicionar um novo nó ao longo da lista de forma ordenada é realizada em 
quatro etapas: 
a) Um nó vazio é criado. Ele está vazio no sentido de que o programa que realiza a inserção 
não atribui quaisquer valores aos campos de dados do nó; 
b) O campo info do nó é inicializado com um valor em particular; 
c) Percorre a lista comparando o campo info do novo nó com cada nó da lista. 
d) Ao determinar a posição de inserção, o elo proximo do anterior do nó corrente aponta para o 
novo nó e, o elo proximo do novo nó aponta para o elo proximo do nó corrente. 
A operação de remoção consiste em remover um nó do início ou ao longo da lista e 
retornar o valor armazenado nela. Deve-se observar que: 
a) Não se pode remover um nó de uma lista vazia; 
b) A remoção de um único nó de uma lista ligada de apenas um nó, o ponteiro Primeiro deve ser 
atualizado; 
c) A remoção do primeiro nó da lista com pelo menos dois nós exige a atualização do ponteiro 
Primeiro; 
d) A remoção de um nó no meio de uma lista deve ser realizada somente após efetuar as ligações 
necessárias afim de manter a consistência da lista. 
 
 
 
 
 
 
Figura 14.5 Ilustração de uma lista singularmente ligada. 
 
 
 
 
 
 
 
 
 
2 5 8 41 
Primeiro 
A 
 
Primeiro 
 
Tmp 
A 
 
Primeiro 
 
Tmp 
A 
 
Primeiro 
(1) (2) (3) 
 76
Figura 14.6 Ilustração de inserção em uma lista singularmente ligada. 
 
 
 
 
 
 
 
 
 
Figura 14.7 Ilustração de inserção em uma lista singularmente ligada. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Primeiro 
A 
 
Tmp 
C 
(1) 
 
Primeiro
A 
 
Tmp
C 
(2) 
 
Primeiro 
A C 
(3) 
 
Primeiro 
A C S R 
A 
(3) 
 
Primeiro 
A C S R 
A 
 
Tmp 
(2) 
A 
 
Tmp 
 
Primeiro 
A C S R 
(1) 
 77
 
Figura 14.8 Ilustração de inserção em uma lista singularmente ligada. 
 
14.3.2 Listas Duplamente Ligadas 
Uma lista duplamente ligada (ou lista linear duplamente ligada) consiste em dados e 
elos para o próximo item e para o item precedente. A vantagem de possuir dois elos são: 
• A lista pode ser lida em ambas as direções; 
• Se um dos elos tornar-se inválido, a lista pode ser reconstruída utilizando-se o outro elo. 
A inserção de um nó de forma ordenada em uma lista duplamente ligada pode ser 
realizada basicamente de três formas: 
• no início da lista; 
• no meio da lista; 
• no fim da lista. 
O processo para a inserção no início da lista é realizado em quatro etapas: 
a) Um novo nó é criado inicializando-se os dados (inclusive os ponteiro como nulo); 
b) O elo proximo do novo nó recebe Primeiro; 
c) O elo anterior apontado por Primeiro recebe novo nó; 
d) O ponteiro Primeiro recebe novo nó. 
O processo para a inserção no fim da lista é realizado em quatro etapas: 
a) Um novo nó é criado inicializando-se os dados (inclusive os ponteiro como nulo); 
b) O elo anterior do novo nó recebe Ultimo; 
c) O elo proximo apontado por Ultimo recebe novo nó; 
d) ponteiro Ultimo recebe novo nó. 
 
 
 
 
 
 
 
Figura 14.8 Ilustração de uma lista linear duplamente ligada. 
 
O processo de adicionar um novo nó ao longo da lista duplamente ligada de forma 
ordenada é realizada em quatro etapas: 
a) Um novo nó é criado inicializando-se os dados (inclusive os ponteiro como nulo); 
Primeiro 
1 9 3 5 
Último 
 78
b) O campo info do nó é inicializado com um valor em particular; 
c) Percorre a lista comparando o campo info do novo nó com cada nó da lista. 
d) Ao determinar a posição de inserção, o elo proximo do anterior do nó corrente aponta 
para o novo nó. O elo anterior do novo nó aponta para o anterior do nó corrente. O elo 
proximo do novo nó aponta para o nó corrente e, o elo anterior do nó corrente aponta 
para o novo nó. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Figura 14.9 Ilustração de inserção em uma lista duplamente ligada. 
 
A operação de remoção consiste em remover um nó do início, do fim ou ao longo da 
lista e retornar o valor armazenado nela. Deve-se observar que: 
a) Não se pode remover um nó de uma lista vazia; 
 
Primeiro Ultimo 
S 
(1) 
 
Primeiro Ultimo 
S 
(2) 
 
Primeiro Ultimo tmp 
S 
(3) 
E 
 
Primeiro Ultimo 
S 
(4) 
S 
 
tmp Primeiro Ultimo 
S 
(5) 
S 
 
 79
b) A remoção de um único nó de uma lista ligada de apenas um nó, o ponteiro Primeiro e Ultimo 
deve ser atualizado; 
c) A remoção do primeiro nó da lista com pelo menos dois nós exige a atualização do ponteiro 
Primeiro; 
d) A remoção do ultimo nó da lista com pelo menos dois nós exige a atualização do ponteiro 
Ultimo; 
e) A remoção de um nó no meio de uma lista deve ser realizada somente após efetuar as ligações 
necessárias afim de manter a consistência da lista. 
Uma outra construção possível é a lista circular ligada que pode conter ou não a 
indicação para o início da lista 
 
 
 
 
 
 
 
 
Figura 14.9 Ilustração de uma lista circular duplamente ligada com cabeçalho. 
 
14.4 Árvores Binárias 
Árvore binária é um conjunto finito de elementos que está vazio ou é particionado 
basicamente em três subconjuntos disjuntos: raiz, subárvore esquerda e subárvore direita. Cada 
elemento de uma árvore binária é chamado nó da árvore. Em cada nó contém um registro, e, para 
cada nó, a seguinte propriedade é verdadeira: 
• Todos os registros com chaves menores estão na subárvore esquerda e todos os registros 
com chaves maiores estão na subárvore direita; 
• O número de subárvores de um nó é chamado grau daquele nó; 
• Um nó de grau zero é chamado de nó externo ou folha. Os outros nós são chamados de nó 
interno; 
• Grau de uma árvore é o mais alto dentre os graus de seus nós; 
• Árvore binária são árvores de grau 2; 
• O nível do nó raiz é 0. Se um nó está no nível i então a raiz de suas subárvores estão no 
nível i+1; 
Início 
1 9 3 5 
 80
• A altura de um nó é o comprimento do caminho mais longo deste nó até um nó folha; 
• A altura de uma árvore é a altura do nó raiz; 
• A profundidade é o número de arestas da raiz até um determinado nó. A raiz possui 
profundidade 0. As subárvores (sucessores diretos) da raiz possuem profundidade 1. Um nó 
no nível n possui a profundidade n. 
As árvores podem ser utilizadas para administrar grandes quantidades de dados em uma 
ordem qualquer, permitem o uso de listas ligadas e a divisão de um conjunto de dados em 
subconjuntos, administrando-as de forma hierárquica. Além disso, podem representar processos 
decisórios. 
 
 
 
 
 
 
 
 
 
Figura 14.10 Ilustração de uma árvore binária. 
 
Embora árvores sejam fáceis de visualizar, elas apresentam alguns problemas difíceis de 
programação. A maioria das funções que usam árvore é recursiva porque a própria árvore é uma 
estrutura de dados recursiva. Isto é, cada subárvore é ela própria uma árvore. 
O procedimento de acesso a cada nó na árvore é chamado de transversalização da 
árvore. Existem três maneiras de percorrer uma árvore: de forma ordenada, pré-ordenada e pós-
ordenada. Usando a forma ordenada, cada nó é visitado da subárvore da esquerda, a raiz e, em 
seguida, a subárvore da direita. Na maneira pré-ordenada, cada nó é visitado da raiz, a subárvore da 
esquerda e, em seguida, a subárvore da direita. Com a pós-ordenada, cada nó é visitado da 
subárvore da esquerda, a subárvore da direita e, depois, a raiz. Considerando-se o exemplo da figura 
14.11, a ordem de acesso à árvore usando cada método é: 
 
 
Ordenada a b c d e f g 
Pré-ordenada d b a c f e g 
Pós-ordenada a c b e g f d 
 
 
Raiz: 15 
Grau da árvore: 2 
Nível 0: 15 
Nível 1: 5 e 16 
Nível 2: 2, 12 e 20 
Nível 3: 10, 13, 18 e 23 
Nível 4: 6 
Nível 5: 7 
Altura da árvore: 7 
 
f 
d
ge 
b
ca
 81
 
Figura 14.11 Exemplo de árvore binária. 
Uma árvore binária ordenada é aquela em que a subárvore da esquerda contém nós que 
são menores ou iguaisà raiz e os da direita são maiores que a raiz. 
 
14.5 EXERCÍCIOS 
1. Elaborar as funções pop() e push() de uma pilha. 
2. Elaborar um programa que simule o armazenamento e recuperação de uma pilha. 
3. Elaborar as funções para armazenar e recuperar dados em uma fila. 
4. Elaborar um programa que simule uma fila de atendimento. 
 
 
 
 
 
 82
15. BIBLIOGRAFIA 
Arakaki, R.; Arakaki, J.; Angerami, P.M.; Aoki, O.L.; Salles, D.S. “Fundamentos de Programação 
C: Técnicas e Aplicações” 2ªEdição, Livros Técnicos e Científicos Editora, Rio de 
Janeiro/RJ, 1992. 
Ascencio, A.F.G; Campos, E.A.V. “Fundamentos da Programação de Computadores - Algoritmos, 
Pascal e C/C++”, Editora Prentice Hall, São Paulo/SP, 2002. 
Cormen, T.H.; Leiserson, C.E.; Rivest, R.L.; Stein, C. “Algoritmos - Teoria e Prática”, Tradução da 
2ª.Edição Americana, Editora Campus, 2002. 
Drozdek, A. “Estrutura de Dados e Algoritmos em C++”, Editora Pioneira Thomson, São Paulo/SP, 
2002. 
Loudon, K. “Dominando Algoritmos com C” Editora Ciência Moderna, Rio de Janeiro/RJ, 2000. 
Lourenço, A.C.; Alves Cruz, E.C.; Ferreira, S.R.; Choueri Júnior, S. “Circuitos Digitais” 3ªEdição, 
Editora Érica, São Paulo/SP, 1996. 
Mizrahi, V.V. “Treinamento em Linguagem C++ - Módulo 2”, Editora Makron Books, São 
Paulo/SP, 1994. 
Neto, A. “Matemática Básica”, Editora Atual, São Paulo, 1984. 
Pressman, R.S.; Ince, D. “Software Engineering: A Practitioner’s Approach (European 
Adaptation)” 5thEdition, MacGraw-Hill International, Berkshire/UK, 2000. 
Schildt, H. “C Completo e Total” 3ªEdição Makron Books Ltda., São Paulo/SP, 1997. 
Stroustrup, B. “A Linguagem de Programação C++”, 3ª.Edição, Editora Bookman, Porto 
Alegre/RS, 2000. 
Tenenbaum, A.M.; Langsam, Y.; Augenstein, M.J. “Estruturas de Dados Usando C” Makron Books 
Ltda., Rio de Janeiro/RJ, 1995. 
Ziviani, N. “Projeto de Algoritmos com Implementações em Pascal e C” 4ªEdição, Editora Pioneira 
Informática, São Paulo/SP, 1999. 
 
 
 
 
 
 
 83
16. APÊNDICE 
16.1 Tabela ASCII 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 84
16.2 Sistema Numérico 
O homem é resultado contínuo da sua própria evolução. Em um determinado momento 
ao longo desse processo, surgiu a necessidade de medir grandezas. Para medir essas grandezas o 
homem criou os sistemas numéricos. 
Por exemplo, o tempo é medido utilizando um sistema de 24 unidades para as horas, um 
sistema de 60 unidades para minutos e segundos, um sistema de 12 unidades para os meses e um 
sistema de 10 unidades para os anos. Os números de todos os sistemas numéricos podem ser 
decompostos de acordo com a lei de formação: 
 
 
 
onde: 
an = algarismo; 
b = base do número; 
n = quantidade de algarismos –1. 
 
Para a compreensão de um circuito digital até um computador são importantes três 
sistemas numéricos: 
 Sistema Decimal (base 10): O sistema decimal ou base 10 é o sistema mais utilizado no dia-
a-dia. Utiliza 10 símbolos (algarismos) para representar qualquer quantidade: 0 1 2 3 4 5 
6 7 8 9. Para a representação de quantidades maiores que a base adota-se pesos para cada 
posição do algarismo. Por exemplo, o número 3452 é composto 4 algarismos, isto é, por 3 
milhares, 4 centenas, 5 dezenas e 2 unidades, ou de acordo com a lei de formação: 
 
 
 Sistema Binário (base 2): O sistema binário ou base 2 utiliza apenas dois símbolos para 
representar qualquer quantidade: 0 1. Cada algarismo ou dígito de um número binário é 
chamado de bit (binary digit). É um sistema muito utilizado em circuitos lógicos e 
aritméticos. 
 
 Sistema Hexadecimal (base 16): O sistema hexadecimal ou base 16 possui 16 símbolos para 
representar qualquer quantidade: 0 1 2 3 4 5 6 7 8 9 A B C D E F. É um sistema 
muito utilizado na área de microprocessadores. 
 
0
0
2
2
1
1 **** babababaNúmero
n
n
n
n
n
n ++++=
−
−
−
− K
0123 10*210*510*410*33452 +++=
 85
A equivalência entre os números dos três sistemas numéricos é apresentado na seguinte 
tabela: 
Tabela 16.1 - Equivalência entre os sistemas numéricos. 
Decimal Binário Hexadecimal 
0 0 0 
1 1 1 
2 10 2 
3 11 3 
4 100 4 
5 101 5 
6 110 6 
7 111 7 
8 1000 8 
9 1001 9 
10 1010 A 
11 1011 B 
12 1100 C 
13 1101 D 
14 1110 E 
15 1111 F 
16 10000 10 
17 10001 11 
... ... ... 
 
16.3 Conversão entre Bases 
Para converter um número de um sistema numérico qualquer para a base decimal, basta 
aplicar a lei de formação: 
 
 
Dado um número inteiro na base 10, para obter o equivalente em uma base b qualquer, 
divide-se o número por b sucessivamente até que o quociente da divisão seja menor que b. O último 
quociente da divisão e os restos das divisões sucessivas, tomados na ordem inversa, correspondem 
ao número na base b. 
 
 
 
 
 
 
 
 
 
10
01
16
10
0123
2
)58(1*1016*316*A16*3)A3(
)9(2*12*02*02*1)1001(
=+=+=
=+++=
210
210
)111010()58(
112/3
132/7
072/14
1142/29
0292/58
(?))58(
=
==
==
==
==
==
=
resto
resto
resto
resto
resto
1610
1610
)A3()58(
10316/58
(?))58(
=
==
=
resto
 86
Existem uma relação estreita entre o sistema binário e o hexadecimal. Esta relação vem 
do fato que o número 16 pode ser escrito como 24. 
 
 
 
 
 
 
A conversão de números fracionários é realizada por partes: a parte inteira e a parte 
fracionária. A lei de Formação para números fracionários é: 
 
onde: 
an = algarismo; 
b = base do número; 
n = quantidade de algarismos da parte inteira –1; 
m = quantidade de algarismos da parte fracionária. 
 
Para a conversão de base 10 para base 2 ou base 16, a parte inteira é convertida 
separadamente pelo processo das divisões sucessivas. A parte fracionária é utilizado o processo das 
multiplicações sucessivas pela base desejada. A parte inteira resultante dos produtos formará os 
dígitos da parte fracionária do número convertido. 
 
 
 
 
 
 
 
 
 
162
162
)A3()111010(
A1010
30011
(?))111010(
=
→
→
=
216
216
)00111010()A3(
1010A
00113
(?))A3(
=
→
→
=
m
m
n
n
n
n
n
n bababababababaNúmero
−
−
−
−
−
−
−
−
−
− ++++++++= *******
2
2
1
1
0
0
2
2
1
1 KK
210
210
210
)011,1000()375,8(
000,0
1000,12*500,0
1500,12*750,0
0750,02*375,0
)1000()8(
(?))375,8(
=
→
→=
→=
→=
=
=
Fim
1610
1610
1610
)1,25()0625,37(
000,0
1116*0625,0
)25()37(
(?))0625,37(
=
→
→=
=
=
Fim

Mais conteúdos dessa disciplina