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

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 <string.h>

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:

int k;

for (k = 0; s[k] != '\0'; ++k) ;

return k;

unsigned int strlen( char *s) {

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-dedados 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<5; i++)
i<=4; i++)
Vetor[i] = 30;
= 30;
Colocar os nmeros de 1 a 5 em Vetor
for(i=0; i<5; i++)
Vetor[i] = i+1;
Colocar os nmeros de 5 a 1 em Vetor
for(i=0; i<5; i++)
Vetor[i] = 5-i;
Uso de Constantes para definir o tamanho de um vetor

for(i=0;
Vetor[i]

#define TAM_MAX 10
double VetReais[TAM_MAX];
for(i=0; i<TAM_MAX; i++)
VetReais[i] = TAM_MAX - i;
5,4,3,2,1 no vetor

// coloca

Copiar os dados de um vetor para outro


#define TAM_MAX 10
double VetReais[TAM_MAX], Copia[TAM_MAX];
for(i=0; i<TAM_MAX; i++)
VetCopia[i] = VetReais[i];
de um vetor

// Copia os dados
// para outro

Copiar os dados de um VET1 para as primeiras 5 posies de COPIA e


VET2 para as outras 5
#define TAM_MAX 10
// Note que a declarao do vetor "Cpia" cria o
dobro de posies
double Vet1[TAM_MAX], Vet2[TAM_MAX],
Copia[TAM_MAX*2];
for(i=0; i<TAM_MAX; i++)
VetCopia[i] = Vet1[i];
primeiro vetor

// Copia os dados do

for(i=0; i<TAM_MAX; i++)


// Copia os dados do
segundo vetor
VetCopia[i+TAM_MAX] = Vet2[i];
// ****** Pergunta: Como fazer a cpia usando um
nico comando for ?
Leitura dos dados de um um vetor
#define TAM_MAX 10
double Vet1[TAM_MAX];

for(i=0; i<TAM_MAX; i++)


scanf("%f",&Vet1[i]);
Encontrar o maior valor dentro de um vetor
#define TAM_MAX 10
double Vet1[TAM_MAX];
double Maior;
for(i=0; i<TAM_MAX; i++)
scanf("%f",&Vet1[i]);// le os

dados

Maior = Vet1[0]; // assume que o primeiro o


maior
for(i=0; i<TAM_MAX; i++)
if Vet1[i] > Maior
Maior = Vet1[i];
printf("O maior elemento %f\n",Maior);
// ****** Pergunta: Como fazer a mesma busca e
imprimir tambm a
// ****** posio do dado dentro do vetor. Tente
fazer isto usando
// ****** apenas 1 varivel.
Crie um programa que copie para um vetor os elementos de outro em
ordem crescente.
// a idia aqui encontrar o menor elemento do vetor 1 e colocar no vetor 2.
Tirar este nmero de vet1, por exemplo,
// colocando no seu lugar, no vetor 1, um nmero grande e recomear a busca
pelo novo nmero menor.
#define TAM_MAX 10
double Vet1[TAM_MAX], VetOrdenado[TAM_MAX];
double Menor, Maior;
for(i=0; i<TAM_MAX; i++)
scanf("%f",&Vet1[i]);// le os

dados

PosMaior = 0; // assume que o maior est na 1a.


posio
for(i=0; i<TAM_MAX; i++)

if Vet1[i] > Vet1[PosMaior]


PosMaior = i;
// acha a posio do maior
for(j=0; j<TAM_MAX;j++)
{
PosMenor = 0; // assume que o primeiro o
menor
for(i=0; i<TAM_MAX; i++)
if Vet1[i] < Vet1[PosMenor]
PosDoMenor = i;
VetOrdenado[j]= Vet1[PosMenor]; // copia menor
para o novo vetor
// inutiliza a posio do menor colocando nela um
nmero grande
Vet1[PosMenor] = Vet1[PosMaior]; // no caso o
maior do vetor
}
for(i=0; i<TAM_MAX; i++)
print("%f\n",VetOrdenado[i]);// Imprime
os
dados

Passagem de Matrizes e Vetores como Parmetro


Para passar uma matriz ou vetor como parmetro, basta declarar o
parmetro da mesma forma que a matriz foi declarada.
Um vetor sempre passado por referncia, logo, qualquer alterao em
seus elementos altera a varivel usada como parmetro na chamada da rotina.
#define TAM_MAX 10
void ImprimeVet (int Tam, int Vet[TAM_MAX])
{
int i;
for (i=0; i< Tam; i++)
{
printf("%d", Vet[i]);
}
}
void main()

{
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 usase 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 <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#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);
}

Вам также может понравиться