Programação Estruturada
UFABC
.h no EP1.c conhece outro?Cada arquivo .c é compilado separadamente.
Em desenho.c, uma função é implementada:
Como o compilador saberá que essa função existe?
desenho.h declara/avisa o que desenho.c oferece para os outros arquivos.
Os arquivos que precisam dessa informação incluem o mesmo cabeçalho:
desenho.h
O comando #include torna as declarações em .h disponíveis antes da compilação do arquivo .c.
Podemos pensar nas linhas que começam com # são diretivas do pré-processador, processadas antes da compilação propriamente dita.
#include inclui um cabeçalho#define define uma constante/macro#ifndef e #endif processam um trecho apenas sob determinada condição.No EP1, a combinação de #ifndef, #define e #endif evita que o mesmo .h seja incluído mais de uma vez.
Os arquivos .h não são compilados separadamente: compilamos os .c que os incluem.
char.Na memória, string é um vetor de char:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| H | e | l | l | o | ␣ | W | o | r | l | d | \0 |
Toda string em C termina com o caractere nulo '\0'.
#include<stdio.h>
int main() {
char universidade[5];
universidade[0] = 'U';
universidade[1] = 'F';
universidade[2] = 'A';
universidade[3] = 'B';
universidade[4] = 'C';
printf("%s\n", universidade);
return 0;
}Veja que usamos aspa simples para representar caracteres!
O que será impresso?
Resultado (em alguns compiladores)
Faltou colocarmos o caractere \0 indicando o final da String!
Muitas vezes a impressão não vai sair quebrada como acima. Usar a flag -fsanitize=address vai apontar acesso em local inválido da memória.
Para ler Strings sem espaços (␣, \t, \n,), passamos o vetor para o scanf:
int main() {
char universidade[50];
scanf("%s", universidade);
printf("%s\n", universidade);
return 0;
}Apesar de ser o scanf, observe que aqui não usamos o “&”.
Identificador do vetor sem os colchetes representa o endereço do primeiro elemento.
Como universidade == &universidade[0], o seguinte código funciona:
gets e putsFunções para ler e imprimir strings
gets: lê uma string até \n ou EOF (End Of File) (substituidos por \0);puts: imprime uma string e quebra a linha.fgetsO fgets é parecido com gets, mas limita a quantiade de caracteres lida
fgetsPegou apenas os 5 primeiros caracteres!
É recomendável utilizar o fgets ao invés do gets! O gets é insegura, pode sobrescrever pedaços arbitrários da memória.
O fgets lê até o primeiro \n ou EOF
fgets e putsfgets: lê uma string com um limite de caracteres;puts: imprime uma string e quebra a linha.Qual a diferença para o scanf e printf?
scanf("%s", texto) ignora espaços em branco iniciais e para de ler quando encontra o próximo espaço em branco.fgets(texto, n, stdin) lê no máximo n - 1 caracteres, parando antes disso se encontrar \n ou EOF. Se encontrar \n, ele é armazenado na string.string.hA biblioteca string.h tem várias funções úteis:
<, <=, >, >=, == e !=strcpy copia uma stringstrcat concatena duas strings… e várias outras. Veja o manual para a documentação (ex: man strlen)
Não confunda com a biblioteca strings.h
Na cifra de César, cada letra é substituída pela letra que está n posições à frente no alfabeto.
charEm C, um char armazena um pequeno valor inteiro. A tabela ASCII (American Standard Code for Information Interchange) associa um número a cada caractere.
| Caractere | ASCII | Caractere | ASCII |
|---|---|---|---|
'A' |
65 | 'a' |
97 |
'B' |
66 | 'b' |
98 |
... |
... |
... |
... |
'Z' |
90 | 'z' |
122 |
ASCII possui 128 códigos, de 0 a 127. Letras acentuadas, como á e ç, não fazem parte da tabela ASCII original. Número negativos em char são usados em outras tabelas.
O mesmo valor pode ser interpretado como um caractere ou como um número:
No ASCII, as letras maiúsculas e minúsculas formam duas sequências. Assim, podemos fazer operações aritméticas com elas:
E se tivéssemos letra = Z?
Subtrair 'a' transforma uma letra minúscula em uma posição entre 0 e 25:
Depois, deslocamos essa posição e voltamos a somar 'a':
int posicao = letra - 'a';
int nova_posicao = (posicao + n) % 26;
char cifrada = 'a' + nova_posicao;O operador % 26 faz a contagem voltar ao começo do alfabeto para valores >= 26.
Para cada caractere da string:
'a' e 'z', use 'a' como base;'A' e 'Z', use 'A' como base;Para cifrar, avançamos n posições:
a e z;Como seria o protótipo dessas funções?
Faça uma função que receba uma frase e remova a segunda palavra de uma frase.
Frase legal de teste -> Frase de teste
Ideia de assinatura:
Podemos fazer esta função sem o parâmetro de comprimento?
Sim, nesse caso, teríamos que encontrar o caractere '\0' primeiro (ele indica o fim da string).
i de uma fraseFaça uma função que receba uma frase e remova a palavra de índice i de uma frase (considere que a primeira palavra tem índice 0).
Slides originais: Prof. Paulo Henrique Pisani, Strings e Matrizes, Programação Estruturada, UFABC, setembro/2021.