Upload
caio-zapparolli
View
83
Download
1
Embed Size (px)
DESCRIPTION
Prova que é aplicada na faculdade anhanguera
Citation preview
Cadeias de caracteres (strings)
Uma string (ou cadeia de caracteres) na linguagem C um vetor de caracteres em que o caractere nulo ('\0') interpretado como fim da parte relevante do vetor. Exemplo:
char *s;
s = malloc( 10 * sizeof (char));
s[0] = 'A';
s[1] = 'B';
s[2] = 'C';
s[3] = '\0';
s[4] = 'D';
Depois da execuo desse fragmento de cdigo, o vetor s[0..3] contm a string ABC. O caractere nulo marca o fim dessa string. A poro s[4..9]do vetor ignorada.
Comprimento e endereo
O comprimento (= length) de uma string o seu nmero de caracteres, sem contar o caractere nulo final.
O endereo de uma string o endereo do seu primeiro caractere, da mesma forma que o endereo de um vetor o endereo de seu primeiro elemento.
Em discusses informais, usual confundir uma string com o seu endereo. Assim, a expresso considere a string s deve ser entendida comoconsidere a string cujo endereo s.
Strings constantes
Para especificar uma string constante, basta embrulhar uma sequncia de caracteres num par de aspas duplas. O caractere nulo
final fica subentendido. Por exemplo, "ABC" uma string constante e o fragmento de cdigo
char *s;
s = "ABC";
equivalente ao que aparece na introduo desta pgina (exceto pelo fato de que a string "ABC" ocupa apenas 4 bytes na memria).
O primeiro argumento das funes printf e scanf, quase sempre uma string constante. Por exemplo,
scanf( "%d", &n);
printf( "O valor de n %d", n);
Exerccios 1
1. Qual o efeito do seguinte fragmento de cdigo?
2. char *s;
3. s = "ABC";
4. printf( "%s\n", s);
5. O que h de errado com a seguinte variante do exerccio anterior?
6. char s[20];
7. s = "ABC";
8. printf( "%s\n", s);
Exemplo: contagem de vogais
A seguinte funo conta o nmero de vogais (no acentuadas) em uma string:
int contaVogais( char s[]) {
int numVogais, i;
char *vogais;
vogais = "aeiouAEIOU";
numVogais = 0;
for (i = 0; s[i] != '\0'; ++i) {
char ch = s[i];
int j;
for (j = 0; vogais[j] != '\0'; ++j) {
if (vogais[j] == ch) {
numVogais += 1;
break;
}
}
}
return numVogais;
}
Exerccios 2
1. Qual a diferena entre "A" e 'A'?
2. Qual a diferena entre "mno" e "m\no"? Qual a diferena entre "MNOP" e "MN0P"? Qual a diferena entre "MN\0P" e "MN0P"?
3. Escreva uma funo que receba um caractere c e devolva uma string cujo nico caractere c.
4. Escreva uma funo que receba uma string e imprima uma tabela com o nmero de ocorrncias de cada caractere na string. Escreva um programa para testar a funo.
5. PALNDROMOS. Escreva uma funo que decida se uma string ou no um palndromo (ou seja, se o inverso da string igual a ela). Escreva um programa para testar a funo.
6. Escreva uma funo que receba strings s e t e decida se s segmento de t (ou seja, se s pode ser obtida apagando um nmero arbitrrio de elementos do incio de t e um nmero arbitrrio de elementos no fim de t). Escreva um programa que use a funo para contar o nmero de ocorrncias de uma string s em uma string t.
7. Escreva uma funo que receba uma string e substitua cada segmento de dois ou mais espaos em branco por um s espao em branco.
8. Escreva uma funo que receba uma string de 0s e 1s, interprete essa string como um nmero natural em notao binria e devolva o valor desse nmero.
A biblioteca string
A biblioteca padro string da linguagem C contm vrias funes de manipulao de strings. Para usar essas funes, o seu programa deve incluir
#include
o arquivo-interface string.h. Eis as funes mais importantes da biblioteca string:
A funo strlen (o nome uma abreviatura de string length) recebe uma string e devolve o seu comprimento. O cdigo dessa funo poderia ser escrito assim:
unsigned int strlen( char *s) {
int k;
for (k = 0; s[k] != '\0'; ++k) ;
return k;
}
A funo strcpy (o nome uma abreviatura de string copy) recebe duas strings e copia a segunda (inclusive o caractere nulo final) para o espao ocupado pela primeira. O contedo original da primeira string perdido. Antes de chamar a funo, o programador deve certificar-se de que o espao alocado para a primeira string suficiente para acomodar a cpia da segunda. (Buffer overflow uma das mais comuns origens de bugs de segurana!) O cdigo dessa funo poderia ser escrito assim:
void strcpy( char *s, char *t) {
int i;
for (i = 0; t[i] != '\0'; ++i)
s[i] = t[i];
s[i] = '\0';
}
(Na verdade, a funo strcpy no do tipo void. Ela do tipo char * e devolve o seu primeiro argumento. Isso til em algumas situaes, mas em geral os usurios s esto interessados no efeito da funo e no no que ela devolve.)
A funo strcpy pode ser usada da seguinte maneira para obter um efeito semelhante ao do exemplo no incio desta pgina:
char s[10];
strcpy( s, "ABC");
A funo strcmp (o nome uma abreviatura de string compare) recebe duas strings e compara as duas lexicograficamente. Ela devolve um nmero negativo se a primeira string for lexicograficamente menor que a segunda, devolve 0 se as duas strings so iguais e devolve um nmero positivo se a primeira string for lexicograficamente maior que a segunda.
Embora os parmetros da funo sejam do tipo char *, a funo se comporta como se eles fossem do tipo unsigned char *. Assim, por exemplo, "bb" considerada lexicograficamente menor que "bb" e "ba" considerada lexicograficamente menor que "b". O cdigo da funo poderia ser escrito assim:
int strcmp( char *s, char *t) {
int i;
unsigned char usi, uti;
for (i = 0; s[i] == t[i]; ++i)
if (s[i] == '\0') return 0;
usi = s[i]; uti = t[i];
return usi - uti;
}
Convm lembrar que o valor da expresso usi - uti calculado em aritmtica int (e no mdulo 256).
A ordem lexicogrfica a que nos referimos acima anloga ordem das palavras em um dicionrio. Ela se baseia na ordenao dos caracteres estabelecida na tabela ISO8859-1, da mesma forma que a ordem das palavras em um dicionrio se baseia na ordenao usual das letras no alfabeto. Para comparar duas strings s e t, procura-se a primeira posio, digamos k, em que as duas strings diferem. Se s[k]vem antes de t[k] na tabela ISO ento s lexicograficamente menor que t. Se k no est definido ento s e t so idnticas ou uma prefixo prprio da outra; nesse caso, a string mais curta lexicograficamente menor que a mais longa.
Poderamos tratar strings como um novo tipo-de-dados introduzindo a definio
typedef char *string;
Feito isso, todas as ocorrncias de char * podem ser trocadas por string.
Exerccios 3
1. Qual a diferena entre as expresses strcpy( s, t) e s = t?
2. Qual a diferena entre as expresses if (strcmp( s, t) < 0) e if (s < t)?
3. Discuta as diferenas entre os trs fragmentos de cdigo a seguir:
4. char a[8], b[8];
5. strcpy( a, "abacate");
6. strcpy( b, "banana");
7. char *a, *b;
8. a = malloc( 8); strcpy( a, "abacate");
9. b = malloc( 8); strcpy( b, "banana");
10. char *a, *b;
11. a = "abacate";
12. b = "banana";
13. O que h de errado com o seguinte trecho de cdigo?
14. char b[8], a[8];
15. strcpy( a, "abacate");
16. strcpy( b, "banana");
17. if (a < b)
18. printf( "%s vem antes de %s no dicionrio", a, b);
19. else
20. printf( "%s vem depois de %s no dicionrio", a, b);
21. O que h de errado com o seguinte trecho de cdigo?
22. char *b, *a;
23. a = "abacate";
24. b = "banana";
25. if (a < b)
26. printf( "%s vem antes de %s no dicionrio", a, b);
27. else
28. printf( "%s vem depois de %s no dicionrio", a, b);
29. O que h de errado com o seguinte trecho de cdigo?
30. char *a, *b;
31. a = "abacate";
32. b = "amora";
33. if (*a < *b)
34. printf( "%s vem antes de %s no dicionrio", a, b);
35. else
36. printf( "%s vem depois de %s no dicionrio", a, b);
37. Escreva uma funo que receba uma string s e um inteiro no negativo i e devolva o (i-1)-simo caractere de s, ou seja, o caractere s[i].
38. Escreva uma funo que receba uma string s e inteiros no negativos i e j e devolva o segmento s[i..j]. Sua funo no deve alocar novo espao e pode destruir a string s que recebeu.
39. Escreva uma funo que receba strings s e t e decida se s um segmento de t. Escreva um programa que use a funo para contar o nmero de ocorrncias de uma string s em uma string t.
40. Escreva uma funo que receba uma string s e um caractere c e devolva o ndice da primeira posio de s que igual a c. Agora faa uma verso mais completa da funo, que procura c a partir de uma dada posio i.
41. Escreva uma funo que receba strings x e s e devolve o ndice da posio a partir da qual x ocorre em s.
Matrizes e Vetores
Introduo
Uma matriz uma coleo de variveis de mesmo tipo, acessveis
com um nico nome e armazenados contiguamente na memria.
A individualizao de cada varivel de um vetor feita atravs do uso
de ndices.
Os Vetores so matrizes de 1 s dimenso.
Declarao de Matrizes
int Vetor[5]; // declara um vetor de 5
posies
int Matriz[5][3]; // declara uma matriz de 5
linhas e 3 colunas
Acesso aos elementos do vetor
Para acessar os elementos de um vetor usa-se ndices. O ndice define
a posio da varivel dentro do vetor.
Em todos os vetores tem o primeiro elemento na posio 0(zero).
Assim, se tomarmos "K" como sendo o tamanho do vetor a ltima posio a
de ndice "K-1"
Vetor[0] = 4; // Coloca 4 na primeira posio de "Vetor"
Vetor[4] = 8; // Coloca 8 na ltima posio
de "Vetor"
Exemplos com Vetores
int Vetor[5]; // declara um vetor de 5 posies
int Matriz[5][3]; // declara uma matriz de 5
linhas e 3 colunas
Vetor[0] = 9; // coloca 9 na primeira
posio do vetor
Vetor[4] = 30 // coloca 30 na ltima posio
do vetor
Matriz[0][1] = 15; // coloca 15 na clula
que est na primeira linha
// e na segunda coluna da
matriz
Preenchimento de um vetor com um dado
for(i=0; i
#define TAM_MAX 10
double VetReais[TAM_MAX];
for(i=0; i
if Vet1[i] > Vet1[PosMaior]
PosMaior = i; // acha a posio do maior
for(j=0; j
{
int Notas[TAM_MAX];
ImprimeVet(TAM_MAX, Notas); // Passa o vetor
'Notas' como
// parmetro
}
A passagem dos elementos de um vetor como parmetro idntica
passagem de uma varivel. Ou seja, quando a passagem for por valor usa-
se vet[i] e quando for por referncia usa-se&vet[i].
void Imprime (int N) // funo com um parmetro
por valor
{
printf("%d", N);
}
void Incr (int *N) // funo com um parmetro por
referncia
{
*N = *N + 1;
}
void Incr (int *N)
{
int i;
for (i=0; i< Tam; i++)
{
Incr(&Vet[i]); // Note que preciso colocar o
'&' antes
// de Vet[i] pois a funo
'Incr' espera um
// parmetro por
REFERNCIA
Imprime(Vet[i]); // Note que NO se deve colocar
nada antes
// de Vet[i] pois a
funo 'Imprime' espera um
// parmetro por VALOR
}
}
Exemplos com Matrizes
#define NLIN 10
#define NCOL 10
int Matriz[NLIN][NCOL];
Preencher uma matriz com um dado
for(i=0; i < NLIN; i++)
for(j=0; j < NCOL; j++)
Matriz[i][j] = 30;
Somar um nmero a uma linha/coluna de uma matriz
void SomaValorNaColuna(int Valor, int
Matriz[NLIN][NCOL], int Coluna)
{
for(i=0; i < NLIN; i++) // para cada linha de
'Coluna'
Matriz[i][Coluna] = Matriz[i][Coluna] + 30;
}
Criar uma matriz identidade
void CriaIdent(int Colunas, int linhas, int
Matriz[NLIN][NCOL])
{
}
Criar uma matriz transposta
void CriaTransp(int Colunas, int linhas,
int Matriz[NLIN][NCOL], int
Trasposta[NLIN][NCOL])
{
}
Cria uma rotina que some duas matrizes
void SomaMatrizes(int Colunas, int linhas,
int MatrizA[NLIN][NCOL], int
MatrizB[NLIN][NCOL],
int MatrizSOMA[NLIN][NCOL])
{
}
Cria uma rotina que multiplique duas matrizes
void MultMatrizes(int Colunas, int linhas,
int MatrizA[NLIN][NCOL], int
MatrizB[NLIN][NCOL],
int MatrizMULT[NLIN][NCOL])
{
}
Exerccios
1. Dada uma seqncia de n nmeros, imprimi-la na ordem inversa da
leitura.
#include
#include
#include
#define MAX 100
int main() {
int n, i, v[MAX];
printf("Digite o comprimento da seqncia: ");
scanf("%i", &n);
printf("Digite uma seqncia com %d nmeros inteiros: ", n);
for (i = 0; i < n; i++)
scanf("%i", &v[i]);
for (i = n-1; i >= 0; i--)
printf("%d ", v[i]);
printf("\n");
system(pause);
}