Вы находитесь на странице: 1из 30

Escola Estadual de Educação Profissional Dr.

Solon Tavares
Técnico em Gerenciamento de Redes
Técnico em Sistemas de Informação

Apostila da Disciplina de

Estruturas de Dados

Prof. Alan Malta Rodrigues

Guaíba, 2007.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Sumário

CAPÍTULO 1 – CONCEITOS BÁSICOS


1.1. INTRODUÇÃO
1.2. COMPILAÇÃO DE PROGRAMA C
1.3. MAPEAMENTO DE MEMÓRIA DE C
1.4 . IMPLEMENTAÇÃO
1.5. ESTRUTURA DE UM PROGRAMA C
1.6. ANÁLISE E SOLUCAO DE PROBLEMAS

CAPÍTULO 2 – EXPRESSÕES
2.1. DADO, INSTRUÇÃO E PROGRAMA
2.2. TIPOS DE DADOS
2.3. VARIÁVEIS
2.4. IDENTIFICADORES DE VARIÁVEIS EM C
2.5. CONSTANTES
2.6. ATRIBUIÇÃO
2.7. OPERADORES ARITMÉTICOS
2.8. OPERADORES RELACIONAIS
2.9. OPERADORES LÓGICOS
2.10. OPERADOR BIT A BIT
2.11. OPERADOR ?
2.12. OPERADORES DE PONTEIROS & E *
2.13. OPERADOR SIZEOF
2.14. OPERADORES PONTO (.) E SETA (->)
2.15. PRECEDÊNCIA
2.16. CASTS
2.17. PARÊNTESES E ESPAÇAMENTOS
EXERCÍCIOS

CAPÍTULO 3 – ENTRADA E SAÍDA DE DADOS


3.1. E/S PELO KONSOLE
3.2. PRINTF
3.3. SCANF
EXERCÍCIOS

CAPÍTULO 4 – COMANDOS DE CONTROLE


4.1. DECISÕES COM IF
4.2. DECISÕES COM SWITCH
4.3. LAÇO FOR
4.5. LAÇO WHILE
4.6. LAÇO DO-WHILE
4.7. COMANDOS DE DESVIO INCONDICIONAL
EXERCÍCIOS

CAPÍTULO 5 – VETORES E MATRIZES


5.1. VETORES
5.2. VETORES BIDIMENSIONAIS - MATRIZES

CAPÍTULO 6 – CADEIA DE CARACTERES


6.1. CARACTERES
6.2. STRINGS
6.3. LEITURA E ESCRITA DE CARACTERES E CADEIAS DE CARACTERES
6.4. MANIPULAÇÃO DE STRINGS
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

CAPÍTULO 7 – PONTEIROS
7.1. ARITMÉTICA DE PONTEIROS
7.2. PONTEIROS PARA VETORES
7.3. PONTEIROS PARA VETORES
7.4. CUIDADOS COM PONTEIROS

CAPÍTULO 8 – FUNÇÕES
8.1. ARGUMENTOS DE FUNÇÕES
8.2. COMANDO RETURN

BIBLIOGRAFIA
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Objetivo
Esta apostila foi construída com o intuito de facilitar o ensino da linguagem de
programação C, a ser aplicado na disciplina de Estruturas de Dados do segundo módulo na Escola
Solon Tavares. Poderemos acompanhar o conteúdo através dela, a qual será composta pelos
comandos básicos de C e muitos exemplos e exercícios, pois sem a prática da programação, o
ensino e a compreensão se tornam mais complexo.

1. Conceitos básicos
1.1. Introdução
A linguagem C foi criada por Dennis Ritchie, implementada em UNIX. O nome da
linguagem se deve a uma linguagem anterior que tinha o nome de B. A linguagem segue um
padrão estabelecido em 1983 pelo ANSI (American National Standards Institute). C é considerada
uma linguagem de médio nível, podendo trabalhar com bits, bytes e endereços.
Códigos escritos em C são altamente portáveis, ou seja, programas aplicados em um
sistema operacional funcionarão normalmente em outros sistemas operacionais, com pouca ou
nenhuma alteração. O C é uma linguagem estruturada, ou seja, um programa pode ser dividido em
varias sub-rotinas (mini-programa), onde cada sub-rotina cria suas próprias variáveis e executa
determinada função.
Quando você cria um programa em C, você obtêm o código-fonte, mas para esse
programa ser executado pela máquina é necessário compila-lo. Um compilador tem como função
ler um código-fonte e através da conversão deste criar um código-objeto, então este código-objeto
(também conhecido como código-binário ou código de máquina) pode ser executado pela máquina.
Em Estruturas de Dados serão discutidas diversas técnicas de programação, introduzindo
os conceitos básicos da linguagem de programação C, que serão utilizadas para a implementação
das estruturas de dados apresentadas. A linguagem C tem sido amplamente utilizada na
elaboração de programas e sistemas nas diversas áreas em que a informática atua.
Utilizaremos nas aulas de programação C o sistema operacional Kubuntu GNU/Linux, os
programas serão digitados no Editor de texto Kate e o programa será compilado e executado
através do Konsole. Para quem preferir programar no Windows há uma ferramenta muito boa, na
qual você edita o código fonte, compila e também executa, chamado de Devc++.

1.2. Compilação de programas C


Para compilar um programa em C será necessário seguir basicamente três passos:
1. Criar o programa (código fonte);
2. Compilar o código fonte (gerar o código objeto);
3. Executar o código objeto.
Para estes processos será necessário um editor de textos e um compilador. Com o editor
escreveremos os programas fontes, que devem ser salvos com a extensão “.c”. Com o compilador
geramos o código objeto através do código fonte, para poderem ser executados.
Para compilar um programa, com o nome p.e. “prog.c”, digite no Konsole:

>gcc prog.c –o prog //pode ser assim: gcc -o prog prog.c

Se não houver erro de compilação no arquivo fonte, será gerado um executável com nome
prog. Podemos então executar o programa da seguinte forma:

>./prog

1.3. Mapeamento de memória de C


Quando um programa C é compilado ele cria e utiliza quatro regiões logicamente distintas
na memória. A primeira região armazena o código fonte. A segunda armazena as variáveis globais.
A terceira é a pilha, que tem como funções básicas de armazenar as variáveis locais, os
argumentos passados para funções e também armazenar o endereço de retorno de sub-rotinas. A
quarta e última região é chamada de heap, que consiste de uma área de memória livre,
normalmente utilizada para alocação dinâmica de variávies.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

1.4. Implementação
Tradução do algoritmo para linguagem de programação. Programa é um roteiro que orienta
o computador, mostrando-lhe a seqüência de operações necessárias para executar uma
determinada tarefa.

1.5. Estrutura de um programa C

#include<stdio.h>
main() {
bloco de comandos;
}

- #include<stdio.h>: esta linha mostra ao compilador que será usado o arquivo cabeçalho
stdio.h. Este arquivo contém declarações de funções úteis de entrada e saída de dados (std =
standard, padrão em inglês, io = input/output, entrada/saída em inglês).
- main: define o inicio da execução em um programa C. É a única função obrigatória em
qualquer programa C e é uma palavra reservada da linguagem.
- { }: indicam, respectivamente, o inicio e o termino da função main.
- ( ): contem os parâmetros da função (se existir).
- a palavra reservada main, os parênteses e as chaves são os únicos elementos
obrigatórios.
- as palavras reservadas têm um significado pré-definido na linguagem.
Podem-se inserir comentários no código fonte, iniciados com /* e finalizados com */, assim
como pode ser utilizado também o // (mas este só comenta a linha correspondente). Declarações e
comandos em C são terminados pelo caractere ponto-e-vírgula (;).

