Prévia do material em texto
VARIÁVEIS COMPOSTAS HOMOGÊNEAS
Vimos ser possível dar um nome para uma posição de memória, sendo que a esta será
associado um valor qualquer. Pois bem, acontece que, muitas vezes, esta forma de definição, ou
melhor, de alocação de memória, não é suficiente para resolver certos problemas computacionais.
Imagine por exemplo, o seguinte problema: dada uma relação de 5 estudantes, imprimir o
nome de cada estudante, cuja nota é maior do que a média da turma. Um algoritmo simples para
resolver esse problema poderia ser o código apresentado abaixo.
1. #include
2. #include
3. int main()
4. {
5. char nome1[80], nome2[80], nome3[80], nome4[80], nome5[80];
6. float nota1, nota2, nota3, nota4, nota5;
7. float media;
8. printf("Digite o nome do aluno 1: ");
9. scanf("%s", &nome1);
10. printf("Digite o nome do aluno 2: ");
11. scanf("%s", &nome2);
12. printf("Digite o nome do aluno 3: ");
13. scanf("%s", &nome3);
14. printf("Digite o nome do aluno 4: ");
15. scanf("%s", &nome4);
16. printf("Digite o nome do aluno 5: ");
17. scanf("%s", &nome5);
18. printf("Digite a nota do aluno 1: ");
19. scanf("%f", ¬a1);
20. printf("Digite a nota do aluno 2: ");
21. scanf("%f", ¬a2);
22. printf("Digite a nota do aluno 3: ");
23. scanf("%f", ¬a3);
24. printf("Digite a nota do aluno 4: ");
25. scanf("%f", ¬a4);
26. printf("Digite a nota do aluno 5: ");
27. scanf("%f", ¬a5);
28. media = (nota1+nota2+nota3+nota4+nota5)/5.0;
29. if (nota1>=media)
30. printf("%s\n", nome1);
31. if (nota2>=media)
32. printf("%s\n", nome2);
33. if (nota3>=media)
34. printf("%s\n", nome3);
35. if (nota4>=media)
36. printf("%s\n", nome4);
37. if (nota5>=media)
38. printf("%s\n", nome5);
39. return 0;
40. }
O algoritmo acima representa uma solução possível para o problema. O grande
inconveniente dessa solução é a grande quantidade de variáveis para gerenciarmos e o uso repetido
de comandos praticamente idênticos.
Agora imagine se tivéssemos, ao invés de 5, 100 estudantes. Expandir o algoritmo anterior
para trabalhar com um total de 100 alunos significaria, basicamente, aumentar o número de
variáaveis para guardar os dados de cada aluno e repetir, ainda mais, um conjunto de comandos
praticamente idênticos. Desse modo, teríamos:
#include
#include
int main()
{
char nome1[80], nome2[80], nome3[80], ....., nome100[80];
float nota1, nota2, nota3, ....., nota100;
float media;
printf("Digite o nome do aluno 1: ");
scanf("%s", &nome1);
printf("Digite o nome do aluno 2: ");
scanf("%s", &nome2);
.
.
.
printf("Digite o nome do aluno 100: ");
scanf("%s", &nome100);
printf("Digite a nota do aluno 1: ");
scanf("%f", ¬a1);
printf("Digite a nota do aluno 2: ");
scanf("%f", ¬a2);
.
.
.
printf("Digite a nota do aluno 100: ");
scanf("%f", ¬a100);
media = (nota1+nota2+.....+nota100)/100.0;
if (nota1>=media)
printf("%s\n", nome1);
if (nota2>=media)
printf("%s\n", nome2);
.
.
.
if (nota100>=media)
printf("%s\n", nome100);
return 0;
}
Como se pode notar, temos uma solução extremamente engessada para o nosso problema.
Modificar o número de alunos usado pelo algoritmo implica em reescrever todo o código, repetindo
comandos praticamente idênticos. Além disso, temos uma grande quantidade de variáveis para
gerenciar, cada uma com o seu próprio nome, o que torna essa tarefa ainda mais difícil de ser
realizada sem a ocorrência de erros.
Como estes dados têm uma relação entre si, pode-se declará-los usando um único nome
para todos os 100 elementos. Assim, foi criado um novo conceito para alocação de memória sendo,
desta forma, também criado uma nova maneira de definir variáveis, a qual foi denominada de
variável composta indexada.
Uma variável indexada corresponde a uma sequência de posições de memória, a qual
daremos um único nome, sendo que cada uma destas pode ser acessada através do seu índice, que
corresponde a um valor numérico inteiro. Cada uma das posições de memória de uma variável
indexada pode receber valores no decorrer do algoritmo como se fosse uma variável comum – a
única diferença reside na sintaxe de utilização desta variável.
As variáveis compostas homogêneas permitem agrupar diversas informações dentro de uma
mesma variável. Este agrupamento ocorrerá obedecendo sempre ao mesmo tipo de dado, razão
pela qual tais estruturas são chamadas homogêneas.
A utilização deste tipo de dado recebe diversos nomes, como: variáveis indexadas, variáveis
compostas, variáveis subscritas, arranjos, vetores, matrizes, tabelas em memória ou arrays.
Exemplos:
V = 4 7 2 5 3 M = 3 8 1 5 0
0 1 2 3 4 0 2 4 7 1
2 5 9 3 2
0 1 2 3
Cada elemento dos arrays pode ser referenciado através de seus índices. Observe:
V[0] = 4 M[0,0] = 3
V[1] = 7 M[1,2] = 4
V[4] = 3 M[2,0] = 2
1. ARRAY DE UMA DIMENSÃO – VETOR
Um array de uma dimensão, ou vetor, é a forma mais comum de dados estruturados da
linguagem C. Um vetor é simplesmente um conjunto de variáveis do mesmo tipo, igualmente
acessíveis por um índice. A ideia de um vetor é bastante simples: criar um conjunto de variáveis do
mesmo tipo utilizando apenas um nome.
Relembrando o exemplo anterior, onde as variáveis que guardam as notas dos 100 alunos
são todas do mesmo tipo, essa solução permitiria usar apenas um nome (notas, por exemplo) de
variável para representar todas as notas dos alunos, ao invés de um nome para cada variável.
1.1. DECLARAÇÃO DE VETOR
Em linguagem C, a declaração de um vetor possui a seguinte sintaxe básica:
tipo_de_dado nome_do_array[tamanho];
Onde:
• tipo de dado → tipo de dado de cada elemento do vetor;
• nome do array → identificador do vetor;
• [tamanho] → número de elementos do vetor.
Pensando no exemplo anterior, poderíamos usar um vetor de reais contendo 100 elementos
para guardar as notas dos 100 alunos. Ele poderia ser declarado como mostrado abaixo:
float notas[100];
1.2. ACESSO À ELEMENTOS DO VETOR
Como a variável que armazena a nota de um aluno possui agora o mesmo nome que as
demais notas dos outros alunos, o acesso ao valor de cada nota é feito utilizando um índice, como
mostrado abaixo.
notas 7.4 4.3 10.0 9.5 ........ 5.2
0 1 2 3 99
Note que na posição “0” do array está armazenado o valor “7.4”, na posição “1” está
armazenado o valor “4.3”, e assim por diante. Para indicar qual índice do vetor se quer acessar,
utiliza-se o operador de colchetes [ ]: notas[índice].
Observe o exemplo abaixo.
1. #include
2. #include
3. int main()
4. {
5. float notas[10];
6. int i;
7. for (i=0; iagrupamento de dados, do mesmo tipo,
adjacentes na memória. O nome do vetor indica onde esses dados começam na memória. O índice
do vetor indica quantas posições se deve pular para acessar uma determinada posição. A figura
abaixo exemplifica como um vetor está disposto na memória.
Memória
# var conteúdo
123 notas 7.4 notas[0]
124 notas 4.3 notas[1]
125 notas 10.0 notas[2]
126 notas 9.5 notas[3]
127 .....
.
.
Em um vetor de 100 elementos, índices menores do que 0 e maiores do que 99 também
podem ser acessados. Porém, isto pode resultar nos mais variados erros durante a execução do
programa.
Como já foi dito, um vetor é um agrupamento de dados adjacentes na memória e o seu índice
apenas indica quantas posições se deve pular para acessar uma determinada posição. Isso significa
que se tentarmos acessar o índice 100, o programa tentará acessar a centésima posição a partir da
posição inicial. O mesmo vale para a posição de índice -1. Nesse caso o programa tentará acessar
uma posição anterior ao local onde o vetor começa na memória. O problema é que, apesar dessas
posições existirem na memória e serem acessíveis, elas não pertencem ao vetor ou podem ainda
pertencer a outras variáveis do programa, e a alteração de seus valores pode resultar nos mais
variados erros durante a execução do programa. Portanto, é função do programador garantir que
os limites do vetor sejam respeitados.
1.3. OPERAÇÕES BÁSICAS COM VETORES
Do mesmo modo que acontece com variáveis simples, também é possível operar com
variáveis indexadas. Contudo não é possível operar diretamente com o conjunto completo, mas com
cada um de seus componentes isoladamente.
O acesso individual a cada componente de um vetor é realizado pela especificação de sua
posição no mesmo por meio do seu índice.
Suponha que exista uma variável composta v capaz de armazenar 5 números inteiros. Para
acessar um elemento deste vetor deve-se fornecer o nome do mesmo e o índice do componente
desejado do vetor (um número de 0 a 4, neste caso). Por exemplo, v[0] indica o primeiro elemento
do vetor, v[1] indica o segundo elemento do vetor e v[9] indica o último elemento do vetor.
Observe o exemplo abaixo, onde se declara duas variáveis composta v e v1.
1. #include
2. #include
3. int main()
4. {
5. int v[5] = {1,2,3,4,5};
6. int v1[5];
7. v1 = v; */ INCORRETO
8. return 0;
9. }
Assim, não é possível operar diretamente sobre vetores como um todo, mas apenas sobre
seus componentes, um por vez. Isso ocorre porque a linguagem C não suporta a atribuição de um
vetor para outro. Para atribuir o conteúdo de um vetor a outro vetor, o correto é copiar seus valores
elemento por elemento para o outro vetor.
Por exemplo, para somar dois vetores é necessário somar cada um de seus componentes
dois a dois. Da mesma forma, as operações de atribuição, leitura e escrita de vetores devem ser
feitas elemento a elemento. Para se realizar essa tarafa, a utilização de uma estrutura iterativa em
conjunto com arrays é muito comum. De fato, esta construção é muito utilizada quando se opera
com vetores, devido à necessidade de se realizar uma mesma operação com os diversos
componentes dos mesmos. Na verdade, são raras as situações que se deseja operar isoladamente
com um único componente do vetor.
Observe o exemplo abaixo:
1. #include
2. #include
3. int main()
4. {
5. int v[5] = {1,2,3,4,5};
6. int v1[5];
7. int i;
8. for (i=0; i
2. #include
3. int main()
4. {
5. int m[2][2] = {1,2,3,4};
6. int m1[2][2];
7. m1 = m; */ INCORRETO
8. return 0;
9. }
mat[0][1]
Assim, não é possível operar diretamente sobre matrizes como um todo, mas apenas sobre
seus componentes, um por vez. Por exemplo, para somar duas matrizes é necessário somar cada
um de seus componentes dois a dois. Da mesma forma, as operações de atribuição, leitura e escrita
de matrizes devem ser feitas elemento a elemento.
Para se realizar essa tarafa, a utilização de uma estrutura iterativa em conjunto com arrays
é muito comum. De fato, esta construção é muito utilizada quando se opera com matrizes, devido
à necessidade de se realizar uma mesma operação com os diversos componentes das mesmas. Na
verdade, são raras as situações que se deseja operar isoladamente com um único componente da
matriz.
Observe o exemplo abaixo:
1. #include
2. #include
3. int main()
4. {
5. int m[2][2] = {1,2,3,4};
6. int m1[2][2];
7. int i,j;
8. for (i=0; i3. ARRAY DE MÚLTIPLAS DIMENSÕES
Vimos até agora como criar arrays com uma ou duas dimensões. A linguagem C permite que
se crie arrays com mais de duas dimensões de maneira bem fácil.
Na linguagem C, cada conjunto de colchetes [] representa uma dimensão do array. Cada
par de colchetes adicionado ao nome de uma variável durante a sua declaração adiciona uma nova
dimensão àquela variável, independente do seu tipo.
Observe:
float n[5]; // 1 dimensão
float o[4][5]; // 2 dimensões
float p[3][4][5]; // 3 dimensões
float q[2][3][4][5]; // 4 dimensões
A utilidade de arrays multidimensionais é muito grande. No exemplo acima, cada array pode
ser utilizada para armazenar uma quantidade maior de informações. Por exemplo:
✓ o array n pode ser utilizado para armazenar 5 notas de um aluno;
✓ o array o pode ser utilizado para armazenar 5 notas de 4 alunos;
✓ o array p pode ser utilizado para armazenar 5 notas de 4 alunos de 3 disciplinas;
✓ o array q pode ser utilizado para armazenar 5 notas de 4 alunos de 3 disciplinas, de 2
turmas.
A figura abaixo ilustra o array p definido anteriormente:
O acesso ao valor de uma posição de um array multidimensional é feito utilizando um índice
para cada dimensão do array. Observe o exemplo abaixo.
1. #include
2. #include
3. int main()
4. {
5. float p[3][4][5];
6. int i,j,k;
7. for (i=0; i
#include
int main()
{
int v[5]= {5,10,15,20,25};
int i;
for (i=0; i
#include
int main()
{
int v[5];
int i;
v[0]=5;
v[1]=10;
v[2]=15;
v[3]=20;
v[4]=25;
for (i=0; i
2. #include
3. int main()
4. {
5. int mat1[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
6. int mat2[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
7. char str1[10] = {'J','o','ã','o','\0'};
8. char str2[10] = "João";
9. char strmat[3][10] = {"João","Pedro","Edwar"};
10. system("pause");
11. return 0;
12. }
Note no exemplo acima que a inicialização de um array de duas dimensões pode ser feita de
duas formas distintas. Na primeira matriz (mat1) os valores iniciais são definidos utilizando um único
conjunto de chaves, igual ao que é feito com vetores. Nesse caso, os valores são atribuídos para
todas as colunas da primeira linha da matriz, para depois passar para as colunas da segunda linha e
assim por diante. Lembre-se que a dimensão que se move mais rapidamente na memória é sempre
a mais à direita, independente do tipo ou número de dimensões do array. Já na segunda matriz
(mat2) usa-se mais de um conjunto de chaves para definir cada uma das dimensões da matriz.
Para a inicialização de um array de caracteres, pode-se usar o mesmo princípio definido na
inicialização de vetores, como foi feito com str1. Percebe-se que essa forma de inicializaçã não é
muito prática. Por isso, a inicialização de um array de caracteres também pode ser feita por meio
de “aspas duplas”, como mostrado na inicialização de str2. O mesmo princípio é válido para iniciar
um array de caracteres de mais de uma dimensão. Vale ressaltar que, na inicialização de um array
de caracteres não é necessário definir todos os seus elementos.
4.1. INICIALIZAÇÃO SEM TAMANHO
A linguagem C também permite inicializar um array sem que tenhamos definido o seu
tamanho. Nesse caso, simplesmente não se coloca o valor do tamanho entre os colchetes durante
a declaração do array, como mostrado abaixo:
tipo_de_dado nome_do_array[] = {dados};
Nesse tipo de inicialização, o compilador da linguagem C vai considerar o tamanho do dado
declarado como sendo o tamanho do array. Isto ocorre durante a compilação do programa. Depois
disso, o tamanho do array não poderá mais ser modificado durante o programa.
Observe abaixo um exemplo de inicialização de arrays sem tamanho.
1. #include
2. #include
3. int main()
4. {
5. char texto[] = "Linguagem C.";
6. int vetor[] = {1,2,3,4,5,6,7,8,9,10};
7. int matriz[][2] = {1,2,3,4,5,6,7,8,9,10};
8. system("pause");
9. return 0;
10. }
Note no exemplo acima que foram utilizados 12 caracteres para iniciar o array texto.
Porém, o seu tamanho final será 13. Isso ocorre por que arrays de caracteres sempre possuem o
elemento seguinte ao último caractere como sendo o caractere ‘\0’. Mais detalhes sobre isso será
abordados na próxima seção. Esse tipo de inicialização é muito útil quando não queremos contar
quantos caracteres serão necessários para inicializarmos uma string (array de caracteres).
No caso da inicialização de arrays de mais de uma dimensão, é necessáriosempre definir as
demais dimensões, como pode ser visto na linha 07. Apenas a primeira dimensão pode ficar sem
tamanho definido.
4.2. ARRAY DE TAMANHO VARIÁVEL
Na linguagem C, todos os arrays têm um tamanho fixo, e que não pode variar durante a
execução do programa. Mas como proceder quando o tamanho do array não pode ser previsto até
o momento da execução?
Considere um programa que lê n valores e os armazena em um array. O valor n é informado
pelo usuário durante a execução do programa. A linguagem C não oferece recursos para se declarar
um array cujo tamanho se ajuste automaticamente ao número n de elementos.
A solução mais simples é declarar o array com o tamanho máximo necessário para tratar o
pior caso. O número de elementos realmente utilizado ficará armazenado em uma outra variável.
Uma abordagem mais flexível pode ser conseguida utilizando-se alocação dinâmica de memória,
mas esta é uma técnica mais complexa.
Continuando o exemplo, vamos supor que foi utilizado algum critério para descobrir que o
array nunca precisará armazenar mais do que 100 elementos.
int valores[100];
int nro_elementos;
Para imprimir todos os elementos do array, procedemos como antes, utilizando uma
estrutura de repetição. Mas, ao invés de utilizar o tamanho máximo como condição de parada,
comparamos o índice com o tamanho dado pela variável nro_elementos.
for (i=0; i
2. #include
3. int main()
4. {
5. int valores[100];
6. int nro_elementos;
7. int i;
8. printf("Digite a quantidade de valores? (máximo 100): ");
9. scanf("%d", &nro_elementos);
10. if ((nro_elementos>100) || (nro_elementos=0; i--)
22. {
23. printf("%d ", valores[i]);
24. }
25. return 0;
26. }
A variável valores é declarada como um vetor de 100 elementos de tipo inteiro. Ela
armazenará os valores digitados pelo usuário. A variável nro_elementos armazena quantos
elementos do vetor estão realmente sendo utilizados para armazenar os valores digitados pelo
usuário. A declaração cria uma variável contadora para o laço for de leitura e o laço for de escrita
de valores.
Nas linhas 08 e 09, o programam pede ao usuário para informar de quantos elementos
consiste a lista de números. Esse valor será armazenado na variável nro_elementos e passará a
controlar o número de repetições do laço for.
Nas linhas 10 a 14, é feita a verificação se o número de elementos que o usuário digitou está
dentro do limite suportado pelo programa. Esta verificação é essencial para garantir que nenhuma
operação de indexação do vetor seja realizada com índice maior que a capacidade do vetor, ou com
índice negativo, o que poderia comprometer a integridade do programa.
A estrutura de repetição for (linhas 16 a 19) é executada nro_elementos vezes, variando
o conteúdo de i de 0 até nro_elementos-1. A cada repetição, o comando scanf lê um número
inteiro e o armazena no i-ésimo elemento do vetor valores. Note que tal como no scanf para
variáveis comuns, o nome do vetor é precedido pelo símbolo &.
O vetor contém nro_elementos números lidos no laço for anterior. Agora, vamos usar
novamente a estrutura de repetição for (linhas 21 a 24) para imprimir o vetor de trás para frente.
Por este motivo, fazemos o índice i variar de nro_elementos-1 para 0.
5. ARRAYS DE CARACTERES – STRINGS
String é o nome que usamos para definir uma sequência de caracteres adjacentes na
memória do computador. Essa sequência de caracteres, que pode ser uma palavra ou frase, é
armazenada na memória do computador na forma de um array do tipo char.
Sendo a string um array de caracteres, sua declaração segue as mesmas regras da declaração
de um array convencional, como mostrado abaixo:
char str[6];
A declaração acima cria na memória do computador uma string (array de caracteres) de
nome str e tamanho igual a 6. No entanto, apesar de ser um array, devemos ficar atentos para o
fato de que as strings têm no elemento seguinte à última letra da palavra ou frase armazenada, um
caractere ‘\0’.
O caractere ‘\0’ indica o fim da sequência de caracteres. Isso ocorre por que podemos definir
uma string com um tamanho maior do que a palavra armazenada. Imagine uma string definida com
um tamanho de 50 caracteres, mas utilizada apenas para armazenar a palavra “oi”. Nesse caso,
temos 48 posições não utilizadas e que estão preenchidas com lixo de memória (um valor qualquer).
Obviamente, não queremos que todo esse lixo seja considerado quando essa string for exibida na
tela. Assim, o caractere ‘\0’ indica o fim da sequência de caracteres e o início das posições restantes
da nossa string que não estão sendo utilizadas nesse momento.
o i \0 ? ã # 3 t ..... @
0 1 2 3 4 5 6 7 49
Ao definir o tamanho de uma string, devemos sempre considerar o caractere ‘\0’. Como o
caractere ‘\0’ indica o final de nossa string, isso significa que numa string definida com um tamanho
de 50 caracteres, apenas 49 estarão disponíveis para armazenar o texto digitado pelo usuário.
5.1. INICIALIZAÇÃO DE STRINGS
Uma string pode ser lida do teclado ou já ser definida com um valor inicial. Para sua
inicialização, pode-se usar o mesmo princípio definido na inicialização de vetores e matrizes.
char str[10] = {’G’,’u’,’s’,’t’,’a’,’v’,’o’,’\0’};
Percebe-se que essa forma de inicialização não é muito prática. Por isso, a inicialização de
strings também pode ser feita por meio de “aspas duplas”, como mostrado abaixo.
char str[10] = “Gustavo”;
Essa forma de inicialização possui a vantagem de já inserir o caractere ‘\0’ no final da string.
5.2. ACESSO À ELEMENTOS DE STRINGS
Outro ponto importante na manipulação de strings é que, por se tratar de um array, cada
caractere pode ser acessado individualmente por indexação como em qualquer outro vetor ou
matriz.
char str[10] = “Teste”;
str[0] = ’L’;
str = T e s t e \0
0 1 2 3 4 5 6 7 8 9
str = L e s t e \0
0 1 2 3 4 5 6 7 8 9
Vale ressaltar que, na atribuição de strings usa-se “aspas duplas”, enquanto que na
atribuição de caracteres, usa-se ’aspas simples’.
5.3. MANIPULAÇÃO DE STRINGS
O primeiro cuidado que se deve ter ao se trabalhar com strings é na operação de atribuição.
Strings são arrays. Portanto, não se pode fazer atribuição de strings. Observe o exemplo abaixo:
1. #include
2. #include
3. int main()
4. {
5. char str1[20] = "Olá pessoal!";
6. char str2[20];
7. str1 = str2; //INCORRETO
8. system("pause");
9. return 0;
10. }
Isso ocorre porque uma string é um array e a linguagem C não suporta a atribuição direta de
um array para outro. Para atribuir o conteúdo de uma string a outra, o correto é copiar a string
elemento por elemento para a outra string. Observe o exemplo abaixo:1. #include
2. #include
3. int main()
4. {
5. char str1[20] = "Olá pessoal!";
6. char str2[20];
7. int i;
8. for (i=0; str1[i]!=’\n’; i++)
9. {
10. str2[i] = str1[i];
11. }
12. str2[i] = ‘\0’;
13. system("pause");
14. return 0;
15. }
O exemplo acima permite copiar uma string elemento por elemento para outra string. Note
que foi utilizada a mesma forma de indexação que seria feita com um array de qualquer outro tipo.
Infelizmente, esse tipo de manipulação de arrays não é muito prático quando estamos trabalhando
com palavras.
Felizmente, a biblioteca padrão da linguagem C possui funções especialmente desenvolvidas
para a manipulação de strings na arquivo .
5.3.1. LEITURA DE STRINGS
Utilizando a função scanf()
Existem várias maneiras de se fazer a leitura de uma sequência de caracteres do teclado.
Uma delas é utilizando a já conhecida função scanf() com o código de controle “%s”, como
mostrado abaixo.
char str[20];
scanf(“%s”,str);
Quando usamos a função scanf() para ler uma string, o símbolo de & antes do nome da
variável não é utilizado. Os colchetes também não são utilizados pois queremos ler a string toda e
não apenas uma letra.
Infelizmente, para muitos casos, a função scanf() não é a melhor opção para se ler uma
string do teclado, pois a função scanf() lê apenas strings digitadas sem espaços, ou seja, palavras.
No caso de ter sido digitada uma frase (uma sequência de caracteres contendo espaços em branco),
apenas os caracteres digitados antes do primeiro espaço encontrado serão armazenados na string
se a sua leitura for feita com a função scanf().
Utilizando a função gets()
Uma alternativa mais eficiente para a leitura de uma string é a função gets(), que faz a
leitura do teclado considerando todos os caracteres digitados (incluindo os espaços em branco) até
encontrar um caractere de nova linha (ENTER).
char str[20];
gets(str);
Limpando o buffer do teclado
Às vezes, podem ocorrer erros durante a leitura de caracteres ou strings do teclado. Para
resolver esse pequenos erros, podemos limpar o buffer do teclado (entrada padrão) usando a
função setbuf(stdin, NULL) antes de realizar a leitura de caracteres ou strings. Observe o
exemplo abaixo.
leitura de caracteres leitura de strings
char ch;
setbuf(stdin, NULL);
scanf(“%c”, &ch);
char str[10];
setbuf(stdin, NULL);
gets(str);
Basicamente, a função setbuf() preenche um buffer (primeiro parâmetro) com um
determinado valor (segundo parâmetro). No exemplo acima, o buffer da entrada padrão (stdin), ou
seja, o teclado, é preenchido com o valor vazio (NULL). Na linguagem C a palavra NULL é uma
constante padrão que significa um valor nulo. Um buffer preenchido com NULL é considerado
limpo/vazio.
Além disso, uma outra função que também faz a limpeza do buffer do teclado é a função
fflush(). A sintaxe básica para essa função é a seguinte:
fflush(stdin)
Observe o exemplo abaixo:
1. #include
2. #include
3. int main()
4. {
5. int cpf;
6. char nome[80];
7. int idade;
8. char end[100];
9. printf("Digite o CPF: ");
10. scanf(" %d", &cpf);
11. printf("Digite o nome: ");
12. setbuf(stdin, NULL);
13. gets(nome);
14. printf("Digite a idade: ");
15. scanf(" %d", &idade);
16. printf("Digite o endereço: ");
17. fflush(stdin);
18. gets(end);
19. system("pause");
20. return 0;
21. }
Observe no exemplo acima, o uso da função setbuf(), na linha 12, e fflush(), na linha
17. Como parâmetros dessas funções, pode-se ter o buffer da entrada padrão (stdin) – o teclado,
ou o buffer da saída padrão (stdout) – o monitor.
5.3.1. ESCRITA DE STRINGS
Utilizando a função printf()
Basicamente, para se escrever uma string na tela utilizamos a função printf() com o
código de controle “%s”. Os colchetes não são utilizados pois queremos escrever a string toda e não
apenas uma letra. Observe o exemplo abaixo.
char str[20] = “Hello World”;
printf(“%s”,str);
Utilizando a função puts()
Uma alternativa mais eficiente para a escrita de uma string é a função puts(), que faz a
escrita na tela de saída de uma string armazenada em uma variável.
char str[10];
puts(“Digite uma palavra: ”);
gets(str);
puts(“A palavra digitada foi: ”);
puts(str);
Vale ressaltar que a função puts() só aceita um único argumento. Assim, o exemplo abaixo
estaria incorreto. Observe:
char str[10];
puts(“Digite uma palavra: ”);
gets(str);
puts(“A palavra digitada foi: ”, str); //INCORRETO
5.4. FUNÇÕES PARA MANIPULAÇÃO DE STRINGS
A biblioteca padrão da linguagem C possui funções especialmente desenvolvidas para a
manipulação de strings no arquivo . Observe a seguir, algumas das funções mais
utilizadas.
5.4.1. TAMANHO DE STRING
Para se obter o tamanho de uma string, utiliza-se a função strlen():
char str[15] = “teste”;
printf(“%d”,strlen(str));
Neste caso, a função retornará 5, que é o número de caracteres na palavra “teste” e não 15,
que é o tamanho do array de caracteres. A função strlen() retorna o número de caracteres até
o caractere ‘\0’, e não o tamanho do array onde a string está armazenada.
5.4.2. CÓPA DE STRING
Uma string é um array e a linguagem C não suporta a atribuição de um array para outro.
Nesse sentido, a única maneira de atribuir o conteúdo de uma string a outra é a cópia, elemento
por elemento, de uma string para outra. A linguagem C possui uma função que realiza essa tarefa:
a função strcpy().
strcpy(char destino, char origem)
Basicamente, a função strcpy() copia a sequência de caracteres contida em origem para
o array de caracteres destino. Observe o exemplo abaixo:
1. #include
2. #include
3. #include
4. int main()
5. {
6. char str1[100], str2[100];
7. printf("Digite uma string: ");
8. gets(str1);
9. strcpy(str2, str1);
10. puts(str2);
11. system("pause");
12. return 0;
13. }
Vale ressaltar que, para evitar estouro de buffer, o tamanho do array destino deve ser longo
o suficiente para conter a sequência de caracteres contida em origem.
5.4.3. CONCATENAÇÃO DE STRINGS
A operação de concatenação é outra tarefa bastante comum ao se trabalhar com strings.
Basicamente, essa operação consiste em copiar uma string para o final de outra string. Na linguagem
C, para se fazer a concatenação de duas strings, utiliza-se a função strcat().
strcat(char destino, char origem)
Basicamente, a função strcat() copia a sequência de caracteres contida em origem para
o final da string destino. O primeiro caractere da string contida em origem é colocado no lugar do
caractere ‘\0’ da string destino. Observe o exemplo abaixo
1. #include
2. #include
3. #include
4. int main()
5. {
6. char str1[15] = "Boa ";
7. char str2[15] = "Noite";
8. strcat(str1, str2);
9. puts(str1);
10. system("pause");
11. return 0;
12. }
Vale ressaltar que, para evitar estouro de buffer, o tamanho do array destino deve ser longo
o suficiente para conter a sequência de caracteres contida em ambas as strings: origem e destino.
5.4.4. COMPARAÇÃO DE STRINGS
Da mesma maneira como o operador de atribuição não funciona para strings, o mesmo
ocorre com operadores relacionais usados para comparar duas strings. Desse modo, para saber se
duas strings são iguais, utiliza-se a função strcmp().
int strcmp(char str1, char str2)
A função strcmp() compara posição a posição as duas strings (str1 e str2) e retorna um
valor inteiro igual a zero no caso das duas strings serem iguais. Um valor de retorno diferente de
zero significa que as strings são diferentes. Observe o exemplo abaixo:
1. #include
2. #include3. #include
4. int main()
5. {
6. char str1[100], str2[100];
7. printf("Digite uma string: ");
8. gets(str1);
9. printf("Digite uma outra string: ");
10. gets(str2);
11. if (strcmp(str1,str2)==0)
12. printf("As duas strings são iguais.\n");
13. else
14. printf("As duas strings são diferentes.\n");
15. system("pause");
16. return 0;
17. }
A função strcmp() é case-sensitive. Isso significa que letras maiúsculas e minúsculas
tornam as strings diferentes.
5.4.5. CONVERSÃO DE STRING PARA NUMÉRICO
Existem duas funções que recebem uma cadeia de caracteres que representa um número e
a converte no número correspondente.
A função atoi() (alphanumeric to integer) recebe uma cadeia de caracteres que representa
um número inteiro em notação decimal e a converte no número inteiro correspondente. Sua forma
geral é:
var_int = atoi(string);
De forma similar, a função atof() (alphanumeric to float) recebe uma cadeia de caracteres
que representa um número real em notação decimal e a converte no número real (do tipo double)
correspondente. Sua forma geral é:
var_double = atof(string);
Observe abaixo um exemplo de sua utilização.
1. #include
2. #include
3. int main()
4. {
5. char str1[2] = “12”;
6. char str2[4] = “2.14”;
7. double soma;
8. soma = atoi(str1) + atof(str2);
9. printf ("A soma das strings é %lf.",soma);
10. return 0;
11. }
Vale ressaltar que ambas as funções estão declaradas no arquivo .
5.5. VETORES DE STRINGS
Vetores de strings são matrizes bidimensionais. Isto porque uma string é um array de
caracteres. Dessa forma, ao utilizar um vetor de strings estaremos fazendo, na verdade, um vetor
de vetores, ou seja, uma matriz bidimensional do tipo char.
A forma geral de um vetor de strings pode ser dada da seguinte maneira:
char nome_da_variável [numero_de_strings][comprimento_das_strings];
Assim, para acessar uma única string, basta usar o primeiro índice, como mostrado abaixo.
printf(“%s”, nome_da_variável[índice]);
Observe abaixo um exemplo de um programa que lê 5 strings e as exibe na tela.
1. #include
2. int main()
3. {
4. char strings[5][100];
5. int i;
6. for (i=0; i