Escolar Documentos
Profissional Documentos
Cultura Documentos
1
Introdução
2
Introdução
C - Dennis Ritchie (Laboratórios Bell)
Inicialmente para máquinas do tipo PDP-1
(com UNIX).
Depois para os IBM PC e compatíveis
(ambientes MS DOS, e MS Windows)
3
O Standard ANSI-C
Versão C que segue a norma da American
National Standard Institute (ANSI), e da
International Standards Organization (ISO).
4
Características
A linguagem C é muito famosa e muito
utilizada:
– pela concisão de suas instruções;
– pela facilidade de desenvolvimento
de Compiladores C;
– pela rapidez de execução de programas;
– e principalmente pelo fato que o poderoso
sistema operacional Unix foi escrito em C.
5
Um Programa Simples
#include <stdio.h>
/*
um programa bem simples
que imprima: Ate logo.
*/
void main ()
{
printf("Ate logo. ");
}
6
Exemplo 1
#include <stdio.h> /* 1 */
#define B 20 /* 2 */
int a,s; /* 3 */
void main () /* 5 */
{
scanf("%d",&a); /* 6 */
s=somar(a,B); /* 7 */
printf("%d",s); /* 8 */
}
7
Comentários – Ex1
/* 1 */ inclusão de um arquivo da biblioteca de C que
implementa as funções printf, scanf...
8
Estrutura de um Programa C
9
main
void main ()
{
declarações
instruções 1
instruções 2
...
instruções n
}
10
As outras funções
Tipo nome (declaração-de-parâmetros)
{
declarações;
instruções 1;
instruções 2;
...
instruções n;
}
11
Considerações sobre as funções
12
Compilação
Pre-Processadores:
13
Tipos Básicos
14
Principais tipos de Dados
16
Inteiros
Atributos de representação
– unsigned : somente os positivos
– signed : positivos e negativos
17
Combinação de Atributos - Inteiros
– int;
– short int; todos signed
– long int;
e
– unsigned int;
– unsigned short int;
19
– unsigned long int;
Pseudo-Reais
O tipo é: Char
char c,b;
c = ’\65’;
b = ’c’;
22
E o tipo String?
Um substituo:
os vetores de caracteres:
char nome[20]
23
E o tipo Boolean?
Atenção:
tipo int:
0 : false
1 : true
24
Em sistemas 32 bits
char 1 -128 a 127
signed char 1 -128 a 127
unsigned char 1 0 a 255
short 2 -32,768 a 32,767
unsigned short 2 0 a 65,535
int 4 -2,147,483,648 a 2,147,483,647
unsigned int 4 0 a 4,294,967,295
long 4 -2,147,483,648 a 2,147,483,647
unsigned long 4 0 a 4,294,967,295
float 4 3.4E+/-38 (7 dígitos)
double 8 1.7E+/-308 (15 dígitos)
long double 10 1.2E+/-4932 (19 dígitos)
25
DECLARAÇÃO DE
VARIÁVEIS
26
Identificadores
27
Identificadores
30
linguagem.
Palavras Chaves
(são 32 palavras)
tipo lista-de-nomes-de-variáveis
Exemplo:
int i,a;
double d1, d2;
char c;
32
Inicialização de Variáveis
33
Operações
34
Atribuição
Exemplo :
i=4;
a=5*2;
d=-b/a;
raiz=sqrt(d);
35
Exemplos de Atribuição
i = (j = k) - 2; (caso k=5)
5 j=5
3 i=3
Atribuição múltipla:
a=b=c=8;
36
Conversão de Tipos (1)
O compilador faz uma conversão
automática
float r1,r2=3.5; int i1,i2=5;
char c1,c2=’A’;
r1=i2; /* r1 ← 5.0 */
i1=r2; /* i1 ← 3 */
i1=c2; /* i1 ← 65 */
c1=i2; /* c1 ← 5 */
r1=c2; /* r1 ← 65.0 */
c1=r2; /* c1 ← 3 */
37
Conversão de Tipos (2)
int a = 2;
float x = 17.1, y = 8.95, z;
char c;
c = (char)a + (char)x;
c = (char)(a + (int)x);
c = (char)(a + x);
c = a + x;
z = (float)((int)x * (int)y);
z = (float)((int)(x * y));
z = x * y;
38
Adição/subtração/multiplicação
Expressão1 + expressão2
Expressão1 - expressão2
Expressão1 * expressão2
Expressão1 / expressão2
Exemplos:
a >= b
(a = = 0) || (b != 0)
! ((a = = 0) && (b<3))
44
Operador & Inflação
É o operador de endereçamento
(ponteiro):
&a é o endereço da variável a
45
Incremento/decremento
x = x + 1; /* isto incrementa x */
s+=i; /* s=s+i*/
v = v operador expressão
≅
v operador= expressão
47
Condicional
48
Entradas e Saídas
49
Saídas
Printf("Bom dia");
puts("Bom dia"); /* para imprimir um string */
putch(a) /* para imprimir um char */
50
Entradas
gets(s); /* leitura de um string */
char c;
c = getch();
c = getchar(); /* com echo */
scanf ("%d",&nome);
/* para a leitura da var. nome */
51
Constantes utilizados no printf
\n nova linha
\t tabulação (horizontal)
\v tabulação vertical
\b um espaço para trás
\r um return
\a um bip
\\ backslash
\% o caracter %
\{’’} um apostrofo
\? um ponto de interrogação
52
Conversão de Tipos
d notação de decimal
o notação octal
x notação hexadecimal
e notação matemática
u notação sem sinal
c notação de caracter
s notação de string
f notação de flutuante
53
Formatação
54
Formatação
- justificar a esquerda
+ o sinal sempre aparente
n o comprimento mínimo da saída (senão
brancos)
0n o comprimento mínimo da saída (senão 0s
esquerda)
n.m para separar as partes antes e depois da
virgula total de n dígitos, cujo m são depois
da virgula.
l para indicar um long
55
Exemplo
#include <stdio.h>
int main()
{
int a; long int b; short int c;
unsigned int d; char e; float f;
double g;
a = 1023; b = 2222; c = 123;
d = 1234; e = ’X’;
f = 3.14159;
g = 3.1415926535898;
...
}
56
Exemplo
{ printf("a = %d\n", a); a = 1023
printf("a = %o\n", a); a = 1777
printf("a = %x\n", a); a = 3ff
printf("b = %ld\n",b); b = 2222
printf("c = %d\n", c); c = 123
printf("d = %u\n", d); d = 1234
printf("e = %c\n", e); e = X
printf("f = %f\n", f); f = 3.141590
printf("g = %f\n", g); g = 3.141593
}
57
Exemplo
{
printf("\n");
printf("a = %d\n", a);
printf("a = %7d\n", a);
printf("a = %-7d\n", a);
c = 5;
d = 8;
printf("a = %*d\n", c, a);
printf("a = %*d\n", d, a);
}
58
Exemplo
{
printf("\n");
printf("f = %f\n", f);
printf("f = %12f\n", f);
printf("f = %12.3f\n", f);
printf("f = %12.5f\n", f);
printf("f = %-12.5f\n", f);
}
59
Exemplo
As saídas são:
f = 3.141590
f = 3.141590
f = 3.142
f = 3.14159
f = 3.14159
60
Diretivas de Compilação
61
Diretivas de compilação
Em Unix: /usr/lib/include
Em DOS: APPEND (~ PATH, mas para os
arquivos de dados e não
para os executáveis)
Em Windows: isto é especificado no
ambiente
63
Inclusão de Fontes: #include
#include “nome-de-arquivo”
... f2.c
#include "f2.c" for (i=0;i<5;i++)
... printf("Oi");
f1.c
f1.c
...
for (i=0;i<5;i++)
printf("Oi");
...
65
Arquivos headers (.h)
Arquivos headers standards:
stdlib, stdio.h, conio.h, etc.
Um arquivo header contém um conjunto
de declarações de variáveis e funções.
Observação:
{
BOOLEAN a=FALSE;
if (a = = TRUE) ...; else ...;
}
(uma convenção: usar os maísculos)
67
Macro Substituições: #define
quadrado(3-2); (3-2)*(3-2) = 1
5*adicionar(2+1,4); 5*((2+1)+(4)) = 35
regra geral: colocar todas as variáveis entre
parênteses e o resultado também
69
Substituições parciais
#define MAX 60
... /*aqui MAX=60*/
#undef MAX
#define MAX 45
... /*aqui MAX=45*/
70
Compilação condicional (1)
Objetivo: a otimização
#if (condição)
corpo 1
[#else
corpo 2]
#endif
71
Compilação condicional (2)
#ifdef identificador
corpo 1
#endif
#ifndef identificador
corpo 1
#endif
72
O const
Para declarar variáveis constantes podemos
usar a palavra chave const
const int N 20
Isto proibe que N seja modificado no programa
(toda tentativa de modificação vai dar erro)
73
Estruturas de Controle
74
Blocos de instruções
{
declarações
instrução_1
..... /*um bloco de instruções
é delimitado por duas chaves*/
instrução_2
}
Exemplos:
if (a>=b) if (a!=0)
max=a; x=-b/a;
else
max=b;
76
Instrução if...else (2)
77
Instrução if...else (3)
If (condição_1)
instrução_1;
else if (condição_2)
instrução_2;
else if (condição_3)
instrução_3;
else
instrução_4;
78
Instrução if...else (4)
if (a>b)
{
if (c<d) b=2*a;
}
else a=2*b;
79
Instrução if...else (5)
If (condição_1)
{
instrução_1;
if (condição_2)
instrução_2;
}
else if (condição_3)
instrução_3;
80
Observação
int b=0;
if (b) /* equiv. a: if(b!=0)*/
{
...
81
}
Instrução switch (1)
escolha múltipla
switch (expressão)
{
case constante_1:
instruções
break;
case constante_2:
instruções
break;
...
default:
instruções
82
}
Instrução switch (2)
Quando as mesmas instruções devem ser
executadas no caso de um conjunto de
valores:
switch (expressão)
{
case val_1:
...
case val_n:
instruções
break;
case val_3:
instruções
break;
default:
instruções
}
83
Instruções de Repetição
84
while
while (condição)
instrução
Exemplo:
fim do while
não
c=’s’; condição!=0 ?
while (c!=’f’)
{
c=getch(); sim
}
instruções
85
do...while (1)
do
instrução(ões)
while (condição)
86
do...while (2)
do
c=getch();
while (c==’s’)
instrução
fim do do
sim
não
condição!=0 ?
87
for (1)
for (expressão1, condição, expressão2)
instrução(ões)
expressão1 inicialização
fim do for
não
condição!=0 ?
sim
instruções
expressão2
89
for (3)
A novidade é que as expressões podem ser
instruções múltiplas (separadas por virgula)
Exemplo:
90
break
O break permite parar a instrução
de repetição (for, do ou while)
Se temos vários níveis, o controle volta
à penúltima estrutura de repetição.
for (i=0;i<20;i++)
if (vet[i]==10) break;
91
continue
Utilizada dentro de uma instrução for, while ou
do
O continue permite parar a iteração atual e
passar à iteração seguinte.
Exemplo:
for (i=1;i<20;i++)
{
if (vet[i]<0) continue;
...
}
92
Instrução: goto
goto <identificador> ;
permite quebrar a seqüência do programa
Exemplo:
mais:
...
94
Definição de uma função
95
Ex. de funções: (stdio.h)
Principalmente:
puts
gets
printf
scanf
96
Ex. de funções: (math.h)
97
Ex. de funções: (conio.h)
99
Ex. de funções: dos.h
delay
sound
nosound parar o som
sleep suspende em seg void sleep(unsigned s)
exemplo:
{ sound(300); /* emitir um som de 300 Hz*/
delay(2000); /* esperar 2 segundos */
nosound(); /* antes de parar */
}
100
Exemplos de funções
graphics.h
string.h
101
Definição de uma função
[lista de declarações 1]
{
[lista de declarações 2]
lista de instruções
}
102
Semântica
tipo: é o tipo do valor devolvido pela função
103
Exemplo
return (3.14159);
105
Observação
{
int m_1, m_2; float p, d=4.5;
m_1 = max (4,3); m_2 = max(6*2-3,10);
p = d * pi();
}
107
Procedimentos
Funções que não retornam valores: usando o
tipo especial void
void linha ()
{
printf("-------------------------\n");
}
Observação: não temos aqui a instrução return
(o tipo especial void não existia nas
primeiras versões da linguagem)
108
Omissão do tipo da função!
109
Passagem dos Parâmetros
void main ()
{
int a=8, b=5, s;
s = somar(a,b); /*os parâmetros efetivos*/
}
110
Passagem por Valor
111
Passagem por Referência
(ou por endereço)
Usar o operador de endereçamento &
void somar (int x, int y, int * som)
{
*som = x+y;
}
void main ()
{
int a=5, b=6, s;
somar(a,b, &s);
printf("%d + %d = %d",a,b,s);
}
112
Outro uso do void
void f (void)
{
...
}
113
Declaração de Funções
114
Exemplo
116
Funções Iterativas
exemplo do fatorial
for (i=1;i<=n;i++)
res=res*i;
return (res);
}
117
Funções Recursivas
exemplo do fatorial
120
Escopo das declarações
são 4 escopos:
– Um identificador declarado fora das funções, tem
um escopo em todo o programa.
– Um parâmetro formal de uma função, tem
um escopo local à função.
– Um identificador declarado em um bloco
tem um escopo local ao bloco.
– Uma etiqueta de instrução, tem escopo em
toda a função onde ela é declarada.
121
Visibilidade dos identificadores
int i=1;
int j=1;
void p()
{
int i=2; /* este i cobre o precedente */
int k;
if (a==b)
{
int i=3; /*cobre o i precedente*/
int j=2; /* cobre o j precedente*/
int k; /*cobre o k precedente*/
}
}
122
Duração vida de uma variável
Variáveis Estáticas:
Alocação no início do programa e liberação
no final da execução do programa.
Variáveis Automáticas
Alocação na entrada de uma instrução
composta (um bloco) e liberação na saída.
Variáveis Dinâmicas
A declaração e liberação são explicitamente
realizadas pelo programador (usando malloc
e free). Mas, essas funções são da biblioteca
e não fazem parte integrante da linguagem.
123
Duração vida de uma variável
124
Duração vida de uma variável
125
Indicadores de classes de memória
auto
static
register
extern
126
auto
{auto int i; ... }
Este tipo de indicador é autorizado somente para
as variáveis locais a uma instrução composta
(um bloco).
Ele indica que a variável tem uma duração
de vida local ao bloco.
127
static
132
Classes de memória (2)
133
o extern não é realmente)
Tabelas
134
Tabelas
135
Declaração
float vet[10];
long int v1[8], v2[15];
/* v1 é um vetor de 8 long int
e v2 é um vetor de 15 long int */
136
Dimensão
137
Acesso aos elementos
Sintaxe:
nome-variável [expressão]
expressão deve retornar um inteiro (o indexador)
Exemplos:
vet[0]=6;
vet[4+1]=-2;
x=3*vet[2*a-b];
138
Inicialização
#define N 4
int v[N]={1,2,3,4};
Incialização de somente uma parte do vetor:
#define N 10
int v[N]={1,2}; //o resto será zerado
Inicialização pelo mesmo valor:
for (i=0;i<=9;i++) v[i]=2;
139
Operadores abrangentes
lembramos que:
x++ incrementa x mas retorna o valor inicial
++x incrementa x e retorna o valor incrementado
i=0;
v[i++]=0; /* v[0]=0 e i=i+1 */
v[i++]=0; /* v[1]=0 e i=i+1 */
i=1;
v[++i]=0; /* i=i+1 e v[2]=0 */
v[++i]=0; /* i=i+1 e v[3]=0 */
idem para o operador --
140
Uso da instrução nula
Inicialização de um vetor:
for (i=0;i<10;v[i++]=1);
Isto é equivalente a:
for (i=0;i<10;i++) v[i]=1;
Pesquisar em um vetor:
Matrizes
Declaração:
int mat [3][4]; /* matriz bidimensional de
3 linhas 4 colunas */
Inicialiazação:
int mat [3][4] =
{
{5,6,8,1},
{4,3,0,9},
{12,7,4,8},
142 }
Exemplo
/* Declaração: */
#define L 4;
#define C 3;
int mat[L][C];
/* leitura: */
for (i=0;i<=L;i++)
for (j=0;j<=C;j++)
{
printf("digite o elemento [%d,%d]: ",i,j);
scanf("%d",&mat[i][j]);
}
143
Observação 1
145
Exercícios
A.1 Escreva o procedimento ini_num_dias que
inicializa um vetor num_dias[12] que indica para cada
mês do ano seu número de dias: (num_dias[i] indica o
número de dias do mês i do ano), sabendo que:
Se i=2 então num_dias=28;
Se (i par e i<=7) ou (se i impar e i>7) então
num_dias=30 Senão num_dias=31.
A.2 Escreva o procedimento imp_num_dias que
imprima os números de dias de todos os meses do ano.
B. Escreva a função ordenar que ordena um vetor.
C. Escreva a função palindromo que determina se um
vetor é um palindromo.
146
Tipos Enumerados
147
enum
A enumeração permite de agrupar um conjunto
de constantes (compartilhando a mesma
semântica)
exemplos:
enum dias {Domingo, Segunda, Terça,
Quarta, Quinta, Sexta, Sábado};
declaração:
dias d1,d2=Quinta;
enum defini um novo tipo cujo os elementos
são numerados automaticamente de pelo
compilador: 0 1 2 ...
148
Exemplo
#include <stdio.h>
enum dias {Segunda,Terça,Quarta,Quinta,
Sexta,Sábado,Domingo} d;
// d é uma variável declarada de tipo dias
150
Ponteiros
151
Variáveis Dinâmicas
152
Variáveis Dinâmicas
float * pf
/* declara que pf é um ponteiro sobre um real */
pf
4.6
153
Os Operadores & e * (1)
O operador de indireção *
se aplica sobre um ponteiro e permite
retornar (manipular) o objeto
apontado.
154
Os Operadores & e * (2)
*P
P V
(Ponteiro) (Variável)
&v
155
Exemplo
int i,j;
int *pi;
/* pi é um ponteiro sobre um inteiro */
pi &i
&j
i=5;
pi=&i; 56 i
*pi=6;
j=*pi-2; 4 j
pi=&j;
156
Exercício
158
Passagem de Parâmetros
Passagem de parâmetros (dois tipos):
– por valor
– por referência (passar o endereço da variável)
160
Exemplo
}
161
Um outro exemplo
A função troca
void troca (int * x, int * y)
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
chamada da função
troca(&a,&b); /* passagem por referência */
162
Funções Genéricas
O problema é que esta função troca que nós definimos
se aplica somente sobre os inteiros
163
Tabelas e Ponteiros
164
Relação entre Tabela e Ponteiros
Manipulação de sub-tabelas:
int t[10]; p
int * p; t
p=&t[2];
0 1 2 3 9
167
Conseqüência 3
i[t] *(i+t)
Mas,por razões de legibilidade do
programa esta possibilidade é muito
pouco utilizada.
168
Aritmética dos Ponteiros
169
Ilustração do Cálculo de Ponteiros
#define N 10
int t[N];
int *p, *q, *r, *s;
170
Passagem de Parâmetros
Em C uma tabela pode ser passada como
parâmetro a uma função
for (i=0;i<num_elem;i++)
printf("%d",*(t+i));
}
173
2a Abordagem
Por esta razão, C permite uma declaração mais
“natural” dos parâmetros formais:
void imp_tabela (int t[],int n)
{
int i;
for (i=0;i<n;i++)
printf("%d",t[i]);
}
Atenção: Não é preciso conhecer o tamanho exato da
tabela. o tamanho é geralmente passado como
parâmetro separado.
chamada: imp_tabela(tab,L);
174
Tabelas Multi Dimensionais
175
Algumas considerações
A função min é aplicada a uma tabela que tem qualquer
número de linhas, mas deve ter um exato C de colunas.
As outras dimensões (≠ 1a), devem ser especificadas por
que o compilador precisa para gerar o código que permite o
acesso aos elementos:
No caso de uma matriz binária t por exemplo, o endereço de
t[i][j] é: t+(i*C+j)*T (T é o tamanho de um elemento de
t, C é o número de colunas)
Representação da tabela na memória:
11 12 13 14 21 22 23 24 31 32 33 34 41...
176
Modificação dos elementos
void f (int t[],int nb_elem)
{
int i;
for (i=0;i<nb_elem;i++)
t[i]++;
}
a chamada: f(tab,L);
/* já que a passagem de parâmetros é feita por referência
então qualquer modificações sobre o vetor é física */
acesso:
i
*tab[i] tab
Objeto
178
*tab[i] apontado
Ponteiro de Ponteiro
179
Ortogonalidade do operador *
Já que um ponteiro é uma variável como as
outras, é muito normal que um ponteiro aponte
sobre um ponteiro
Um exemplo é um ponteiro sobre um ponteiro
sobre mais um inteiro
declaração:
int **ppint
int
ppint
180
Argumentos do main
Um programa C pode ser chamado
externamente com alguns parâmetros:
182
exemplo
Suponha: programa achar_max pega como parâmetros
um conjunto qualquer de strings e que deve determinar e
imprimir a maior string:
argv
achar_max\0
\0
\0
\0
argv[0] é o nome do programa: achar_max,e os outros
argv[i] são os argumentos passados ao programa na
linha de comandos.
183
#include <stdio.h>
#include <string.h>
void main (int argc, char * argv[])
{
int com_max=0, arg_max=0; argc--;
while (argc>=1)
{
if (strlen(argv[argc])>com_max)
{
com_max=strlen(argv[argc]);
arg_max=argc;
}
argc--;
}
if (arg_max) printf("O string maior é: %s", argv[arg_max]);
}
184
Strings
185
String ~ Vetor
Um string é um conjunto de caracteres.
Em C, um string é uma estrutura
equivalente à estrutura de vetor,
A única diferença é que o string termina
sempre pelo caractere ’\0’
Isto para facilitar o tratamento dos strings
(para poder detectar o fim do string)
186
Declaração
Declaração:
#define N 20
char ch [N];
188
Inicialização de Vetor de Caracteres
190
Como Ponteiro sobre Caracteres
char * ch = "exemplo";
Contrariamente à outra maneira, a reserva do
espaço memória não é feita no momento da
declaração, mas dinamicamente no momento da
atribuição.
191
Inicialização e Atribuição
ch
ch = "uma mudança"; uma mudança\0
ch = "outra mudança";
outra mudança\0
Isto não é uma copia mas uma atribuição de ponteiros.
192
Manipulação de Strings
194
strlen
195
strcat/strncat
strcat se aplica sobre dois strings e retorna
um ponteiro sobre a concatenação dos dois.
exemplo:
char *ch1="boa", *ch2="noite",
*ch3, *ch4;
ch3=strcat(ch1,ch2);
ch4=strncat(ch1,ch2,3);
printf("%s %s",ch3,ch4);
/* vai imprimir boanoite boanoi*/
196
strcmp/strncmp
Lembramos que as letras são ordenadas dando
seu código: ’a’< ... ’z’< ’A’...<’Z’
strcmp compara dois strings s1 e s2 e
retorna um valor: negativo se s1 < s2
0 se s1 == s2
positivo se s1 > s2
exemplo:
char *ch1="boa tarde",
*ch2="boa noite";
int a,b;
a=strcmp(ch1,ch2);
b=strncmp(ch1,ch2,4);
/* a vai receber um valor >0 e b 0*/
197
strchr/strrchr
strchr procura por um caractere em um string e
retorna um ponteiro sobre sua última ocorrência, senão
retorna null.
exemplo:
char ch[]="informática";
char *pc, c='f';
pc=strchr(ch,c);
if (pc) /* i.e. if pc!=null */
printf("%d",*pc);
else
printf("Caractere inexistente");
O strrchr faz a busca no senso inverso.
198
touppar/tolower
toupper converte um caractere minúsculo
em maiúsculo.
tolower faz o contrário.
# include <ctype.h>
char c='a';
c=toupper(c); /* c= 'A' */
c=toupper(c); /* c já esta ='A' */
c=tolower(c); /* c volta a ser 'a' */
199
Exercícios 1
200
int tamanho1 (char s[]) /* com um vetor */
{
int i=0;
while (s[i]) /* equiv. while (s[i]!= '\0' ) */
i++;
return (i);
}
202
Exercícios 2: Criptografia Simples
203
Tipos usuários
204
typedef
Podemos definir novos tipos usando o
typedef:
typedef <tipo> <sinônimo>
exemplo:
typedef float largura;
typedef float comprimento;
largura l;
comprimento c=2.5;
l=c; //* ⇒ warning *//
205
typedef e struct
206
Estruturas
207
Declaração: método 1
struct cliente {
int cpf;
char nome [20];
char endereco[60];
};
208
Declaração: método 2
Podemos criar estruturas sem nome:
struct {
int cpf;
char nome [20];
char endereco[60];
} c1,c2;
Problema:
para criar uma outra variável de mesmo
tipo em outro lugar do programa é preciso
rescrever tudo.
209
Declaração: método 3
Cliente c1,c2={28400,"Maria","Rua
Liberdade, N. 140"};
211
Acesso aos Campos
nome-estrutura.nome-do-campo
exemplo:
chamada da função:
imprimir_cliente (c2);
213
Combinação de Estruturas
217
Estruturas dinâmicas
218
Ponteiros sobre uma Estrutura
typedef struct {
char * nome;
int idade;
} Pessoa ;
Pessoa pess;
/* pess é uma variável de tipo pessoa */
Pessoa *pp;
/* p é um ponteiro sobre uma pessoa */
pp=&pess;
/* p agora aponta sobre a pessoa pess */
219
Ponteiros sobre uma Estrutura
pess.idade=18;
pess.nome="joao";
Para acessar aos campos da estrutura apontada
por pp usamos o operador ->
pp->nome; /* equiv. a pess.nome */
pp->idade=25; /* ⇔ pess.idade=18 */
printf("%s",pp->nome);
// escreveria João
printf("%d",pp->idade);
// escreveria 25
220
Observação sobre o acesso
Para acessar o campo nome de pessoa
apontada por um ponteiro pp:
*pp.nome
Mas o operador de seleção . é mais prioritário do
que o operador de indireção * ⇒ isto é equiv. a:
*(pp.nome)
o que está errado (pois pp não é uma estrutura).
Deveremos escrever:
(*pp).nome
Mas esta notação é um pouco complicada.
Por isso temos um novo operador -> (pp->nome)
221
Estrutura apontando sobre uma
outra Estrutura (1)
exemplo:
struct pessoa {
...
struct pessoa * next;
} ;
222
Estrutura apontando sobre uma
outra Estrutura (1)
exemplo:
typedef struct pessoa * PtrPessoa;
// PtrPessoa é um ponteiro sobre a estrutura pessoa
typedef struct pessoa {
char nome[30];
int idade;
PtrPessoa next;
} Pessoa;
/* next é um ponteiro sobre uma outra pessoa */
PtrPessoa pp;
223
Ilustração
CPF
nome
endereco
next
CPF
nome
endereco
next
224
Acessos aos elementos de uma
Estrutura Apontada
PtrPessoa p;
...
printf("Entra com o nome: ");
scanf("%s",&p->nome);
p->next=NULL;
225
Tamanho alocado à uma Estrutura
228
malloc
malloc pega um único parâmetro que
é o tamanho (em bytes) do espaço memória
do elemento que nós desejamos criar, e
retorna um ponteiro sobre o elemento criado.
Obs. O tamanho do elemento é obtido usando
o operador sizeof.
exemplo:
Pessoa * p;
p=malloc(sizeof(Pessoa));
p=malloc(sizeof(char));
229
calloc
calloc pega dois parâmetros:
- o número de elementos que
desejamos criar;
- e o tamanho de um elemento (em
bytes).
O objetivo é de alocar espaços para
vários
elementos de só uma vez.
230
calloc
exemplo:
Pessoa * p;
int num_elementos=4;
...
p=calloc(num_elemenetos,
sizeof(Pessoa));
Podemos, depois, usar p[0],
p[1], ...
P[num_elementos - 1]
231
Observação
232
null
233
Liberação de Memória
234
As Estruturas como Parâmetros
235
Exemplo
data * d2001 ()
{ data * p; p=malloc(sizeof(data));
p->dia=1; p->mes=1; p->ano=2000;
return (p);
}
data * d; d=d2001();
237
Observação
Pessoa * p;
p=malloc(...)
Normalmente o malloc não retorna um
ponteiro sobre uma estrutura. Isto pode
causar um warning.
Uma maneira correta de escrever é:
p=(Pessoa*)malloc(sizeof(Pessoa))
Uma outra solução é:
Pessoa * malloc();
238
Exercício
239
data * proximo_anniv (data * p)
{
data * anniv;
anniv=(data*)malloc(sizeof(data));
anniv->ano=p->ano + 1;
anniv->mes=p->mes;
anniv->dia=p->dia;
return (anniv);
}
data d_nasci,d_anniv; ...
d_anniv=proximo_anniv(&d_nasci);
240
Criação de Listas
typedef struct {
char nome[20];
int peso;
Cabeça Pessoa * seguinte;
} Pessoa;
241
Pessoa * cabeca,pant,patu; char resp;
patu=(Pessoa *)malloc(sizeof(Pessoa));
patu->peso=30; ...
cabeca=patu;
puts("mais uma pessoa (s/n): "); resp=getch();
while (toupper(resp)!=’N’)
{
pant=patu;
patu=(Pessoa *)malloc(sizeof(Pessoa));
... /* leitura dos dados da nova pessoa */
pant->seguinte=patu; patu->seguinte=NULL:
puts("mais uma pessoa (s/n): ");resp=getch();
}
242
Modos FIFo Vs. LIFO
Exercício:
243
Listas
Conjunto de elementos individualizados
em que cada um referencia um outro
elemento distinto como sucessor
244
Listas
Lista de Tarefas
Começo em 3
Item Próximo
1. Pagar as contas no banco 6
2. Comprar os livros na livraria 4
3. Deixar o carro no estacionamento 8
4. Pegar algumas fitas na videolocadora Final
5. Enviar carta pelo correio 1
6. Buscar as fotos reveladas 2
7. Autenticar documentos no cartório 5
8. Passa na banca de jornais 7
245
Inserção no meio da Lista
Antes
Farmácia (9)
246
Inserção no meio da Lista
1º passo
Farmácia (9)
247
Inserção no meio da Lista
2º passo
Farmácia (9)
248
Inserção no meio da Lista
Antes
Farmácia (9)
Locadora (4) 0
250
Inserção no fim da Lista
1º passo
Farmácia (9)
Foto (6) 0
251
Inserção no fim da Lista
2º passo
Farmácia (9)
Foto (6) 0
252
Inserção no fim da Lista
Antes
Farmácia (9)
254
Inserção no início da Lista
1º passo
Farmácia (9)
255
Inserção no início da Lista
2º passo
Farmácia (9)
256
Inserção no fim da Lista
258
Remoção em uma Lista
Antes
Farmácia (9)
259
Remoção em uma Lista
1º passo
Farmácia (9)
260
Remoção em uma lista
void remove(int velho, int antecess)
{
antecess = lista[velho].prox;
}
261
Filas (FIFO)
É também uma Lista
Regra: todo o elemento que entra na
lista, entra no final e todo o elemento
que sai da lista, sai do início dela.
FIFO (First In, First Out)
262
Filas (FIFO)
#define MAX 100
char *p[MAX]; int rpos=0, spos=0;
void armazena(char *c) {
if (spos==MAX) {
printf(“Lista Cheia\n”);
else
p[spos] = c;
spos++;
}
}
263
Filas (FIFO)
char *retira()
{
if (rpos==spos)
printf(“Sem eventos\n”);
return NULL;
else
rpos++;
return(p[rpos-1]);
}
264
PILHA (LIFO)
É o inverso de uma fila
Regra: todo o elemento que entra na
lista, entra no final e todo o elemento
que sai da lista, sai do final dela.
Último a entrar, primeiro a sair
LIFO (Last In, First Out)
push/pop (empilha/desempilha)
265
PILHA (LIFO) - vetor
int p[100], top=0;
void push(int i)
{
if (top>=100)
printf("pilha cheia\n");
else {
p[top] = i;
top++;
}
266
}
PILHA (LIFO) - vetor
int pop();
{
top--;
if (top<0) {
printf("pilha vazia");
return 0; }
else
return(p[top]);
}
267
PILHA (LIFO) - ponteiro
int *p, *top, *b;
p = (int*)malloc(MAX*sizeof(int));
top = p;
b = p+MAX-1;
268
PILHA (LIFO) - ponteiro
void push(int i)
{
if (p>b)
printf("pilha cheia\n");
else {
*p = i;
p++;
}
}
269
PILHA (LIFO) - ponteiro
int pop();
{
p--;
if (p<top) {
printf("pilha vazia");
return 0; }
else
return(*p);
}
270
Árvores Binárias
Rapidezna pesquisa, inclusão e
exclusão (qdo ordenadas)
info
info info
0 0 0 0
271
Árvores - conceitos
Raiz
Nós
Nó terminal
Sub-árvore
Altura
272
Transversalização
d
b f
a c e g
Ordenada abcdefg
Preordenada dbacfeg
Pós-ordenada acbegfd
273
Uniões de Tipos
274
Objetivo
Todas variáveis que nos vimos até agora
possuam um único tipo.
As vezes é interessante atribuir vários tipos
a uma variável (uma mesma zona memória).
Isto pode ser feito através do mecanismo
de uniões de tipos usando a palavra chave
union.
Portanto, uma variável teria, a um dado
instante, um único tipo, porém pode mudar.
275
Declaração
Exemplo:
/* declaração de um tipo que una os inteiros e os reais */
typedef union {
int i;
float f;
} número;
numero n;
Podemos então escrever:
n.i=20; /* para atribuir um inteiro */
n.f=3.14159; /* para atribuir um real */
276
Observação
#define INTEIRO 0
#define REAL 1
typedef struct
{
int tipo_var;
union
{
int i;
float f;
} número;
} aritmética;
278
Utilização Prática das Uniões
/* declaração */
aritmética a1,a2;
a1.tipo_var=INTEIRO;
a1.tipo_var=REAL
a1.número.i=10;
a1.número.i=10;
279
Facilitar o acesso aos campos
280
Arquivos
281
Streams
Stream de texto
– Sequência de caracteres
Stream binária
– Sequência de bytes com uma
correspondência de 1 para 1 com aqueles
encontrados no dispositivo externo
282
Funções mais comuns
Nome Função
#include <stdio.h>
283
Funções mais comuns
Nome Função
fseek() Posiciona o arquivo em um bytes
específico
fprintf() = printf – console
fscanf() = scanf – console
feof() Final de arquivo?
ferror() Ocorreu um erro?
rewind() Indicador de posição no início do arquivo
286
Abrindo um arquivo
r r+
w
w+
a
a+
rb
r+b
wb
w+b
ab
a+b
287
Abrindo um arquivo
file *fp;
if ((fp=fopen(“test”,”w”))==null)
{
printf(“não pode ser aberto”);
exit(1);
}
288
Fechando um arquivo
Função fclose()
Exite uma quantidade máxima de
arquivos que podem ser abertos
FOPEN_MAX (exemplo: 20)
289
Lendo / Escrevendo
void carrega_arquivo(char s[10000],
char nome_arquivo[1000]) {
FILE *fp; int i=0;
if ((fp =
fopen(nome_arquivo,"r"))==NULL) {
printf("erro\n");
exit(1); }
for (i=0; i<9999 && s[i]!=EOF;i++)
s[i] = getc(fp);
fclose(fp); }
290