1.6. Análise e solução de problemas


- compreensão rigorosa do problema;
- analise dos requisitos;
- coleta de dados;
- estudo de possíveis soluções;
- seleção de uma solução;
- desenvolvimento da metodologia de solução;
- descrição do processo de solução passo a passo;
- programação do algoritmo e depuração do problema;
- validação do programa.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

2. Expressões
A combinação de variáveis, constantes e operadores constituem uma expressão.

2.1. Dado, instrução e programa


Um computador manipula informações ou dados. Uma instrução é algo que manipula
dados. Isto é, uma instrução executa uma determinada operação sobre um ou mais dados. Um
programa é composto por uma serie de instruções.

2.2. Tipos de dados


Em C podemos encontrar cinco tipos básicos de dados: inteiro, ponto flutuante, ponto
flutuante de dupla precisão, caractere e vazio (int, float, double, char e void). Dados do tipo inteiro
geralmente são compostos de quatro bytes, mas isto pode variar de acordo com a arquitetura da
máquina. Valores do tipo caractere geralmente apresentam o tamanho de 1 byte, definido de
acordo com a tabela ASCII. Os dados do tipo ponto flutuante são caracterizados de acordo com
sua faixa de precisão. Por fim, o tipo vazio significa que a função não retorna valores. Os tipos de
dados devem ser definidos para cada variável, sendo que ele define um conjunto de valores que
uma variável pode receber e quais operações podem ser executadas com ela.

Tipo Tamanho Faixa


char 8 bits -128 a 127
unsigned char 8 bits 0 a 255
short int 16 bits -32.768 a 32.767
long int 32 bits -2.147.483.648 a 2.147.483.647
float 32 bits 6 dígitos de precisão
double 64 bits 10 dígitos de precisão

Os tipos short int e long int podem ser referenciados simplesmente com short e long,
respectivamente. O tipo int isolado é mapeado para o tipo inteiro natural da maquina, que pode ser
short ou long.

2.3. Variáveis
• Correspondem a uma posição de memória;
• conteúdo pode variar ao longo do tempo;
• armazenam um só valor por vez;
• armazenam valores de um só tipo (logo, tem tipo definido);
• devem ser declaradas antes de serem utilizadas;
• valor inicial imprevisível (posição de memória);
Uma variável é uma entidade que possui um valor, sendo conhecida no programa por um
nome (identificador). As variáveis são declaradas em três lugares básicos: no campo de
parâmetros de funções, no início de funções e fora de todas as funções.

Variáveis Locais: são declaradas dentro de uma função, somente esta função tem acesso direto a
elas, as variáveis locais deixam de existir quando a função finaliza sua execução. As variáveis
locais devem ser declaradas sempre que inicia-se um bloco de comandos, antes de qualquer
instrução do programa.

Variáveis Globais: normalmente são definidas no inicio do arquivo-fonte, devendo estar fora de
qualquer função. Podem ser acessadas diretamente por qualquer função subseqüente, existem
permanentemente e guardam seus valores enquanto o programa existir.
Forma geral para declaração de variáveis:

tipo lista_de_variáveis;

Onde tipo é um tipo de dado em C, e lista_de_variáveis pode ser composta de apenas 1


variável ou várias, separadas por vírgulas.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Exemplo:
int reta, curva, a, b;
char nome, turma;
short int lado;

Em C é possível inicializar as variáveis junto a declaração, ou seja, no momento que a


variável estiver sendo declarada, ela poderá receber um valor inicial, para isto deve-se colocar um
sinal de igualdade e uma constante logo após o nome, por exemplo:

int reta = 10, curva = 5;


char letra = ‘z’;

2.4. Identificadores de variáveis em C


Para identificar corretamente variáveis e funções, os seguintes itens são necessários:
• o primeiro caractere deve ser uma letra ou _ (sub-linha) e as demais podem ser letras,
numero ou caracteres (sub-linha);
• em C os primeiros 32 caracteres são significativos, ou seja, não adianta colocar
identificadores muito extensos porque serão ignorados pelo compilador;
• o C distingue letras maiúsculas de minúsculas;
• não deve ser utilizado as palavras reservadas da linguagem, assim como não deve ser
dado nomes a variáveis iguais a identificadores de funções.

2.5. Constantes
As constantes se caracterizam por valores fixos que não podem ser alterados. As
constantes satisfazem os cinco tipos de dados em C, variando sua representação de acordo com o
tipo. Para números inteiros e ponto flutuante basta colocar o valor (p.e.: 7, -2.13, 25423).
Constantes do tipo caractere são envolvidas por aspas simples (p.e.: ‘a’, ‘A’, ‘!’). Constantes do tipo
string são representadas entre aspas duplas (p.e.: “ola”, “ola novamente amigo”). Constantes em
octal são representadas com um 0 na frente (e seguidas de 0 a 7) e constantes em hexadecimal
são representadas com um 0x na frente ( e seguidas de 0 a 9 ou de a até f).

2.6. Atribuição
A operação de atribuição especifica que a uma variável será dado um valor ou o resultado
de uma expressão. A atribuição em C é indicada pelo símbolo de igualdade ‘=’. O lado esquerdo da
igualdade será o destino do valor e deve ser uma variável ou um ponteiro, o lado direito pode ser
uma constante, uma expressão ou uma variável.

Exemplo:
variável = expressão; // variável recebe valor da expressão
a = 5; /* armazena o valor 5 em a */
c = 10.3; /* armazena o valor 10.3 em c */
a = b = c = 10; // todas as variáveis recebem o valor 10

2.7. Operadores Aritméticos


Operadores aritméticos são usados para desenvolver operações matemáticas.

+ Adição
- Subtração
* Multiplicação
/ Divisão
% Módulo (devolve o resto da divisão inteira, e só aceita operandos inteiros).
++ Incremento
-- Decremento
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Exemplo:
c=a+b; /* armazena a soma do conteúdo de a e b em c */
i=i+2; // variável i recebe conteúdo de i + 2
n++; // n recebe n + 1;
n--; // n recebe n – 1;

Também temos operadores que C reduzido, simplificando a codificação de certas


operações de atribuição. Sua forma geral é:

variável operador = expressão; // variável = variável operador expressão;

Exemplo:
x += 10; // é igual a x = x + 10;
y *= (10 + 25); // é igual a y = y * (10 + 25)

2.8. Operadores Relacionais


Os operadores relacionais realizam comparações entre duas ou mais variáveis. O
resultado gerado por um operador relacional ou operador lógico é um (1) ou zero (0) (verdadeiro ou
falso). Em C não existe o tipo booleano (verdadeiro ou falso). O valor zero é interpretado como
falso e qualquer valor diferente de zero é considerado verdadeiro.

> Maior que


>= Maior ou igual a
< Menor que
<= Menor ou igual a
== Igual a
!= Diferente de

2.9. Operadores Lógicos


