Professional Documents
Culture Documents
Introduo
Introduo
(com UNIX).
O Standard ANSI-C
Verso C que segue a norma da American National Standard Institute (ANSI), e da International Standards Organization (ISO).
Os Compiladores da Borland foram os primeiros a oferecer compatibilidade com esta norma (os compiladores de Turbo C a partir da verso 2.0).
Caractersticas
pela conciso de suas instrues; pela facilidade de desenvolvimento de Compiladores C; pela rapidez de execuo de programas;
e principalmente pelo fato que o poderoso sistema operacional Unix foi escrito em C.
Um Programa Simples
#include <stdio.h>
/* um programa bem simples que imprima: Ate logo.
*/
void { }
6
main ()
Exemplo 1
#include <stdio.h> #define B 20 int a,s; int somar (int x, int y) { return (x+y); } void main () { scanf("%d",&a); s=somar(a,B); printf("%d",s); }
7
/* 1 */ /* 2 */ /* 3 */ /* 4 */
/* 5 */ /* 6 */ /* 7 */ /* 8 */
Comentrios Ex1
/* 1 */
/* 2 */
incluso de um arquivo da biblioteca de C que implementa as funes printf, scanf... b deve ser substitudo por 20 declarao de duas variveis inteiras: a e s definio de uma funo somar definio da funo principal: main
/* 3 */
/* 4 */ /* 5 */
/* 6 */
/* 7 */ /* 8 */
8
Estrutura de um Programa C
Um
A
conjunto de funes
obrigatria.
main
void main () { declaraes
instrues 1 instrues 2 ... instrues n }
10
As outras funes
Tipo nome (declarao-de-parmetros)
12
Compilao
Pre-Processadores:
Transformao lexical do texto do programa.
Compiladores:
Traduo do texto gerado pelo pre-processador e sua transformao em instrues da mquina.
Observao
Geralmente, o pre-processador considerado como fazendo parte integrante do compilador.
13
Tipos Bsicos
14
famlia dos nmeros inteiros famlia dos nmeros pontoflutuantes (pseudo-reais) famlia dos caracteres
Inteiros
Atributos de preciso:
: : :
16
Inteiros
Atributos de representao
unsigned signed
: :
17
unsigned short int : rep. sobre 8 bits [0, 255] signed short int : rep. sobre 7 bits
[-128, 127]
unsigned int
: rep. sobre 16 bits [0, 65535] signed int : rep. sobre 15 bits [-32768, 32767] unsigned long int : rep. sobre 32 bits [0, 4294967295] signed long int : rep. sobre 31 bits [-2147483648, 2147483647]
Os Inteiros
todos signed
e
19
Pseudo-Reais
(representao da forma: M * 10EXP)
[-3.4*10-38, 3.4*1038 ] double : representao sobre 15 algarismos [-1.7*10-308, 1.7*10308 ] long double : representao sobre 19 algarismos [-3.4*10-4932, 3.4*104932 ]
20
Caracteres
Ele pode ser manipulado como um inteiro. Um caracter codificado sobre um byte podemos representar at 256 caracteres.
21
Caracteres
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?
24
Em sistemas 32 bits
25
char signed char unsigned char short unsigned short int unsigned int long unsigned long float double long double
1 1 1 2 2 4 4 4 4 4 8 10
0 a 4,294,967,295 -2,147,483,648 a 2,147,483,647 0 a 4,294,967,295 3.4E+/-38 (7 dgitos) 1.7E+/-308 (15 dgitos) 1.2E+/-4932 (19 dgitos)
DECLARAO DE VARIVEIS
26
Identificadores
27
Identificadores
28
Exemplos de identificadores
Exemplo:
4_nota;
Ateno:
30
Palavras Chaves
(so 32 palavras)
auto break case char const continue default do
31
Declaraes
tipo
lista-de-nomes-de-variveis
Exemplo:
int i,a;
double d1, d2;
char c;
32
Inicializao de Variveis
33
Operaes
34
Atribuio
Exemplo:
35
Exemplos de Atribuio
i = (j = k) - 2; 5 3 (caso k=5) j=5 i=3
Atribuio
mltipla:
a=b=c=8;
36
O compilador faz uma converso automtica float r1,r2=3.5; int i1,i2=5; char c1,c2=A;
r1=i2; i1=r2; i1=c2; c1=i2; r1=c2; c1=r2; /* /* /* /* /* /* r1 5.0 */ i1 3 */ i1 65 */ c1 5 */ r1 65.0 */ c1 3 */
37
Adio/subtrao/multiplicao
Expresso1 + expresso2 Expresso1 - expresso2 Expresso1 * expresso2
As duas expresses so avaliadas, depois a adio/subtrao/multiplicao realizada, e o valor obtido o valor da expresso.
Pode ter uma converso de tipos, depois da avaliao das expresses: float x,y; int z; x=y+z;
39
Diviso (1)
Expresso1 / expresso2
Em C, o / designa no mesmo tempo a diviso dos inteiros e dos reais. Isto depende ento dos valores retornados pelas expresses:
Se os dois so inteiros ento a diviso inteira, mas se um deles real ento a diviso real.
40
Diviso
(2)
Caso os dois operandos inteiros so positivos, o sistema arredonda o resultado da diviso a zero:
7 / 2 retorna 3
Caso os dois operandos inteiros so de sinais diferentes, o arredondamento depende da implementao mas geralmente feito a zero:
-7 / 2 ou 7 / -2 retornam -3 ou -4 (mas geralmente -4)
41
O Mdulo %
Expresso1 % Expresso2
Caso um dois operadores seja negativo, o sinal do mdulo depende da implementao, mas geralmente o sinal do primeiro
7 % 2 -7 % 2 7 % -2 retornam 1 retornam -1 retornam 1
42
Operadores Relacionais
Expresso1 op-rel Expresso2 Onde op-rel um dos seguintes smbolos: Operador Semntica == igual != diferentes > superior >= superior ou igual < inferior <= inferior ou igual
O resultado da comparao um valor lgico: 1 (se a comparao verificada) e 0 (seno)
43
Operadores Lgicos
&& || !
e ou negao
Exemplos:
a >= b (a = = 0) || (b != 0) ! ((a = = 0) && (b<3))
44
45
Incremento/decremento
x = x + 1;
x++; ++x; s+=i; z = y++; z = ++y;
46
/* isto incrementa x */
/* isto incrementa x */
/* isto incrementa x */
/* s=s+i*/ /* z = y e depois y++ */ /* y++ e depois z = y (novo) */
Regra
v = v operador expresso v operador= expresso
47
Condicional
a = (b >= 3.0 ? 2.0 : 10.5 );
if (b >= 3.0) a = 2.0; else a = 10.5;
/* c=maior(a,b) */
/* c=menor(a,b) */
Entradas e Sadas
49
Sadas
Printf("Bom dia");
puts("Bom dia"); putch(a) printf
idade)
50
Entradas
gets(s);
char c; c = getch();
/* leitura de um string */
c = getchar();
/* com echo */
scanf ("%d",&nome);
/* para a leitura da var. nome */
51
nova linha tabulao (horizontal) tabulao vertical um espao para trs um return um bip backslash o caracter % um apostrofo um ponto de interrogao
Converso de Tipos
d o x e u c s f
53
notao de decimal notao octal notao hexadecimal notao matemtica notao sem sinal notao de caracter notao de string notao de flutuante
Formatao
Cada um desses caracteres de converso utilizado depois do % para indicar o formato da sada (da converso)
Mas, entre os dois podemos entrar outros argumentos:
54
Formatao
+ n 0n n.m
justificar a esquerda
o sinal sempre aparente o comprimento mnimo da sada (seno brancos) o comprimento mnimo da sada (seno 0s esquerda) para separar as partes antes e depois da virgula total de n dgitos, cujo m so depois da virgula. para indicar um long
l
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
Exemplo
{ printf("\n");
}
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);
}
59
Exemplo
As sadas so:
f f f f f
60
Diretivas de Compilao
61
Diretivas de compilao
62
Para a incluso de um arquivo. A busca do arquivo feita em primeiro no diretrio atual e depois no local das bibliotecas:
Em Unix:
Em DOS:
/usr/lib/include
APPEND (~ PATH, mas para os arquivos de dados e no para os executveis) Em Windows: isto especificado no ambiente
63
nome-de-arquivo
64
Exemplo de incluso
... #include "f2.c" ...
f2.c
for (i=0;i<5;i++)
printf("Oi");
f1.c f1.c
... for (i=0;i<5;i++) printf("Oi"); ...
65
Um arquivo header contm um conjunto de declaraes de variveis e funes. Observao: Os headers includos podem tambm incluir outros arquivos (mas no pode existir uma referencia mtua)
66
Substituies: #define
#define MAX 60
#define TRUE 1 #define FALSE 0 #define BOOLEAN int BOOLEAN a=FALSE; if (a = = TRUE) ...; else ...;
Outros Macros
#define quadrado(a) (a)*(a) #define quadrado(a) a*a #define adicionar(a,b) ((a)+(b)) #define adicionar(a,b) (a)+(b)
quadrado(3-2); (3-2)*(3-2) = 1 5*adicionar(2+1,4); 5*((2+1)+(4)) = 35
regra geral: colocar todas as variveis entre parnteses e o resultado tambm
69
Substituies parciais
#define MAX 60 ... #undef MAX #define MAX 45
...
/*aqui MAX=45*/ /*aqui MAX=60*/
70
71
O const
Para declarar variveis constantes podemos usar a palavra chave const const int N 20
Isto proibe que N seja modificado no programa (toda tentativa de modificao vai dar erro)
73
Estruturas de Controle
74
Blocos de instrues
{
declaraes instruo_1 ..... } instruo_2 Em um bloco pode-se declarar variveis, que ficam visveis somente no bloco.
75
if (a!=0) x=-b/a;
Qualquer instruo simples C pode ser substituda por uma instruo composta: if (d>0) {
x1=(-b-sqrt(d))/2*a; x2=(-b+sqrt(d))/2*a; }
77
else
78
Observao
A condio no obrigatoriamente uma comparao. Pode ser qualquer expresso retornando um valor que pode ser comparado a zero.
81
82
}
83
Instrues de Repetio
84
while
while (condio) instruo
instruo Exemplo: c=s; while (c!=f) { c=getch(); }
85
fim do while
no
do...while (1)
do instruo(es) while (condio)
o equivalente de repeat do Pascal. A instrues do lao de repetio so executadas pelo menos uma vez.
86
do...while
do
c=getch(); while (c==s)
(2)
instruo
fim do do sim condio!=0 ?
no
87
for
(1)
Exemplo:
88
for
(2)
expresso1 inicializao fim do for
condio!=0 ?
sim
no
instrues
expresso2
89
for
(3)
A novidade que as expresses podem ser instrues mltiplas (separadas por virgula)
Exemplo: for (i=1,j=10; i<=j; i++,j--) { instrues;
90
break
O break permite parar a instruo de repetio (for, do ou while)
Se temos vrios nveis, o controle volta penltima estrutura de repetio. for (i=0;i<20;i++) if (vet[i]==10) break;
91
continue
92
Instruo: goto
goto <identificador> ;
permite quebrar a seqncia do programa Exemplo: mais:
...
If condio goto mais;
93
Funes
94
Alm das funes predefinidas nos arquivos header da biblioteca (no diretrio LIB, usando o #include)
O usurio pode definir novas funes. Exemplos de funes predefinidas da biblioteca: stdio.h, math.h, conio.h, stdlib.h e dos.h
95
96
int
abs(int)
double fabs(double) double exp(double) double double double double ceil(double) floor(double)
pow(double x,double y)
pow10(double) sqrt(double)
hypot
sqrt
97
hipotenusa
raiz quadrada
apaga a tela
apaga o resto da linha apaga a linha atual insere uma linha
posiciona o cursor
void clrscr ()
void clreol () void delline () void insline ()
void gotoxy (int x, int y)
testa se tecla
int
int
kbhit ()
putch (int c)
putch ()
int int wherex () wherey ()
posio y do cursor
int randomize()
sound(300); /* emitir um som de 300 Hz*/ delay(2000); /* esperar 2 segundos */ nosound(); /* antes de parar */
100
Exemplos de funes
graphics.h
rectangle desenha um retngulo void rectangle (int e, int c, int d, int b)
string.h
101
Semntica
tipo:
o tipo do valor devolvido pela funo
Exemplo
float media (a,b) float a,b; /* declarao dos
parmetros formais */
return (resultado);
}
104
105
Observao
{
if (a<b) return (a);
else
return (b); }
106
Procedimentos
Observao: no temos aqui a instruo return (o tipo especial void no existia nas primeiras verses da linguagem)
108
109
111
&
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
parmetros
113
Declarao de Funes
Uma funo F conhecida implicitamente por uma outra funo G se elas so definidas no mesmo arquivo, e que F definida antes de G.
Fora desse caso, e para um controle de tipo e um bom link, preciso declarar as funes antes de usar.
114
Exemplo
void { } ... int maior (int x, int y) { return (x>y?x:y); }
/*a main pode ser definida antes*/
115
main
(void)
int maior (int x, int y); 2a Mas, melhor usar o segundo formato
116
Funes Iterativas
exemplo do fatorial
long int fat (long int n) { long int i,res=1; for (i=1;i<=n;i++) res=res*i; return (res); }
117
Funes Recursivas
exemplo do fatorial
long int fat (long int n) { if (n == 1) return 1; else return (n*fat(n-1)); }
118
Exerccios
119
Declaraes
120
121
/*cobre o i precedente*/
/* cobre o j precedente*/
/*cobre o k precedente*/
}
122
Variveis Estticas:
Alocao no incio do programa e liberao no final da execuo do programa.
Variveis Automticas
Alocao na entrada de uma instruo composta (um bloco) e liberao na sada.
Variveis Dinmicas
A declarao e liberao so explicitamente realizadas pelo programador (usando malloc e free). Mas, essas funes so da biblioteca e no fazem parte integrante da linguagem.
123
124
As variveis globais so variveis estticas. As variveis locais podem ser estticas ou automticas (dependendo do programador), usando os qualificadores de classes de armazenagem: static e auto. Por default, uma varivel local automtica.
125
auto
static register extern
126
auto
{auto int i;
... }
Este tipo de indicador autorizado somente para as variveis locais a uma instruo composta (um bloco). Ele indica que a varivel tem uma durao de vida local ao bloco.
127
static
{static int i;
... }
O static indica que a varivel tem uma durao de vida ao longo da execuo do programa. Mas que ela fica local ao bloco (ela fica desconhecida fora de seu bloco). Portanto, a varivel guardar seu valor para
128
A varivel num_chamada inicializada somente uma vez. Tem durao de vida ao longo da execuo do programa. Mas ela tem escopo local.
129
register
{register int a,b;
... }
Este tipo de indicador autorizado somente para as variveis locais a uma instruo composta (um bloco) e para as declaraes de parmetros de funes. Ele tem o significado do auto, alm de provocar o armazenamento da varivel em um registro e no na memria. acesso mais rpido. Claro que isto depende das capacidades da mquina (nmero e tamanho dos registros)
130
extern
int a; void f() {...
Os outros indicadores so relacionados s variveis locais. Uma varivel global definida fora de qualquer corpo de funo. O extern permite usar (acessar) uma varivel que definida fora.
131
132
133
Tabelas
134
Tabelas
O objetivo da estrutura de tabela agrupar um conjunto de informaes de mesmo tipo em um mesmo nome.
135
Declarao
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
Dimenso
137
Inicializao
#define N 4 int v[N]={1,2,3,4};
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; v[++i]=0;
140
Inicializao 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:
for (i=0; i<N && t[i]!=10; i++);
/* usando a instruo nula */
141
Tabelas MultiDimensionais
Matrizes
Declarao:
int mat [3][4];
/* matriz bidimensional de 3 linhas 4 colunas */
Inicialiazao:
int mat [3][4] = { {5,6,8,1}, {4,3,0,9}, {12,7,4,8}, }
142
Exemplo
/* Declarao: */
#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
Observao 1
for (i=0,j=0;i<L && j<C;i++,j++) {
printf("digite o elemento [%d,%d]: ",i,j); scanf("%d",&mat[i][j]);
}
no a mesma coisa que:
for (i=0;i<=L;i++) for (j=0;i<=C;j++) { printf("digite o elemento [%d,%d]: ",i,j); scanf("%d",&mat[i][j]); }
144
Observao 2
int sum (int n) { int res=0; for (;n>0;n--) /*n inicializada na chamada*/ res=res+n; return (res); }
chamada: sum(5)
Exerccios
A.1 Escreva o procedimento ini_num_dias que inicializa um vetor num_dias[12] que indica para cada ms do ano seu nmero de dias: (num_dias[i] indica o nmero de dias do ms i do ano), sabendo que:
Se i=2 ento num_dias=28; Se (i par e i<=7) ou (se i impar e i>7) ento num_dias=30 Seno num_dias=31.
A.2 Escreva o procedimento imp_num_dias que imprima os nmeros de dias de todos os meses do ano.
146
B. Escreva a funo ordenar que ordena um vetor. C. Escreva a funo palindromo que determina se um vetor um palindromo.
Tipos Enumerados
147
enum
exemplos:
enum dias {Domingo, Segunda, Tera, Quarta, Quinta, Sexta, Sbado};
declarao:
dias d1,d2=Quinta;
enum defini um novo tipo cujo os elementos so numerados automaticamente de pelo compilador: 0 1 2 ...
148
Exemplo
#include <stdio.h> enum dias {Segunda,Tera,Quarta,Quinta, Sexta,Sbado,Domingo} d; // d uma varivel declarada de tipo dias
void main (void) { // dias d; uma outra maneira de declarar for(d = Segunda ; d < Domingo ; d++) printf(O cdigo do dia : %d\n", d); }
Vai imprimir os valores dos dias:
149
0, 1 at 6.
enum
Essa numerao permite comparar os elementos do tipo: if (d1<=d2) ... Portanto podemos mudar essa numerao:
enum boolean {true=1,false=0};
150
Ponteiros
151
Variveis Dinmicas
152
Variveis Dinmicas
pf 4.6
153
O operador de endereamento & se aplica sobre uma varivel e permite retornar seu endereo memria
O operador de indireo * se aplica sobre um ponteiro e permite retornar (manipular) o objeto apontado.
154
P
(Ponteiro)
V
(Varivel)
&v
155
Exemplo
int i,j; int *pi;
/* pi um ponteiro sobre um inteiro */
i=5;
pi=&i; *pi=6; j=*pi-2; pi=&j;
156
pi &i &j
56 i 4 j
Exerccio
1. Declare um inteiro i e um ponteiro p sobre um inteiro
2. Inicialize o inteiro com um valor qualquer 3. Aponte o ponteiro sobre a varivel i 4. Imprima o valor de i
/* 1 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */
Passagem de Parmetros
(FORTRAN, PL/1)
Temos a escolha entre a passagem por valor ou por referncia (caso de PASCAL) Toda passagem feita por valor (caso de C)
159
Estratgia de C
160
Exemplo
void
{ }
*res=a+b;
observe que na chamada tem que passar o endereo da varivel onde deseja-se recuperar o resultado
Um outro exemplo
A funo troca
void troca (int * x, int * y) { int temp; temp=*x; *x=*y; *y=temp; }
Funes Genricas
O problema que esta funo troca que ns definimos se aplica somente sobre os inteiros
void troca (void * x, void * y) { int temp; temp=*x; *x=*y; *y=temp; } Infelizmente isto no pode ser feito em C Mas o problema resolvido em C++
163
Tabelas e Ponteiros
164
Conseqncia 1
166
Conseqncia 2
Manipulao de sub-tabelas:
int t[10]; int * p; p=&t[2];
0 1 2 3 9
p t
Conseqncia 3
O operador de indexao comutativo: t[i] = i[t]
isto porque a adio comutativa:
t[i] i[t]
*(t+i) *(i+t)
Mas, por razes de legibilidade do programa esta possibilidade muito pouco utilizada.
168
169
r=&t[N-1]; s=r-(N-1);
170
Passagem de Parmetros
171
1a Abordagem
void imp_tabela (int * t, int num_elem)
{ int i;
for (i=0;i<num_elem;i++)
printf("%d",*(t+i)); }
chamada: imp_tabela(tab,N);
/* que equiv. a: */
imp_tabela(&tab[0],N);
172
Crtica
Este mtodo apresenta inconvenientes:
173
2a Abordagem
Por esta razo, C permite uma declarao mais natural dos parmetros formais:
Ateno: No preciso conhecer o tamanho exato da tabela. o tamanho geralmente passado como parmetro separado.
chamada:
174
imp_tabela(tab,L);
No caso de uma tabela multidimensional somente a primeira dimenso pode no estar especificada:
int min (int m[][C], int l) { int i,j,min=m[0][0]; for(i=0,j=0;i<l&&j<C;i++,j++) if (m[i][j]<min) min=m[i][j]; return(min); }
175
chamada: min(mat,L);
Algumas consideraes
A funo min aplicada a uma tabela que tem qualquer nmero de linhas, mas deve ter um exato C de colunas.
As outras dimenses ( 1a), devem ser especificadas por que o compilador precisa para gerar o cdigo que permite o acesso aos elementos: No caso de uma matriz binria t por exemplo, o endereo de t[i][j] : t+(i*C+j)*T (T o tamanho de um elemento de t, C o nmero de colunas) Representao da tabela na memria:
11 12 13 14 21 22 23 24 31 32 33 34 41...
176
/* j que a passagem de parmetros feita por referncia ento qualquer modificaes sobre o vetor fsica */
O que faz esta funo?
177
Tabelas de ponteiros
possvel declarar uma tabela de ponteiros:
acesso:
*tab[i]
tab
178
*tab[i]
Objeto apontado
Ponteiro de Ponteiro
179
Ortogonalidade do operador *
J que um ponteiro uma varivel como as outras, muito normal que um ponteiro aponte sobre um ponteiro
Um exemplo um ponteiro sobre um ponteiro sobre mais um inteiro
int
Argumentos do main
argc (argument count) que determine o nmero de argumentos da linha de comando; e argv (argument vector), que um ponteiro sobre uma tabela de ponteiros sobre strings:
181
argv
182
exemplo
Suponha: programa achar_max pega como parmetros um conjunto qualquer de strings e que deve determinar e imprimir a maior string:
argv achar_max\0 \0
\0
\0
183
argv[0] o nome do programa: achar_max,e os outros argv[i] so os argumentos passados ao programa na linha de comandos.
#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
186
Declarao
187
Os strings declarados como vetor de chars tm um tamanho limite fixo (o tamanho do vetor).
188
Se o tamanho do string menor do que o tamanho do vetor, o compilador C completa pelo caractere especial \0 para indicar o fim do string.
A inicializao de um vetor de char pode ser feita, no momento da declarao, de duas maneiras:
1. Atribuindo um conjunto de caracteres:
char ch [20]={e,x,e,m,p,l,o}; (como normalmente feito para inicializar qualquer tipo de vetor).
char ch[20]= "exemplo"; O tamanho pode ou no estar especificado: char nome[]="este tem 23 caracteres";
189
O i
\0
...
ch[N-1]
190
H i
\0
A manipulao dos strings como vetores de caracteres pode aparecer como pouco prtica.
Portanto, podemos criar strings de tamanho dinmico usando um ponteiro sobre um char: char * ch = "exemplo";
Contrariamente outra maneira, a reserva do espao memria no feita no momento da declarao, mas dinamicamente no momento da atribuio.
191
Inicializao e Atribuio
A Inicializao feita diretamente por uma string:
Manipulao de Strings
As funes de manipulao de strings so definidas no arquivo da biblioteca string.h
strncpy
Strcpy/strncpy
A funo especial strcpy permite atribuir um valor texto a uma varivel de tipo texto:
O strcpy apresenta dois formatos de uso:
strcpy(string1,string2); strncpy(string1,string2,N);
exemplo:
char *ch1="boa", *ch2="noite"; strcpy(ch1,"isto um exemplo"); strncpy(ch2,ch1,4); /* ch2 vai pegar "isto" */
194
strlen
strlen permite retornar o tamanho de um string: nmero de chars que compem o string (o \0 no faz parte)
exemplo:
int a; char * nome; strcpy(nome,brasil"); a=strlen(nome); /* a=6 */
195
strcat/strncat
strcat se aplica sobre dois strings e retorna um ponteiro sobre a concatenao dos dois.
exemplo:
char *ch1="boa", *ch2="noite", *ch3, *ch4;
196
strcmp/strncmp
Lembramos que as letras so ordenadas dando seu cdigo: a< ... z< A...<Z
exemplo:
char
strchr/strrchr
strchr procura por um caractere em um string e retorna um ponteiro sobre sua ltima ocorrncia, seno retorna null. exemplo:
char ch[]="informtica"; 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 minsculo em maisculo. tolower faz o contrrio. # include <ctype.h>
char c='a';
/* c= 'A'
*/
Exerccios 1
A. Defina a funo ocorrncia que retorna o
nmero de ocorrncias de um caractere em um string.
int tamanho1 (char s[]) /* com um vetor */ { int i=0; while (s[i]) /* equiv. while (s[i]!= '\0' ) */ i++; return (i); }
int tamanho2 (char * s) /*com os ponteiros*/ { int i=0; while (*s) /* equiv. while (*s!= '\0 ') */ {i++;s++;} return (i); }
201
void
main (void)
{
char ch[]="So Luis"; int a,b; a=tamanho1(ch); b=tamanho2(ch); /* a= 8*/ /* b= 8*/
202
203
Tipos usurios
204
typedef
Podemos definir novos tipos usando o typedef: typedef <tipo> <sinnimo>
exemplo:
typedef float largura; typedef float comprimento;
typedef e struct
206
Estruturas
207
Declarao: mtodo 1
struct cliente { int cpf; char nome [20]; char endereco[60]; };
Declarao: mtodo 2
Podemos criar estruturas sem nome: struct { int cpf; char nome [20]; char endereco[60]; } c1,c2; Problema: para criar uma outra varivel de mesmo tipo em outro lugar do programa preciso rescrever tudo.
209
Declarao: mtodo 3
Podemos, no mesmo tempo, dar um nome estrutura e declarar as variveis:
struct cliente { int cpf; char nome [20]; char endereco[60]; } c1,c2;
Declarao: mtodo 4
Definindo um tipo estrutura typedef struct { int cpf; char nome [20]; char endereco[60]; } Cliente;
Cliente
211
Exemplo
void { imprimir_cliente (Cliente c)
Combinao de Estruturas
Podemos definir estruturas de estruturas, estruturas de vetores, vetores de estruturas.... exemplo
typedef
struct {int num; char * rua; char * bairro; int cep} End; struct {int cpf; char * nome; End endereco} Pessoa;
typedef
214
Vetores de Estruturas
exemplo: struct cliente vet[100]; /* seguindo o mt. 1*/ Cliente vet[100]; /*seguindo o mt. 4*/ declara um vetor de 100 clientes.
Referencia aos elementos: Para referenciar o nome do isimo cliente do vetor: vet[i].nome
215
Exerccio
Escreve um programa C que:
Declara um vetor de alunos: turma (um aluno definido pelo cpd, nome, trs notas, mdia, e conceito) Preenche esse vetor (campos: cpd, nome, e notas). Preenche os campos mdia e conceito (bom se mdia8, regular se 7 e ruim seno); Define a funo que imprime todos o elementos do vetor. Define a funo que pesquisa um elemento do vetor (pesquisa pelo nome, pelo cpd, ou pelo conceito).
216
Estruturas e Ponteiros
217
Estruturas dinmicas
Usando as estruturas e os ponteiros podemos entrar no mundo das estruturas auto referenciais: Listas, Arvores, Grafos, etc.
218
Para acessar aos campos da estrutura apontada por pp usamos o operador -> pp->nome; /* equiv. a pess.nome */ pp->idade=25; /* pess.idade=18 */
221
Para acessar o campo nome de pessoa apontada por um ponteiro pp: *pp.nome Mas o operador de seleo . mais prioritrio do que o operador de indireo * isto equiv. a: *(pp.nome) o que est errado (pois pp no uma estrutura). Deveremos escrever: (*pp).nome Mas esta notao um pouco complicada. Por isso temos um novo operador -> (pp->nome)
typedef struct pessoa { char nome[30]; int idade; PtrPessoa next; } Pessoa;
/* next um ponteiro sobre uma outra pessoa */
PtrPessoa
223
pp;
Ilustrao
CPF
nome endereco next CPF nome endereco next
224
... printf("Entra com o nome: "); scanf("%s",&p->nome); printf("Entra com a idade: "); scanf("%d",&p->idade); p->next=NULL;
225
O tamanho alocado a um tipo pode ser conhecido usando o operador sizeof (a medida feita em nmero de bytes).
sizeof pode ser usada de duas maneiras (aplicao a um tipo ou uma varivel) exemplos: int tamanho,i; tamanho=sizeof i; tamanho=sizeof (short i); tamanho=sizeof (Pessoa);
226
Listas
O fato de que uma estrutura pode apontar para uma outra permite criar listas encadeadas.
Uma lista encadeada til principalmente quando ns no sabemos a priori (no momento da compilao) o nmero de seus elementos, o que uma necessidade no caso do uso do tipo vetor.
Contrariamente aos vetores, uma lista encadeada uma estrutura dinmica: os elementos so criados dinamicamente:
227
malloc para a alocao do espao memria para um elemento; e calloc para a alocao do espao memria para um conjunto de elementos.
228
malloc
malloc
um nico parmetro que o tamanho (em bytes) do espao memria do elemento que ns 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));
229
pega
p=malloc(sizeof(char));
calloc
calloc pega dois parmetros: - o nmero de elementos que desejamos criar; - e o tamanho de um elemento (em bytes).
O objetivo de alocar espaos para vrios elementos de s uma vez.
230
calloc
231
Observao
As funes malloc e calloc so definidas no arquivo <alloc.h> da biblioteca.
Geralmente antes do malloc tem que especificar o tipo da estrutura cujo o ponteiro que ser criado vai apontar:
pat=(PtrPessoa)malloc(sizeof(Pessoa));
p=(char *)malloc(sizeof(char));
232
null
Quando no tem mais espao livre, as
funes malloc e calloc retornam o valor null Este valor pode servir tambm para
Liberao de Memria
Podemos liberar o espao memria alocado para
uma varivel dinmica: free(nome-do-ponteiro); int * p; ... p=(int *)malloc(sizeof(int));
// 2 bytes
234
235
Exemplo
typedef struct {int dia,mes,ano;} data;
/* funo de comparao entre duas datas */ int comp_datas(data * d1, data * d2) { if (d1->ano==d2->ano) && ... return 1; else return 0; } data d1,d2; ... comp_datas (&d1,&d2);
236
data * d2001 () { data * p; p=malloc(sizeof(data)); p->dia=1; p->mes=1; p->ano=2000; return (p); } data * d; d=d2001();
237
Observao
Pessoa * p; p=malloc(...)
Normalmente o malloc no retorna um ponteiro sobre uma estrutura. Isto pode causar um warning. Uma maneira correta de escrever :
p=(Pessoa*)malloc(sizeof(Pessoa))
Exerccio
239
return (anniv);
} data d_nasci,d_anniv; ... d_anniv=proximo_anniv(&d_nasci);
240
Criao de Listas
typedef struct {
char nome[20]; int peso; Pessoa * seguinte; } Pessoa;
nome, peso nome, peso
Cabea
nome,peso
next
241
next
...
NULL
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
Listas
244
Listas
Lista de Tarefas
Comeo em 3 Item 1. Pagar as contas no banco 2. Comprar os livros na livraria 3. Deixar o carro no estacionamento 4. Pegar algumas fitas na videolocadora Prximo 6 4 8 Final
1
2 5 7
Farmcia (9)
Foto (6) Livraria (2)
246
Farmcia (9)
Foto (6) Livraria (2)
247
Farmcia (9)
Foto (6) Livraria (2)
248
1 Passo
lista[9].prox = lista[6].prox;
2 Passo
Lista[6].prox = 9;
249
Farmcia (9)
Locadora (4) 0
250
Farmcia (9)
Foto (6) 0
251
Farmcia (9)
Foto (6) 0
252
1 Passo
lista[9].prox = lista[4].prox;
2 Passo
Lista[4].prox = 9;
253
Farmcia (9)
comeo Estacionam (3)
254
Farmcia (9)
comeo Estacionam (3)
255
Farmcia (9)
comeo Estacionam (3)
256
1 Passo
lista[9].prox = comeco;
2 Passo
comeco = 9;
257
258
Farmcia (9)
comeo Estacionam (3)
259
Farmcia (9)
comeo Estacionam (3)
260
261
Filas (FIFO)
tambm uma Lista Regra: todo o elemento que entra na lista, entra no final e todo o elemento que sai da lista, sai do incio 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
266
268
rvores Binrias
info
271
info
0 0 0
rvores - conceitos
Raiz Ns N terminal Sub-rvore Altura
272
Transversalizao
d
b a
f c e g
Unies de Tipos
274
Objetivo
Todas variveis que nos vimos at agora possuam um nico tipo. As vezes interessante atribuir vrios tipos a uma varivel (uma mesma zona memria).
Isto pode ser feito atravs do mecanismo de unies de tipos usando a palavra chave union. Portanto, uma varivel teria, a um dado instante, um nico tipo, porm pode mudar.
275
Declarao
Exemplo:
/* declarao de um tipo que una os inteiros e os reais */
typedef union { int i; float f; } nmero;
*/
Observao
A declarao parecida s estruturas, mas nas unies somente um campo atribudo um valor. O problema que nos no podemos saber a um dado instante do programa, qual o tipo do atual valor da varivel. Por isso que na prtica a unio associada a um indicador de tipo (o tipo atual) e os dois so combinados em uma estrutura:
277
}
278
a1.tipo_var=INTEIRO;
a1.tipo_var=REAL a1.nmero.i=10; a1.nmero.i=10;
279
Arquivos
281
Streams
Stream de texto
Sequncia de caracteres
Stream binria
Abre um arquivo Fecha um arquivo Escreve um caractere em um arquivo L um caractere em um arquivo #include <stdio.h>
Funo
Posiciona o arquivo em um bytes especfico
fprintf()
fscanf() feof() ferror() rewind() remove()
= printf console
= scanf console Final de arquivo? Ocorreu um erro? Indicador de posio no incio do arquivo Apaga um arquivo
284
Ponteiro de arquivo
arquivo:
285
Abrindo um arquivo
FILE *fopen(nomearq, modo);
286
Abrindo um arquivo
287
r
w a rb
r+
w+
a+
r+b
wb ab
w+b
a+b
Abrindo um arquivo
file *fp;
if ((fp=fopen(test,w))==null)
{
printf(no pode ser aberto);
exit(1);
}
288
Fechando um arquivo
Funo fclose()
Exite uma quantidade mxima de
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