4. Vetores e Strings
4. Vetores e Strings¶
Na Seção 2.5 já demos uma primeira olhada em vetores. Neste capítulo vamos aprofundar em vetores e, principalmente, em como C representa strings — que, como você vai ver, não são um tipo à parte em C, e sim um caso particular de vetor.
Ainda sem ponteiros
Dá pra explicar bastante coisa sobre vetores e strings em C sem falar de ponteiros — e é isso que vamos fazer aqui, focando nas semelhanças e diferenças com o vetor/cadeia do VisuAlg e a list/str do Python. Só que algumas coisas em C (por que passar um vetor para uma função já altera o original? por que == não compara o conteúdo de duas strings?) só fazem sentido de verdade quando você entende ponteiros. Por enquanto vamos tratar esses comportamentos como fatos observáveis — "é assim que funciona" — e explicar o "porquê" no capítulo de ponteiros, quando vamos voltar a estes mesmos tópicos.
4.1. Vetores: inicializando e percorrendo¶
Como já vimos, um vetor em C tem tamanho fixo, definido na hora da declaração — nesse ponto ele é igual ao vetor do VisuAlg, e diferente da list do Python, que cresce e encolhe livremente.
Uma diferença que ainda não tínhamos visto: em C (e em Python) você pode declarar um vetor já inicializando todos os seus valores de uma vez, com uma lista entre chaves. O VisuAlg não tem essa opção — lá, você sempre inicializa posição por posição.
Se você inicializa um vetor em C com menos valores do que o tamanho declarado, o C completa o resto com zero — é a única forma de "zerar" um vetor inteiro de forma compacta, sem um laço:
Percorrer um vetor com um laço é basicamente igual nas três linguagens — só muda a sintaxe do for/para, que já vimos no Capítulo 2:
Repare no comentário na versão Python: para tarefas comuns como somar todos os elementos, Python tem funções prontas (sum, max, min, sorted, ...) que operam sobre a lista inteira de uma vez. Nem C nem VisuAlg têm esse tipo de função embutida para vetores — você sempre escreve o laço manualmente.
| Operação | C | VisuAlg | Python |
|---|---|---|---|
| tamanho fixo, definido na declaração | sim | sim | não (list cresce/encolhe) |
| inicializar com valores literais | {10, 20, 30} |
não existe — só posição por posição | [10, 20, 30] |
| adicionar elemento no fim | não existe | não existe | v.append(x) |
| somar/máx/mín "prontos" | não existe (laço manual) | não existe (laço manual) | sum(v), max(v), min(v) |
| índice do primeiro elemento | 0 |
0 (ou o que você declarar, ex. 1..N) |
0 |
Exercício de mapeamento 4.1
Em VisuAlg:
var
notas: vetor[0..4] de real
i: inteiro
maior: real
inicio
maior <- notas[0]
para i de 1 ate 4 faca
se (notas[i] > maior) entao
maior <- notas[i]
fimse
fimpara
escreval("Maior nota: ", maior)
Escreva o equivalente em C, considerando que o vetor notas já vem preenchido com 5 valores (por exemplo, inicializado como {7.5, 9.0, 6.0, 8.5, 10.0}).
4.2. Passando vetores para funções¶
Aqui vai um comportamento importante para observar, mesmo sem entender ainda o mecanismo por trás: em C, quando você passa um vetor como parâmetro para uma função e a função modifica os elementos do vetor, essa modificação é vista de volta na função que chamou — diferente do que acontece com um int ou um double passados normalmente.
#include <stdio.h>
void dobra(int v[], int tamanho) {
for (int i = 0; i < tamanho; i++) {
v[i] = v[i] * 2;
}
}
int main() {
int numeros[3] = {1, 2, 3};
dobra(numeros, 3);
printf("%d %d %d\n", numeros[0], numeros[1], numeros[2]); // 2 4 6
return 0;
}
Se isso te lembrou o comportamento de listas em Python, você não está enganado:
def dobra(v):
for i in range(len(v)):
v[i] = v[i] * 2
numeros = [1, 2, 3]
dobra(numeros)
print(numeros) # [2, 4, 6]
Em Python, uma função que recebe uma list e modifica seus elementos também altera a lista original — porque listas são um tipo mutável, e o que é passado para a função é uma referência à mesma lista, não uma cópia. Em C, algo parecido acontece com vetores (o motivo exato — que envolve ponteiros — fica para mais adiante).
Já em VisuAlg, o comportamento depende de como você declara o parâmetro: por padrão, um parâmetro é passado por valor (a função recebe uma cópia, e mudanças não voltam para quem chamou); para que a função possa alterar o vetor original, é preciso declarar o parâmetro com a palavra var:
procedimento dobra(var v: vetor[0..2] de inteiro)
var
i: inteiro
inicio
para i de 0 ate 2 faca
v[i] <- v[i] * 2
fimpara
fimprocedimento
Ou seja: em C esse comportamento de "referência" vem de graça para vetores, sem precisar escrever nada de especial; em VisuAlg você precisa pedir isso explicitamente com var. Guarde essa observação — ela vai fazer todo o sentido quando falarmos de ponteiros.
4.3. Strings em C: vetores de char¶
Aqui está a maior diferença entre C e as duas linguagens que você já conhece: C não tem um tipo string. O que existe é uma convenção: uma string é um vetor de char que termina com um caractere especial, '\0' (chamado de caractere nulo), marcando onde o texto acaba.
Essa linha cria um vetor de 20 posições e preenche as 7 primeiras com 'S', 'e', 'r', 'g', 'i', 'o', '\0' — o \0 é adicionado automaticamente pelo compilador porque usamos uma string literal ("Sergio") para inicializar. As outras 13 posições também recebem '\0': como vimos na Seção 4.1, quando um vetor é inicializado com menos valores do que o seu tamanho, C completa o resto com zero. De todo modo, qualquer função que trabalha com essa string para de ler no primeiro '\0', então o que vem depois dele nunca é usado.
Repare que o tamanho do vetor (aqui, 20) precisa ser maior do que o texto que você pretende guardar — sobrando pelo menos 1 posição para o \0. Isso não tem paralelo direto em Python ou VisuAlg, onde uma string simplesmente cresce e encolhe conforme o conteúdo, sem você se preocupar em reservar espaço.
C (char[]) |
VisuAlg (cadeia) |
Python (str) |
|
|---|---|---|---|
| é um tipo de verdade, ou é "só um vetor"? | é um vetor de char (convenção) |
tipo próprio | tipo próprio |
| precisa reservar tamanho manualmente | sim | não | não |
| marcador de fim de string visível | '\0' |
não existe (a linguagem cuida disso) | não existe (a linguagem cuida disso) |
| pode ser modificada depois de criada | sim (é um vetor comum) | sim | não — str é imutável em Python |
Ler uma string do teclado usa scanf com o especificador %s — e, diferente de outras variáveis, você não usa & antes do nome do vetor (mais um comportamento para anotar e entender de verdade só no capítulo de ponteiros):
scanf(\"%s\", ...) é perigoso
O scanf("%s", nome) não sabe que nome só tem 20 posições — se o usuário digitar um texto maior que isso, o scanf vai escrever além do fim do vetor, exatamente o tipo de comportamento sem checagem de limites que vimos na Seção 2.5. Uma forma mais segura é limitar o tamanho no próprio formato — scanf("%19s", nome) lê no máximo 19 caracteres, deixando espaço para o '\0' — ou ler a linha inteira com fgets, que respeita o tamanho do vetor e também aceita espaços (veja o fim da Seção 4.4).
4.4. Funções de string (<string.h>)¶
Como uma string em C é só um vetor de char, os operadores comuns não fazem o que você esperaria vindo de Python ou VisuAlg. Em particular:
O maior gotcha para quem vem de Python/VisuAlg
Em C, você não pode usar == para comparar o conteúdo de duas strings, e não pode usar = para copiar uma string em outra. Isso compila, mas não faz o que parece fazer — == compara onde os vetores estão na memória, não o que tem dentro deles. Para comparar ou copiar o conteúdo de verdade, C oferece funções prontas na biblioteca <string.h>.
#include <string.h>
char a[20] = "casa";
char b[20] = "casa";
if (a == b) { // ERRADO: dá falso, mesmo com o mesmo texto — a e b são vetores diferentes!
printf("iguais\n");
}
if (strcmp(a, b) == 0) { // CERTO: strcmp devolve 0 quando as strings são iguais
printf("iguais\n");
}
Em Python, a == b já compara o conteúdo das duas strings — é exatamente o que parece que deveria fazer. Em VisuAlg, a = b faz a mesma coisa. É só em C que você precisa de uma função à parte para isso.
| O que você quer fazer | C | VisuAlg | Python |
|---|---|---|---|
| tamanho da string | strlen(s) |
compr(s) |
len(s) |
| copiar o conteúdo | strcpy(destino, origem) |
destino <- origem |
destino = origem |
| concatenar (juntar) | strcat(destino, origem) |
destino <- destino + origem |
destino += origem |
| comparar conteúdo | strcmp(a, b) == 0 |
a = b |
a == b |
| pedaço da string (substring) | (precisa laço manual, ou funções de <string.h> mais avançadas) |
copia(s, inicio, tamanho) |
s[inicio:fim] |
char nome[30] = "Sergio";
char sobrenome[20] = " Costa";
strcat(nome, sobrenome); // nome agora contém "Sergio Costa"
printf("%s tem %zu letras\n", nome, strlen(nome)); // %zu: formato do tipo size_t, que strlen devolve
nome = "Sergio"
sobrenome = " Costa"
nome += sobrenome # nome agora contém "Sergio Costa"
print(nome, "tem", len(nome), "letras")
var
nome: cadeia
sobrenome: cadeia
inicio
nome <- "Sergio"
sobrenome <- " Costa"
nome <- nome + sobrenome
escreval(nome, " tem ", compr(nome), " letras")
fimalgoritmo
Note que strcat(nome, sobrenome) exige que o vetor nome já tenha espaço sobrando para caber o resultado da concatenação — se nome tivesse sido declarado com tamanho exato para "Sergio" (7 posições, contando o \0), o strcat escreveria além do fim do vetor. Mais um lugar onde C confia inteiramente em você para reservar espaço suficiente.
strcpy e strcat também não checam limites
Assim como o scanf("%s", ...) da Seção 4.3, nem strcpy nem strcat sabem o tamanho do vetor de destino — se a string de origem (ou o resultado da concatenação) não couber, eles escrevem além do fim do vetor sem avisar, o mesmo tipo de comportamento sem checagem de limites que vimos na Seção 2.5. Existem variantes mais seguras, como strncpy (que recebe um tamanho máximo) e snprintf, mas isso fica para mais adiante — por enquanto, o cuidado prático é sempre declarar o vetor de destino com folga suficiente.
Lendo uma linha inteira: fgets¶
O scanf("%s", ...) para de ler no primeiro espaço: se o usuário digitar Maria Silva, nome recebe só "Maria". Para ler a linha inteira — o que o input() do Python e o leia de uma cadeia no VisuAlg fazem naturalmente — C oferece a função fgets, também de <stdio.h>:
#include <stdio.h>
#include <string.h>
int main() {
char nome[30];
printf("Nome completo: ");
fgets(nome, sizeof nome, stdin); // lê no máximo 29 caracteres + o '\0'
nome[strcspn(nome, "\n")] = '\0'; // remove o '\n' do Enter, se houver
printf("Ola, %s! (%zu caracteres)\n", nome, strlen(nome));
return 0;
}
Os três parâmetros de fgets são o vetor de destino, o tamanho desse vetor e de onde ler (stdin é o teclado). Como recebe o tamanho, fgets nunca escreve além do fim do vetor: se a linha digitada for maior, ela lê só o que cabe e deixa o resto para a próxima leitura. (O sizeof nome dá o tamanho do vetor porque nome foi declarado nesta mesma função; dentro de uma função que o recebe como parâmetro isso não funciona mais — o porquê fica para o Capítulo 6.)
Diferente do input() do Python, fgets guarda o '\n' do Enter no fim da string, quando ele cabe. A segunda linha do exemplo o remove: strcspn(nome, "\n") devolve a posição do primeiro '\n' (ou o tamanho da string, se não houver nenhum), e trocar esse caractere por '\0' encurta a string ali.
Misturar scanf e fgets
Depois de um scanf("%d", &idade), o Enter que o usuário digitou continua no buffer de entrada. Um fgets logo em seguida lê esse Enter sozinho e devolve uma linha vazia, sem esperar o usuário. Para evitar isso, descarte o resto da linha antes do fgets:
| Quero ler... | C | VisuAlg | Python |
|---|---|---|---|
| uma palavra | scanf("%19s", s); |
leia(s) |
input().split()[0] |
| a linha inteira | fgets(s, sizeof s, stdin); + remover o '\n' |
leia(s) |
input() |
Exercício de mapeamento 4.2
Em Python:
usuario = input("Digite seu usuario: ")
senha = input("Digite sua senha: ")
if usuario == "admin" and senha == "1234":
print("Acesso permitido")
else:
print("Acesso negado")
Escreva o equivalente em C. Lembre-se: (1) strings em C precisam de um vetor de char com tamanho reservado, e (2) comparar strings exige strcmp, não ==. Se quiser, primeiro escreva a versão em VisuAlg como passo intermediário.
Dica, não gabarito
strcmp(usuario, "admin") == 0 é a forma de checar se usuario é igual a "admin". Para combinar as duas condições, você vai precisar do operador lógico "e" de C — reveja a Seção 2.1 se não lembrar qual é.
4.5. Vetores de strings¶
Assim como você pode ter um vetor de int ou de double, também é possível ter um vetor onde cada posição é uma string — útil, por exemplo, para guardar uma lista de nomes. Em C isso é declarado como uma matriz de char (um vetor de vetores de char): a primeira dimensão é "quantas strings", a segunda é "tamanho máximo de cada string".
char nomes[3][20] = {"Ana", "Bruno", "Carla"};
for (int i = 0; i < 3; i++) {
printf("%s\n", nomes[i]);
}
var
nomes: vetor[0..2] de cadeia
i: inteiro
inicio
nomes[0] <- "Ana"
nomes[1] <- "Bruno"
nomes[2] <- "Carla"
para i de 0 ate 2 faca
escreval(nomes[i])
fimpara
fimalgoritmo
Repare como, de novo, o Python é o único dos três que consegue inicializar a lista inteira com uma linha só (["Ana", "Bruno", "Carla"]) e nem precisa se preocupar com quantas letras cada nome tem — o VisuAlg pelo menos deixa você inicializar cada posição em uma linha; o C exige que você reserve, por adiantado, um tamanho máximo (20, no exemplo) para o maior nome que algum dia vai caber ali.
Exercício de mapeamento 4.3
Em VisuAlg:
var
cores: vetor[0..3] de cadeia
i: inteiro
inicio
cores[0] <- "vermelho"
cores[1] <- "verde"
cores[2] <- "azul"
cores[3] <- "amarelo"
para i de 0 ate 3 faca
se (compr(cores[i]) > 5) entao
escreval(cores[i])
fimse
fimpara
Esse trecho imprime as cores cujo nome tem mais de 5 letras. Escreva a versão em C (dica: qual das funções da tabela da Seção 4.4 substitui compr?).
4.6. Matrizes (vetores bidimensionais)¶
O vetor de strings da seção anterior já era, na verdade, um vetor de vetores: char nomes[3][20] são 3 vetores de 20 char. A mesma ideia vale para qualquer tipo, e é assim que C representa uma matriz — uma tabela com linhas e colunas.
int m[3][4]; // 3 linhas, 4 colunas: 12 inteiros
m[0][0] = 7; // linha 0, coluna 0
m[2][3] = 9; // última linha, última coluna
Assim como um vetor, uma matriz pode ser inicializada na declaração, agora com chaves aninhadas — uma lista por linha:
Para percorrer uma matriz, usamos dois laços aninhados: o de fora anda pelas linhas, o de dentro pelas colunas. O programa abaixo imprime a matriz e a soma de cada linha:
#include <stdio.h>
int main() {
int m[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
for (int i = 0; i < 2; i++) {
int soma = 0;
for (int j = 0; j < 3; j++) {
printf("%3d", m[i][j]);
soma += m[i][j];
}
printf(" | soma = %d\n", soma);
}
return 0;
}
algoritmo "matriz"
var
m: vetor[0..1, 0..2] de inteiro
i, j, soma: inteiro
inicio
// (preenchimento de m omitido)
para i de 0 ate 1 faca
soma <- 0
para j de 0 ate 2 faca
escreva(m[i, j]:3)
soma <- soma + m[i, j]
fimpara
escreval(" | soma = ", soma)
fimpara
fimalgoritmo
Duas diferenças de sintaxe para guardar: o VisuAlg declara as duas faixas de índice dentro de um único colchete e acessa com vírgula (m[i, j]); C e Python usam um par de colchetes por dimensão (m[i][j]). E em Python, cuidado ao criar uma matriz "vazia": [[0] * 3] * 2 cria duas referências para a mesma linha (alterar m[0][0] muda também m[1][0]); o jeito certo é [[0] * 3 for _ in range(2)]. Em C esse problema não existe: int m[2][3] = {0}; reserva as 6 posições, todas independentes e zeradas.
| C | VisuAlg | Python | |
|---|---|---|---|
| declarar 3×4 | int m[3][4]; |
m: vetor[0..2, 0..3] de inteiro |
m = [[0] * 4 for _ in range(3)] |
| acessar | m[i][j] |
m[i, j] |
m[i][j] |
| tamanho fixo | sim | sim | não |
Na memória, C guarda a matriz linha após linha, em um único bloco contínuo: em int m[3][4], o elemento m[i][j] fica na posição i * 4 + j desse bloco. É por isso que, ao passar uma matriz para uma função, o número de colunas precisa aparecer no parâmetro — sem ele, o compilador não saberia quantos elementos pular para chegar à linha seguinte. O número de linhas pode ficar em branco, como num vetor comum:
void imprime(int m[][4], int linhas) {
for (int i = 0; i < linhas; i++) {
for (int j = 0; j < 4; j++) {
printf("%3d", m[i][j]);
}
printf("\n");
}
}
Assim como um vetor, uma matriz passada para uma função não é copiada: alterações feitas dentro da função aparecem na matriz original (Seção 4.2).
Exercício de mapeamento 4.4
Em VisuAlg:
var
m: vetor[0..2, 0..2] de inteiro
i, soma: inteiro
inicio
// (preenchimento de m omitido)
soma <- 0
para i de 0 ate 2 faca
soma <- soma + m[i, i]
fimpara
escreval("Soma da diagonal: ", soma)
Escreva o equivalente em C, inicializando m na declaração com os valores de 1 a 9 (linha por linha). Depois, transforme o laço em uma função int soma_diagonal(int m[][3]).
4.7. Lista de exercícios¶
Vetores¶
- Leia um vetor
N[20], encontre o menor valor armazenado e a posição desse valor no vetor. - Leia um vetor
K[30]e troque todos os elementos de índice ímpar com o elemento par imediatamente posterior (posição 1↔2, 3↔4, 5↔6, e assim por diante, com cuidado para não sair dos limites do vetor). - Leia um vetor
S[20]e uma variávelA. Em seguida, imprima o produto de A por cada elemento do vetor (exemplo: seA = 2eS = {1, 2, 3}, a saída deve ser2, 4, 6). - Leia um vetor com 20 números inteiros e mostre: (a) todos os elementos; (b) quantos valores pares existem no vetor.
-
Dado o vetor
int vet[] = {7, 3, 1, 5, 13, 11, 9, 15};e o código abaixo:Sem executar, determine qual será a configuração final do vetor após a execução do código. 6. Faça um programa que leia N valores (N informado pelo usuário, até um máximo de 100), guarde-os em um vetor, e imprima: (a) o maior valor; (b) a média dos valores; (c) os valores em ordem crescente; (d) o subconjunto de valores primos contidos no vetor. 7. Faça um programa que preencha um vetor de inteiros com 10 posições e imprima: o maior elemento, o menor elemento, a soma de todos os elementos, e a média aritmética entre eles. 8. Faça um programa que, dadas duas matrizes A e B de dimensão 5×5 (Seção 4.6), calcule e imprima: (a) a soma das duas matrizes; (b) a soma dos elementos da diagonal principal de cada matriz; (c) o produto das duas matrizes. 9. Em um tabuleiro de xadrez 8×8, cada posição guarda um código:
0= ausência de peça,1= peão,2= cavalo,3= torre,4= bispo,5= rei,6= rainha. Leia um tabuleiro 8×8 (64 valores) para uma matrizint tabuleiro[8][8]e calcule: (a) a soma entre a quantidade de peões e de bispos; (b) a quantidade de posições sem peça alguma. 10. A tabela abaixo dá a distância, em km, entre 5 cidades:Cidade 1 Cidade 2 Cidade 3 Cidade 4 Cidade 5 Cidade 1 0 12 10 5 15 Cidade 2 12 0 10 28 20 Cidade 3 10 10 0 18 25 Cidade 4 5 28 18 0 22 Cidade 5 15 20 25 22 0 Guarde essa tabela em uma matriz
int dist[5][5]já inicializada no código (uma matriz literal, como vimos na Seção 4.6) e escreva um programa que: (a) leia pares de códigos de cidade (1 a 5) e informe a distância entre elas, repetindo até que o usuário digite 0 e 0; (b) dado um percurso informado como uma sequência de códigos de cidade (por exemplo,1 2 3 2 5 1 4), imprima a distância total percorrida, somando a distância entre cada cidade e a próxima da sequência. 11. Um cinema com capacidade para 20 lugares está sempre lotado. Em uma sessão, cada um dos 20 espectadores respondeu um questionário com sua idade e sua opinião sobre o filme (uma string:"otimo","bom","regular","ruim"ou"pessimo"). Leia esses 20 pares (idade, opinião) e calcule: (a) a quantidade de respostas"otimo"; (b) a diferença percentual entre respostas"bom"e"regular"; (c) a média de idade das pessoas que responderam"ruim"; (d) a maior idade entre quem respondeu"pessimo". Usestrcmppara comparar as opiniões — lembre-se de que==não funciona para strings, como vimos na Seção 4.4. 12. Considere o programa abaixo, que lê as notas de uma turma e calcula estatísticas:#include <stdio.h> int main(void) { int qtAlunos; printf("Quantidade de alunos: "); scanf("%d", &qtAlunos); float notas[100]; for (int i = 0; i < qtAlunos; i++) { printf("Nota (%d): ", i); scanf("%f", ¬as[i]); } float soma = 0; for (int i = 0; i < qtAlunos; i++) { soma = soma + notas[i]; } float media = soma / qtAlunos; float maior = notas[0]; for (int i = 1; i < qtAlunos; i++) { if (notas[i] > maior) maior = notas[i]; } float menor = notas[0]; for (int i = 1; i < qtAlunos; i++) { if (notas[i] < menor) menor = notas[i]; } float limiar; printf("Nota limiar: "); scanf("%f", &limiar); int conta = 0; for (int i = 0; i < qtAlunos; i++) { if (notas[i] > limiar) conta++; } printf("Media: %f\n", media); printf("Maior nota: %f\n", maior); printf("Menor nota: %f\n", menor); printf("Foram %d maiores que %f\n", conta, limiar); return 0; }Reescreva esse programa criando as seguintes funções (lembre-se da Seção 4.2: um vetor passado como parâmetro já permite que a função o acesse/altere):
int le_notas(float notas[], int max)— lê as notas do usuário e devolve quantas foram lidas.float media_notas(float notas[], int n)— devolve a média.float maior_nota(float notas[], int n)— devolve o maior valor.float menor_nota(float notas[], int n)— devolve o menor valor.int conta_acima(float notas[], int n, float limiar)— devolve quantos valores estão acima do limiar.
Strings¶
- Faça um programa que leia uma palavra (sem espaços) e conte quantas vogais ela tem.
- Faça um programa que leia uma palavra (sem espaços) e diga se ela é um palíndromo — isto é, se lida de trás para frente é igual à original (ex.:
"arara","osso"). - Faça um programa que detecte se uma frase é um palíndromo, ignorando espaços, o caractere hífen
-e a diferença entre maiúsculas e minúsculas (exemplos:"Socorram-me subi no onibus em Marrocos","Omitiram radar maritimo"). - Faça um programa que leia uma palavra e a imprima invertida (ex.: entrada
"programa", saída"amargorp"). - Baseado no exercício 13, mostre quantas vezes aparece cada vogal em uma frase, separando maiúsculas e minúsculas (exemplo, para
"Eu gosto de programar":a=2; e=1; i=0; o=3; u=1eA=0; E=1; I=0; O=0; U=0). - Implemente uma cifra de César: desloque cada letra de uma frase em
nposições no alfabeto. Crie dois programas — um que criptografa a frase com base numa chaven, e outro que descriptografa usando a mesma chave (exemplo, comn=2:"Eu gosto de programar"deve virar"Gw iquvq fg rtqitcoct"). - Receba uma letra e uma frase digitadas pelo usuário, e conte quantas vezes essa letra aparece na frase.
- Receba uma string
se dois caracteresch1ech2, e substitua todas as ocorrências dech1porch2na string. - Receba uma string e converta todos os caracteres para maiúsculo.
- Faça um programa que leia um vetor de 5 palavras (
char nomes[5][20], como na Seção 4.5) e as imprima em ordem alfabética. (Dica:strcmp(a, b)devolve um valor negativo seavem antes debem ordem alfabética, positivo se vem depois, e 0 se são iguais — dá para usar isso no lugar de</>dentro de um algoritmo de ordenação como o que você já deve conhecer de Python/VisuAlg.)