Os operadores lógicos realizam comparações e retornam verdadeiro ou falso.
Normalmente são utilizados para tomada de decisões e para atribuir valores a variáveis.

&& Operador lógico “E”


|| Operador lógico “OU”
! Negação

2.10. Operador Bit a Bit


Como C foi projetada para substituir o assembly em muitas tarefas de programação, ela
suporta manipulação de bits. As operações bit a bit testam, atribuem ou deslocam bits em 1 byte
ou uma palavra, portanto, só podem ser utilizados em dados do tipo int e do tipo char.

& Operador lógico “E”


| Operador lógico “OU”
^ Operador lógico “XOR” (ou exclusivo)
~ Complemento de um
>> Deslocamento à direita
<< Deslocamento à esquerda

2.11. Operador ?
O operador ternário ? é utilizado para substituir uma instrução de desvio condicional como
if-then-else. Sua forma geral é:

expressão1 ? expressão2 : expressão3;


Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Onde expressão1 é a expressão que está sendo testada, se ela for verdadeira a
expressão2 será validada, caso contrário a expressão3 será validada.

Exemplo:
resultado = (nota>6) ? 10 : 0; // resultado recebe 10 ou 0

2.12. Operadores de Ponteiros & e *


Um ponteiro referencia um endereço de memória e ao mesmo tempo seu conteúdo. As
principais funções de ponteiro consistem em referenciar rapidamente elementos de uma matriz,
permite modificar seus valores entre funções e suportam estruturas dinâmicas de dados. O
operador unário & devolve o endereço de memória de seu operando (unário porque necessita de
apenas um operando).

pt = &auxiliar;

No exemplo acima, o ponteiro pt recebe o endereço de memória da variável auxiliar, onde


este endereço é a posição interna da variável no computador.
O segundo operador unário * devolve o conteúdo da variável localizada no endereço que o
segue. Para o exemplo a seguir considere que a variável esta localizada no endereço 65000 e
possui o valor 7.

pt = &auxiliar; // pt recebe o endereço da variável auxiliar (65000)


num = *pt; // num recebe o valor apontado pelo endereço de pt (7)
*pt = 9; // endereço 65000 recebe o valor 9

A declaração de variáveis ponteiros é diferente das outras, pois devem receber o símbolo *
antes do nome da variável. De acordo com o tipo de dados que for apontado por um ponteiro, este
deverá corresponder ao tipo declarado.

Exemplo:
float *pt; // este ponteiro irá apontar dados do tipo ponto flutuante
char *ch; // já este irá apontar dados do tipo caractere

2.13. Operador sizeof


Este operador unário retorna o tamanho, em bytes, de uma determinada variável ou
especificador de tipo, porém este último deve estar entre parênteses.

Exemplo:
int a;
char b;
a = sizeof (float); // armazena o valor 4 em a
a = sizeof b;

2.14. Operadores Ponto (.) e Seta (->)


Estes operadores referenciam elementos de estruturas e uniões, nos quais são tipos de
dados compostos referenciados por um nome. O operador ponto é utilizado quando for necessário
referenciar uma estrutura ou união. Já o operador seta será utilizado quando utilizarmos ponteiros
para uma estrutura ou união.

Exemplo:
struct solon {
char nome[30];
float nota;
}est;
struct solon *pt = &est; // ponteiro pt recebe endereço da estrutura (est)
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

est.nota = 9.5; // elemento nota da estrutura recebe 9.5


pt -> nota = 9.5; // elemento nota da estrutura recebe 9.5

2.15. Precedência
Maior precedência () [] ->
! ++ --
* / %
+ -
< <= > >=
== !=
&&
|| Menor precedência

2.16. Casts
Quando utilizamos tipos de dados diferentes em expressões, o compilador faz conversões
de operandos que possuem tamanho menor em maiores, se existirem na expressão, porém,
podemos garantir um tipo de dado final da expressão com Casts. Este comando irá forçar uma
expressão a ser de determinado tipo. Onde tipo é qualquer tipo de dado válido em C. Sua forma
geral é:

(tipo) expressão;

2.17. Parênteses e Espaçamentos


Visando tornar expressões e o programa mais legível, podemos acrescentar espaçamentos
e tabulações no código fonte. Assim como parênteses adicionais facilita a compreensão de uma
expressão e dá mais controle ao programador referente às precedências de operações.

Exercícios:
Resolva as expressões abaixo e descubra se o resultado é 1 (Verdadeiro) ou 0 (Falso).

a) 10 > 3

b) 10 != 10

c) (10 >= 9) || (10 >= 11)

d) (10 <= 11) && (10 >= 9)

e) !(7 >3) || !(5 < 7)

f) !(9 < 0) && (9 > 0)

g) (23 >= 2) || ! !(13 < 6)


Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

3. Entrada e Saída de dados


Em C há dois tipos de E/S de dados, a primeira é pelo Konsole e a segunda por arquivos.

3.1. E/S pelo Konsole


Em C, tudo é feito através de funções, inclusive as operações de entrada e saída. Na
linguagem C temos uma biblioteca padrão que possui as funções básicas normalmente
necessárias. Para isso, devemos incluir o protótipo destas funções no inicio do código.

#include <stdio.h>

A linguagem C contém um conjunto de instruções que permitem ao operador interagir com


o programa fornecendo dados e recebendo mensagens. As funções printf( ) e scanf( ) são
responsáveis pela entrada e saída de dados, podendo ler e escrever dados em vários formatos.

3.2. printf
Esta função escreve dados no vídeo e sua forma geral é:

printf (“string_de_controle”,lista_de_argumentos);

A string_de_controle descreve o que a função printf( ) vai imprimir na tela. Ela mostra não
somente a mensagem que deve ser colocada na tela, mas também quais as variáveis e suas
respectivas posições, isto é feito usando-se os códigos de controle que usam a notação %. Na
string de controle indicamos quais, de qual tipo e em que posições estão as variáveis a serem
impressas. Para cada código de controle deve haver uma variável na lista_de_argumentos, estes
dois são combinados na ordem da esquerda para a direita.

Códigos de Controle: %d Inteiro


%c Caracter
%f Ponto flutuante
%s String
%o Octal
%x Hexadecimal
%% Imprime o caractere %
%p Imprime o endereço da variável

Exemplo:
int b = 8;
float a = 10.4;
printf(“\n\tO inteiro eh %d e o real eh %f \n”, b, a);
//será impresso no Konsole “O inteiro eh 8 e o real eh 10.4”(sem aspas)
printf(“\n Ola,eu estou vivo!”);
// será impresso no Konsole “Ola,eu estou vivo!”

No lugar do %d será impresso o valor armazenado na variável b (valor inteiro) e no lugar


do %f será impresso o valor armazenado na variável a (valor real). O \n significa nova linha e o \t
significa tabulação no terminal, sendo assim antes de imprimir a mensagem pularia uma linha e
daria uma tabulação para a mensagem ser impressa.
Para escrever um caracter deve-se utilizar o código %c. Mas se for preciso imprimir uma
string deve-se usar o código %s.

3.3. scanf:
Responsável pela entrada de dados via Konsole, sua forma geral é:

scanf(“string_de_controle”,lista_de_argumentos);
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Usando a função scanf( ) podemos pedir dados ao usuário. O numero de argumentos na


lista_de_argumentos deve ser igual ao de códigos de controle na string_de_controle. Deve-se
colocar o “&” antes de cada argumento da lista_de_argumentos. Os códigos de controle na
string_de_controle são os mesmos da função printf( ) => ( %d, %f, %c, %s). A função scanf( )
termina a leitura de um número quando um caractere diferente de números for pressionado.
Para a leitura de uma string devemos utilizar o código %s, no qual acabará a leitura da
string quando for encontrado um caractere de espaço em branco, porém, se for necessário
controlar a leitura de caracteres de uma string, coloca-se o número de caracteres máximo a ser lido
pelo scanf( ) para determinada cadeia de caracteres.

Exemplo:
scanf(“%20s”,str); // irá ler apenas os 20 primeiros caracteres digitados

Exemplo: // b recebe um número inteiro digitado


scanf(“%d %f”,&b,&a); // a recebe um número real digitado

scanf(“%c”,&símbolo); // símbolo recebe um caractere

Exercícios: Desenvolva programas em C para as seguintes questões.

1. Ler dois valores inteiros e imprimi-los.

2. Ler três valores reais e imprimir o somatório deles.

3. Armazenar o valor 10 na variável a, o valor 5 na variável b e trocar seus conteúdos


apresentando a resposta.

4. Supondo um valor real referente a largura e um outro referente ao comprimento de uma


sala, escreva um programa que calcule a área dessa sala.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

4. Comandos de controle
Em C encontramos dois comandos de desvio condicional, esse desvio depende do teste de
uma expressão, resultando em um valor verdadeiro ou falso, porém, não encontramos esses
resultados em C, mas sim valores iguais ou diferentes de zero. Para qualquer valor diferente de
zero consideramos que a resposta é verdadeira, já um valor falso é representado pelo valor 0.

4.1. Decisões com if


A estrutura básica do comando if é:

if(condição) {
comando ou bloco de comandos;
}
ou
if(condição) {
bloco de comandos do if;
}
else {
bloco de comandos do else;
}

Na primeira estrutura se a expressão produzir um valor diferente de 0 (verdadeiro), o bloco


de comandos será executado, caso contrário a execução do programa continua a partir do fecha
chaves “}”. Na segunda estrutura temos duas opções, se o teste for diferente de 0 (verdadeiro) o
bloco de comandos do if que está delimitado pelas chaves será executado, caso contrário (se a
expressão resultar no valor 0), somente o bloco de comandos do else será executado.
Os blocos de comando devem ser delimitados por uma chave aberta e uma chave fechada,
porém, se o desvio possuir apenas uma instrução (um comando), não se torna obrigatório o uso de
chaves. A indentação (recuo de linha) dos comandos é fundamental para uma maior clareza do
código.
Na instrução if-else, ou será executado o bloco de comandos do if, ou será executado o
bloco de comandos referente ao else. Leia assim, “se isto, então isso, se não aquilo...”. Em C, um
comando else sempre se refere ao comando if mais próximo.

Exemplo: /*Recebe 2 valores e acha o maior*/


#include<stdio.h>
int main() {
int n1, n2; // variáveis do tipo inteiro
printf(“\n Entre com 2 valores inteiro\n”);
scanf(“%d %d”, &n1, &n2); //armazena 1 dado lido em cada variável
if (n1 > n2)
printf(“\n Este valor eh o maior %d \n”,n1);
else
printf(“\n Este valor eh o maior %d \n”,n2);
}

O uso de comandos if aninhados (em cascata) é válido e muito usado. Conforme veremos
no exemplo:

if (expressão) {
if (expressão)
comando;
if (expressão)
comando;
else
comando; }
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Com a utilização do comando if podemos construir a chamada escada if-else-if, a qual


consiste em um novo teste condicional caso o teste anterior tenha retornado 0 (falso), até que
encontre o último else ou satisfaça algum dos testes anteriores, conforme mostra o exemplo:

if (expressão)
comando;
else if (expressão)
commando;
else if (expressão)
commando;
...
else
commando;

4.2. Decisões com switch


O comando switch é uma estrutura de controle condicional. Permite que grupos
particulares de instruções sejam escolhidas entre grupos possíveis. A escolha é baseada no valor
correspondente de uma variável ou expressão.
O comando switch é próprio para se testar uma variável em relação a diversos valores
pré-estabelecidos, tanto para constantes inteiras quanto para caracteres.
Sua forma geral é:

switch(variável ou expressão) {
case constante1:
comando1;
break;
case constante2:
comando2;
break;
.... ....
.... ....
case onteúdo n:
comandoN;
break;
default:
comando_default;
break;
}

O switch testa a variável (ou expressão) contra os valores especificados nos comandos
case e executa o comando (ou bloco de comandos) cujo case coincidiu com o valor da variável ou
expressão, esses comandos serão executados até que seja encontrado o comando break ou o fim
do comando switch. A declaração default é opcional e será executada apenas se a variável (ou
expressão) que está sendo testada não for igual a nenhuma das constantes pré-estabelecidas nos
case. O case não pode existir fora do comando switch.
O break é um comando de desvio em C, faz com que o switch seja interrompido passando
a execução do programa a partir da próxima linha de comando após o fecha chaves do switch. O
comando break é muito utilizado em laços.
Duas constantes case no mesmo switch não podem possuir o mesmo valor, à exceção de
um switch dentro de outro. No caso de constantes caracteres, estas devem estar entre aspas
simples, e elas são automaticamente convertidas para seus valores correspondentes inteiro de
acordo com a tabela ASCII.
É possível ter instruções case sem nenhum comando associado, porém, quando isto
acontece a execução do programa cai no próximo case. É importante deixar claro que todo o
comando switch forma um bloco de comandos e os comandos associados a cada case são uma
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

seqüência de comandos, ou seja, variáveis locais são declaradas no início de blocos de comandos
e não podem ser declaradas dentro dos comandos associados aos cases.

Exemplo: /*Entre com o dia da semana e será impresso o nome*/


#include<stdio.h>
int main() {
int num;
printf(“\n Digite um numero entre 1 e 7 \n”);
scanf(“%d”,&num); // armazena valor inteiro em num
switch(num) { // testa num
case 1:
printf(“\n Domingo\n”);
break;
case 2:
printf(“\n Segunda-feira\n”);
break;
case 3:
printf(“\n Terca-feira\n”);
break;
case 4:
printf(“\n Quarta-feira\n”);
break;
case 5:
printf(“\n Quinta-feira\n”);
break;
case 6:
printf(“\n Sexta-feira\n”);
break;
case 7:
printf(“\n onteú\n”);
break;
default: //se valor for != dos case entra aqui no default
printf(“\n Valor digitado invalido\n”);
break;
}
system(“pause”); // para usuários do devc++, não permite
} // que feche o terminal do dev

4.3. Laço for


Algoritmos com laços (loopings) definem conjuntos de instruções que devem ser
executadas repetidas vezes, ou seja, uma ação deve ser realizada um numero preciso e conhecido
de vezes em um ou mais comandos.
O comando das execuções é por contagem, utilizando uma variável contadora. Execuções
acontecem até que um valor limite para a variável contador seja ultrapassado.
Sua forma geral é:

for(inicialização; condição; incremento)


comando;

Onde a inicialização normalmente é um comando de atribuição que inseri um valor inicial


na variável de controle (contador). A condição carrega uma expressão relacional, pode ser lógica
também, a qual determina até quando o laço será executado. Por fim, o incremento é caracterizado
pela operação que é executada em cima da variável contadora todas as vezes que o laço se
repetir. No momento que a condição se tornar falsa, o laço não é mais executado e o programa da
continuidade após o final do bloco de comandos do for.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Exemplo1:
#include<stdio.h>
int main( ) {
int contador;
for(contador=1;contador<=100;contador++)
printf(“\n Não devo conversar em aula”);
}

No exemplo 1, o contador é inicializado com 1, a operação em cima do contador é de


incremento de uma unidade e a condição é que o contador seja menor ou igual a 100, assim que o
contador se tornar maior que 100 será interrompida a execução do laço. A mensagem “Não devo
conversar em aula” será impressa cem vezes e após será finalizado o programa.
O melhor modo de entender o laço for é ver de que maneira ele “funciona”. O laço for é
equivalente a:

inicialização
if (condição) {
comando; // ou bloco de comandos
incremento;
“volte para o comando if”
}

Podemos ver que o for executa a inicialização incondicionalmente e então testa a


condição. Se ela for falsa, não faz mais nada, se ela for verdadeira, ele executa o comando (ou
bloco de comandos), realiza o incremento e volta a testar a condição. Ele fica repetindo estas
operações até que a condição seja falsa.

Exemplo2:
for (i=100; i>0; i=i-1)
printf(“\n %d ”, i);

No exemplo 2 será impresso todos os valores inteiros entre os números 100 e 1, na ordem
decrescente de unidade em unidade, até que o valor 0 seja atingido no contador (i) e interrompa a
execução do looping.

Exemplo3:
for (i=0; i>0; i=i+5)
printf(“\n Oi ”);

Neste exemplo 3 não será impresso nenhuma vez a mensagem “Oi”, pois o laço é
inicializado com 0 e a condição exige que este valor seja maior que zero..

Exemplo4:
for (i=0; i!=666; )
scanf(“%d”, &i);

Conforme demonstrado no exemplo 4, partes da definição do laço for não precisam existir.
O programa inicializa a variável i com 0 e testa se ela é diferente de 666, enquanto o usuário não
digitar este último valor o laço continuará em execução, sem que seja feito nenhuma operação de
incremento na repetição do laço.

Exemplo5:
for ( ; ; )
printf(“ Looping Infinito”);
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

O exemplo 5 sinaliza a construção de um laço infinito, ou seja, os comandos associados ao


for serão eternamente executados até que o computador estrague, falte energia ou até o fim do
mundo.

4.4. Laço while


O while é um comando de laço, isto é, que permite que as instruções que se encontram
dentro do laço sejam repetidas.
Sua forma geral é:

while (condição)
comando; // ou bloco de comandos entre chaves

Ele faz com que o laço (comando ou bloco de comandos) sejam executados enquanto a
condição for verdadeira, onde a condição verdadeira será sempre que for um valor diferente de
zero. Quando a condição for falsa, a execução do programa passa para o próximo comando após
o bloco de comandos do laço while.
O while seria equivalente a:

if(condição) {
comando;
“volte para o comando if”
}

O while tem a mesma característica que o laço for referente a verificação condicional, que
sempre é feita no inicio do laço.

Exemplo:
#include<stdio.h> // imprime o numero de i de 0 ate 99
int main( ) {
int i=0;
while(i<100) {
printf(“ %d “,i);
i++; }
}

4.5. Laço do-while


Em C podemos ver outro comando para a construção de laços, cujo teste é avaliado
somente no final do laço. O comando do-while garante que pelo menos uma vez será executado o
comando ou bloco de comandos.

do {
comando ou bloco de comandos;
}while(condição);

Este laço repete o comando ou bloco de comandos até que a condição seja falsa, ou seja,
até que o valor condicional resultante seja zero. Para esta instrução, procure sempre utilizar as
chaves, mesmo que tenha apenas um comando, a fim de evitar confusões futuras.

Exemplo:
do {
scanf(“%d”, &valor);
} while( (valor >= 1) && (valor <= 100) )

O exemplo acima demonstra um código que lerá do teclado um valor, enquanto este valor
estiver compreendido entre 1 e 100, ele continuará lendo novos valores, quando for digitado um
valor maior que 100 ou menor que 1 o laço interrompe a execução.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

4.6. Comandos de Desvio Incondicional


O C disponibiliza quatro comandos de desvio incondicional, dois deles você utiliza em
comandos de loopings e os outros dois em qualquer parte do programa.
Comando return
Comando utilizado para retornar de uma função, retorna a execução do programa a partir
do ponto em que foi chamado na outra função. Sempre que for encontrado o primeiro return a
função será finalizada, assim como se for encontrado o símbolo “}”. Este comando pode
simplesmente retornar de uma função, como retornar um valor para a função que a chamou. Se
nenhum valor for especificado, será retornado lixo (ou dependendo do compilador será zero). A
forma geral deste comando é:

return expressão;

É importante enfatizar que em funções do tipo void não poderá ser utilizado o comando
return.
Comando goto
Comando de desvio incondicional, normalmente não utilizado em C devido a ilegibilidade
do código fonte. Utilizando este comando você define um rótulo, este rótulo você coloca em outra
parte do programa seguido de dois pontos “:”, definindo ali o ponto de salto (destino) do programa.
Sua forma geral é a seguinte:

goto rótulo;
...
...
rótulo:

Comando break
Conforme estudado no comando switch, o comando break é utilizado para interromper a
execução dos comandos dentro de um case, assim como interromper a continuidade de execução
de um laço.
Função exit()
Utilizando a função exit() você sai imediatamente de um programa. Sua forma geral é:

exit(código_de_retorno);

Onde código_de_retorno contém um valor inteiro, se este valor for 0 (zero) significa para o
sistema operacional que o programa teve uma terminação normal, já outros valores normalmente
indicam algum tipo de erro.

Exercícios:
1) Faca um programa que receba hora e minuto inicial e final de uma partida de tênis, a duração do
jogo não pode ultrapassar 60 minutos. O programa deve calcular a duração do jogo, considere que
o jogo pode começar em um dia e acabar somente no outro.

2) Faça um programa que simule uma calculadora padrão, com as operações ‘+’ soma, ‘-‘
subtração, ‘*’ multiplicação e ‘/’ divisão. Inicialmente o programa deve pedir a operação ao usuário,
após o usuário deve entrar com os 2 operandos. Ao final, o programa deve imprimir a resposta.

3) Faça um programa que receba um valor n inteiro e calcule seu fatorial. O programa deve
imprimir a resposta.

4) Faça um programa que continue em execução enquanto não receber um valor múltiplo de 7,
assim que for digitado um valor correto o programa deverá encerrar sua execução.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

5) Escreva um programa que descubra se três valores recebidos estão ou não em ordem
crescente.

6) Escreva um programa que mostre na tela o conceito conforme a nota obtida, de acordo com a
tabela seguinte:
De 9,0 a 10,0 A
De 7,5 a 9,0 B
De 6,0 a 7,5 C
De 4,0 a 6,0 D
De 0,0 a 4,0 E
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

5. Vetores e Matrizes
Vetores e matrizes são conjuntos de variáveis que são referenciados pelo mesmo nome, e
trabalham com o mesmo tipo de dados. Para ter o acesso a essas diferentes variáveis é
necessário utilizar índices. Esses índices atuam como deslocamentos na memória a partir de um
endereço inicial. Vetores e matrizes em C utilizam uma parte contígua da memória, onde o primeiro
índice corresponde ao endereço mais inferior e o ultimo índice corresponde ao endereço superior
da memória.

5.1. Vetores
A forma geral para declarar um vetor em C é a seguinte:

tipo_de_dado nome_da_variavel[tamanho];

Assim como as variáveis, vetores também devem ser declarados. Esta declaração reserva
um espaço na memória suficientemente grande para armazenar o número de células especificadas
por tamanho, onde está especificado quantos elementos o vetor poderá guardar. No campo
tipo_de_dado será escolhido um dos tipos de dados da linguagem C (inteiro, real, caracter). O
nome_da_variavel é o identificador do vetor. Na linguagem C, a numeração dos índices de um
vetor ou matriz inicia sempre em zero, ou seja, o primeiro elemento sempre será referenciado pelo
índice 0. Isto significa que, no exemplo abaixo, os dados serão indexados de 0 a 29.

Exemplo1:
int num[30]; // declara vetor do tipo inteiro que poderá armazenar até 30 valores

num[0]= 10; // armazena 10 na primeira posição do vetor num


num[1]= 2; // armazena 2 na segunda posição do vetor num
...
num[29]= num[1]; // atribui conteúdo da segunda p/ última posição da variável num

Nada impede de escrever:


num[30];
num[103];

Em C não é verificado se o índice usado está dentro dos limites válidos. Este é um cuidado
que o programador deve tomar, caso contrário há risco de haver variáveis sobre-escritas ou de
escrever no próprio código do programa.

Exemplo2: /*preenchimento de um vetor de tamanho 10*/


#include<stdio.h>
int main() {
int vet[10],i;
printf(“\n Digite um valor inteiro e pressione ENTER \n”);
for(i=0;i<10;i++) // lerá 10 valores digitados no teclado
scanf(“%d”,&vet[i]);
}
/* lê dado a dado e armazena na variável com índice i */

Vetores e matrizes podem ser passados como parâmetros para funções, porém, não é
todo o vetor que será passado, mas sim um ponteiro para o primeiro elemento do vetor. Para isso
você deve passar como parâmetro apenas o nome do vetor, sem colocar o índice.

Exemplo3: // chamando a função soma e passando como parâmetro o 1º elemento de nota


int nota[5];
soma(nota);
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

A função que está sendo chamada, que irá receber o ponteiro para o primeiro elemento do
vetor nota, deve estar preparada para isso. A variável que vai receber este parâmetro poderá ser
declarada de três formas distintas, conforme o exemplo a seguir:

Exemplo4: // referente ao exemplo3, parte da função que receberá o parâmetro


void soma(int aux[5]) { //declarando um vetor de mesmo tamanho
...
}
ou

void soma(int aux[]) { //declarando um vetor sem tamanho


...
}
ou

void soma(int *pt) { //declarando um ponteiro


...
}

5.2. Vetores Bidimensionais – Matrizes


Em C podemos criar vetores multidimensionais, mas normalmente é utilizado
bidimensionais. Por exemplo, para declararmos uma matriz de valores reais com 4 linhas e 3
colunas, fazemos:

float mat[4][3];

Esta declaração reserva um espaço de memória necessário para armazenar os 12


elementos ( 4 x 3 ) da matriz, que são armazenados de maneira contígua, organizados linha a
linha.
Os elementos da matriz são acessados com indexação dupla. No exemplo acima o
primeiro índice é 4, este significa que a matriz apresenta 4 linhas. O segundo índice é 3, este
significa que a matriz apresenta 3 colunas. Como em C a indexação começa em zero, o elemento
da primeira linha e primeira coluna será acessado pelos índices mat[0][0].
Para declarar uma matriz em C, utilizamos a seguinte forma geral:

tipo_da_variavel nome_da_variavel[linha][coluna];

As matrizes também podem ser inicializadas na declaração:

float mat[4][3] = {1,2,3,4,5,6,7,8,9,10,11,12};

Exemplo1: /*exemplo de preenchimento de matriz 4x3*/


for(i=0; i<4; i++) //controle das linhas da matriz
for(j=0; j<3; j++) //controle das colunas da matriz
scanf(“%f”,&mat[i][j]); //matriz recebe valor

No exemplo acima, a cada vez que for executado o primeiro comando for, será executado
todas as vezes possíveis o segundo laço for. Será executado esse conjunto de laços até que a
condição do primeiro laço for seja falsa.

Exemplo2: /* impressão do conteúdo de uma matriz 4x3 */


for(i=0; i<4; i++) // controle das linhas da matriz
for(j=0; j<3; j++) // controle das colunas da matriz
printf (“mat[%d][%d] = %f\n”,i,j,mat[i][j]);
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

6. Cadeia de Caracteres

6.1. Caracteres
Os caracteres são representados por códigos numéricos. A correspondência entre os
caracteres e seus códigos numéricos é feita por uma tabela de códigos. Em geral, usa-se a tabela
ASCII, mas diferentes máquinas podem usar diferentes códigos.
Em C, a diferença entre caracteres e inteiros é feita apenas através da maneira pela qual
são tratados. Por exemplo, podemos imprimir o mesmo valor de duas formas diferentes usando
formatos diferentes. Um constante caractere é escrito envolvendo o caractere com aspas simples.
Assim, a expressão ‘a’ representa um constante caractere e resulta no valor numérico associado
ao caractere a.

char c = ‘a’;
printf(“%d %c\n”, c, c);

6.2. Cadeia de caracteres (strings)


Em C uma string de caracteres é definida como um vetor ou uma matriz de caracteres.
Esse vetor deve terminar com o caractere ‘\0’ (também denominado de caracter nulo). Por essa
razão um string deve conter uma posição a mais do que o número de caracteres que se deseja.
Portanto se desejamos guardar um string de n caracteres devemos definir um vetor com tamanho n
+ 1. Constantes strings são uma lista de caracteres que aparecem entre aspas, não sendo
necessário colocar o ‘\0’, ele é colocado pelo compilador.
Sempre que for necessário trabalhar com strings, o programador deverá incluir a biblioteca
padrão, usando o seguinte cabeçalho no início do código fonte:

#include<string.h>
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

O especificador de formato %s da função printf() permite imprimir uma cadeia de


caracteres. A função printf então recebe um vetor de char e imprime elemento por elemento, até
encontrar o caractere nulo.
Formas de inicializar uma cadeia de caracteres:

(1) char str[10]=“um texto”;

(2) char str[10]={‘u’,‘m’,‘ ’,‘t’,‘e’,‘x’,‘t’,‘o’,’\0’};

(3) strcpy(str,“um texto”);

(4) char str[4];


str[0]=’O’;
str[1]=’l’;
str[2]=’a’;
printf(“%s \n”,str);

A inicialização de cadeias de caracteres é tão comum em códigos C que a linguagem


permite que elas sejam inicializadas escrevendo-se os caracteres entre aspas duplas. Sempre que
for utilizado um constante string, o compilador automaticamente fornece o terminador nulo.
Para ilustrar a declaração e inicialização de cadeias de caracteres, consideremos as
declarações abaixo:

char s1[] = “”;


char s2[] = “Bom dia pessoal”;
char s3[81];
char s4[81] = “Ola”;

Nestas declarações, a variável s1 armazena uma cadeia de caracteres vazia, representada


por um vetor com um único elemento, o caractere ‘\0’. A variável s2 representa um vetor com 15
elementos. A variável s3 representa uma cadeia de caracteres capaz de representar cadeias com
até 80 caracteres, já que foi dimensionada com 81 elementos. Esta variável, no entanto, não foi
inicializada e seu conteúdo é desconhecido. A variável s4 também foi dimensionada para
armazenar cadeias de até 80 caracteres, mas seus primeiros quatro elementos foram atribuídos
na declaração.

6.3. Leitura e escrita de caracteres e cadeias de caracteres


Para capturarmos o valor de um caractere simples fornecido pelo usuário via teclado,
usamos a função scanf, com o especificador de formato %c.

char a;
scanf(“%c”, &a);

6.3.1. Saída de dados com strings


Para saída de dados com strings pode-se usar o formato “%s” da função printf e passar a
variável string diretamente como argumento. Também se pode usar a função puts para este fim:

puts(<var_string>);

Esta função escreve o seu argumento no dispositivo padrão de saída (vídeo), colocando
um ‘\n’ (um salto de linha) no final.

6.3.2. Entrada de dados em strings


A função scanf só lê strings de uma palavra com o formato “%s”. No primeiro espaço em
branco a função encerra. Para a leitura de uma string com tamanho indeterminado deve-se usar a
função gets:
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

gets(<var_string>);

Esta função é utilizada para leitura de uma string através do dispositivo padrão, até que a
tecla ENTER seja pressionada. A função gets() não testa limites do vetor em que é chamada.

Exemplo1:
main() {
char str1[80];
printf(“Entre com um string:\n”);
gets(str1);
printf(“O string lido foi:\n”);
puts(str1);
printf(“Entre com uma palavra:\n”);
scanf(“%s”,str1);
printf(“A palavra lida foi: %s”,str1);
}

Exemplo2: /* impressão caracter a caracter */


int I;
for(i=0;s[i]!=’\0’;i++)
printf(“%c”,s[i]);
printf(“\n”);

O exemplo acima tem a mesma funcionalidade da linha de comando abaixo:

printf(“%s\n”,s);

Exemplo3: /*descobre o comprimento da cadeia de caracteres*/


int i;
int n=0; /* contador */
for(i=0;s[i]!=’\0’;i++)
n++;

Para contar o número de caracteres da cadeia, basta contarmos o número de caracteres


até que o caractere nulo (que indica o fim da cadeia) seja encontrado. O caractere nulo em si não
deve ser contado.

Exemplo4: /*copia uma cadeia de caracteres p/ um vetor de caracteres*/


int I;
for(i=0;orig[i]!=’\0’;i++)
dest[i]=orig[i];
dest[i]=’\0’; /*fecha a cadeia copiada*/

Assumimos que a cadeia que receberá a cópia tem espaço suficiente para que a operação
seja realizada. Salientamos a necessidade de “fechar” a cadeia copiada após a cópia dos
caracteres não nulos. Quando o laço for terminar, a variável i terá o índice de onde está
armazenado o caractere nulo na cadeia original. A cópia também deve conter o ‘\0’ nesta posição.

Exemplo5: /*concatenar um string no final de outra string*/


int i=0; /*conteúdo usado na cadeia destino*/
int j; /*conteúdo usado na cadeia origem*/
/*acha o final da cadeia destino*/
while(s[i]!=’\0’)
i++;
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

/*copia elementos da origem para o final do destino*/


for(j=0;orig[j]!=’\0’;j++) {
dest[i]=orig[j];
i++; }
dest[i]=’\0’; /*fecha cadeia destino*/

Concatenar é, colocar os caracteres de uma cadeia de caracteres no final de outra cadeia.


Assim, se uma cadeia representa inicialmente a cadeia Ola e concatenarmos a ela a cadeia Turma,
teremos como resultado a cadeia OlaTurma.
Funções análogas às funções comprimento, copia e concatena são disponibilizadas pela
biblioteca padrão de C. As funções da biblioteca padrão são, respectivamente, strlen, strcpy e
strcat, que fazem parte da biblioteca de cadeias de caracteres (strings), string.h. Existem diversas
outras funções que manipulam cadeias de caracteres nessa biblioteca.

6.4. Manipulação de strings


A manipulação de strings em C é feita através de rotinas especializadas para este
tratamento. Existem rotinas para copiar, concatenar e comparar strings, além de contar o número
de caracteres (o tamanho) de um string. A seguir serão apresentadas as principais rotinas de
manipulação de strings. Entretanto, é importante ressaltar que esta não é uma lista completa das
rotinas de manipulação de strings. Além destas funções, há outras que podem ser consultadas no
manual de referência da linguagem que apresenta a biblioteca de rotinas padrão de C.

6.4.1. Função strcpy


Serve para copiar o conteúdo de um string para outro. Ela recebe o endereço de dois
strings e copia o conteúdo do segundo string (<string2>) para dentro do primeiro string (<string1>).
O conteúdo original do primeiro string é apagado e o conteúdo do segundo string é copiado por
cima. O segundo string não sofre alteração. O primeiro string deve possuir espaço livre suficiente
para a cópia.

strcpy(<string1>,<string2>);

6.4.2. Função strlen


Serve para contar quantos caracteres existem num string. Ela recebe o endereço de um
string e retorna o tamanho deste. Esta função não conta o caracter ‘\0’ do fim do string.

strlen(<string>);

6.4.3. Função strcat


Serve para concatenar o conteúdo de um string no fim de outro string. Ela recebe o
endereço de dois strings e copia o conteúdo do segundo string (<string2>) no fim do primeiro string
1 (<string1>). O segundo string não sofre alteração. O primeiro string deve possuir espaço livre
suficiente para a concatenação.

strcat(<string1>,<string2>);

6.4.4. Função strcmp


Serve para comparar dois strings. Ela recebe o endereço de dois strings e compara o
conteúdo de um string contra o outro. Esta função irá retornar um valor numérico negativo, zero ou
positivo dependendo do resultado da comparação, de acordo com as seguintes regras:
• Retorna um número negativo se o <string1> for menor que o <string2>
• Retorna zero se o <string1> for igual ao <string2>
• Retorna um número positivo se o <string1> for maior que o <string2>

strcmp(<string1>,<string2>);

Observações:
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

• Letras maiúsculas são consideradas diferentes de minúsculas;


• O valor de retorno corresponde à diferença em ASCII entre os primeiros dois caracteres
diferentes.

Exemplo6:
main() {
char str1[100],str2[100],str3[100];
//inicializa um string com uma constante
strcpy(str1,“uma constante string”);
//copia o onteúdo de um string noutro
strcpy(str2,str1);
//concatena um texto ao fim de str1
strcat(str2,“que foi concatenada com outra”);
//inicializa o string str3
strcpy(str3,“uma constante string”);
//compara os tamanhos de strings
if(strlen(str1)==strlen(str3))
printf(“str1 tem o mesmo tamanho de str3\n”);
else
printf(“str1 não tem o mesmo tamanho que str3\n”);
//compara os strings str1 e str2
if(strcmp(str1,str2)==0)
printf(“str1 e str2 sao iguais\n”);
else if(strcmp(str1,str2)<0)
printf(“str1 eh menor que str2\n”)
else
printf(“str1 eh maior que str2\n”)
}
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

7. Ponteiros

Ponteiros são variáveis que contém um endereço de memória, normalmente este endereço
é a posição de uma outra variável na memória. Para declarar variáveis ponteiros o programador
deve colocar o ‘*’ (asterisco) antes do nome da variável, conforme a seguir:

tipo_de_valor_apontado *nome;

Onde tipo_de_valor_apontado é qualquer tipo de dados válido em C e define que tipo de


dados a variável possui, ou seja, que o ponteiro irá apontar e o nome é o identificador da variável.

Um ponteiro referencia um endereço de memória e ao mesmo tempo seu conteúdo. As principais


funções de ponteiro consistem em referenciar rapidamente elementos de uma matriz, permite
modificar seus valores entre funções e suportam estruturas dinâmicas de dados. O operador unário
& devolve o endereço de memória de seu operando (unário porque necessita de apenas um
operando).

pt = &auxiliar;

No exemplo acima, o ponteiro pt recebe o endereço de memória da variável auxiliar, onde


este endereço é a posição interna da variável no computador.
O segundo operador unário * devolve o conteúdo da variável localizada no endereço que o
segue. Para o exemplo a seguir considere que a variável esta localizada no endereço 65000 e
possui o valor 7.

pt = &auxiliar; // pt recebe o endereço da variável auxiliar (65000)


num = *pt; // num recebe o valor apontado pelo endereço de pt (7)
*pt = 9; // endereço 65000 recebe o valor 9

7.1. Aritmética de Ponteiros


Ponteiros aceitam dois tipos de operações aritméticas, soma e subtração. Supondo que
declaramos um ponteiro para inteiros e este ponteiro possui o endereço 100, se fizéssemos um
incremento neste ponteiro, ele passaria a apontar para o endereço 104, ou seja, próximo elemento,
visto que cada inteiro utiliza quatro bytes da memória, assim como se aplicássemos um
decrementado a ele, passaria a apontar para a posição 96, ou seja, o elemento anterior. Essas
operações podem ser aplicadas para tipos de dados inteiros e caractere.

7.2. Ponteiros para Vetores


Você pode criar um ponteiro para um vetor ou matriz apenas atribuindo ao ponteiro o nome
da variável sem o índice, assim será criado um ponteiro para o primeiro elemento, pois um nome
de matriz sem um índice é um ponteiro para o primeiro elemento da matriz.

Exemplo1:
int *pt, vet[5];
pt=vet; // pt recebe ponteiro para primeiro elemento do vetor
pt[4]=10; // atribuição usando índice do ponteiro
*(pt+4)=10; // atribuição usando aritmética de ponteiros

Os dois comandos de atribuição colocam o valor 10 no quinto elemento do vetor vet.

7.3. Vetores de Ponteiros


Assim como variáveis, também podem ser declarados vetores de ponteiros. Se em algum
momento for necessário passar o vetor de ponteiros como parâmetro para uma função, faz-se o
mesmo processo que com vetores e matrizes, simplesmente coloca-se o nome sem nenhum
índice.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

int *pt[10]; // declara um vetor de ponteiros para inteiros

Um ponteiro assim que é declarado, não aponta para um local de memória válido, então
por convenção, a maioria dos programadores atribui a ele o valor nulo (zero). Assim, qualquer
ponteiro que tiver o valor nulo, significará que ele não aponta para nada.
É importante salientar que qualquer ponteiro em C, pode ser indexado como um vetor,
usando os colchetes ‘[‘ ‘]’.
7.4. Cuidados com Ponteiros
Entre os erros mais difíceis de serem encontrados em C, está na utilização incorreta dos
ponteiros. Analise o exemplo a seguir:
Exemplo1: // programa incorreto
int main() {
int x=10, *pt;
*pt=x; // endereço apontado por pt recebe 10
}
Aí que está o perigo, estamos colocando um valor em alguma posição da memória, sendo
que não temos nem certeza se está posição é ou não válida, o ponteiro pt não recebeu um valor,
portanto ele possui lixo. Portanto, sempre antes de começar a utilizar um ponteiro procure
inicializá-lo, de forma que garanta que este ponteiro nunca irá sobrescrever o próprio código do
programa, ou a área de dados ou o sistema operacional.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

8. Funções

Uma função é um miniprograma dentro de outro. A utilização de funções é uma


característica de uma programação estruturada, pois de qualquer lugar do código fonte pode ser
feita a chamada de função. Em C, cada função contém um bloco de comandos que é executado
separadamente às outras funções. As variáveis declaradas dentro de uma função não são vistas
por outras funções. Uma função jamais deverá estar contida no bloco de comandos de outra
função, apenas a chamada a ela deve estar ali. Como exemplo, podemos citar a função main(), ela
sempre será a primeira a função a ser executada no código, pois é a função principal. Sua forma
geral é:

tipo_de_dado nome_da_função(lista_de_parametros) {
corpo da função ou bloco de comandos;
}

O campo tipo_de_dado especifica o tipo de dado que será retornado pela função, através
do comando return. Se o tipo de dado for void, significa que a função não retornará nenhum valor.
Se não for especificado nenhum tipo de dado de retorno, o compilador assumirá que será
retornado dado do tipo inteiro. O campo nome_da_funcao seque as mesmas regras para
identificadores de variáveis. A lista_de_parametros conterá declaração de variáveis separadas por
vírgula, essas variáveis serão utilizadas para receber os argumentos passados no momento que é
feito a chamada de função. Uma função que não for receber nenhum parâmetro, não precisará ter
variáveis na lista_de_parametros, mas obrigatoriamente deverá aparecer o abre e fecha
parênteses ‘(‘ ‘)’. No caso de declarar variáveis na lista_de_parametros devemos tomar uma
atenção especial, pois qualquer variável deverá ser precedida pelo seu tipo, conforme o exemplo a
seguir:

void funcao(int a, int b, int c, float aux, char letra) {

8.1. Argumentos de funções

Se for necessário passar argumentos a uma função, ela deverá conter variáveis declaradas
para receber estes argumentos. Essas variáveis possuem as mesmas características de variáveis
locais, e devem ser declaradas logo após o nome da função e entre parênteses, não esquecendo
do tipo de dados que estas variáveis receberão, que deve coincidir com o argumento recebido.
Quando uma matriz é passada como argumento para uma função, apenas o endereço
inicial da matriz é passado, e não todo seu conteúdo.

8.2. Comando return


Utilizado para devolver um valor para o programa (ou função) que o chamou. Também
utilizada para sair imediatamente de uma função, a função que a possui. Uma função será
finalizada quando for encontrado o comando return ou quando for encontrado o fecha chaves da
função ‘}’.
Escola Solon Tavares - Estruturas de Dados Prof. Alan Malta Rodrigues

Bibliografia
SCHILDT, Herbert. C Completo e Total [3ª edição]. São Paulo: Makron Books, 1996.

CELES, Waldemar; RANGEL, José Lucas. Apostila de Estruturas de Dados. PUC-RIO, 2002.

GLUZ, João Carlos. Apostila de Algoritmos de Dados. Guaíba: UERGS, 2003.