C avançado para sistemas
Compilação, bibliotecas, apontadores, tempo de vida, strings e argumentos.
Compilar e ligar
gcc -E, -S, -c param no pré-processamento, assembly e objeto. Só a ligação produz o executável.
| Erro | Fase | Falta |
|---|---|---|
implicit declaration | compilação | declaração visível (incluir o .h) |
undefined reference | ligação | definição (objeto ou -lX) |
- Cabeçalho declara; implementação define.
-L.diz onde procurar,-lvetoro quê; a biblioteca estática entra depois dos objetos que a usam. - Partilhada: compilar com
-fPIC, ligar com-shared; o carregador tem de encontrar a.soem execução (LD_LIBRARY_PATH). -gé depuração,-Wallnão é todos os avisos. Lê e corrige cada aviso.
Apontadores
C passa tudo por valor. A cópia de um endereço permite alterar o objeto, não o apontador do chamador.
int x = 5, y = 3, *p = &x, *q = p;
p = &y; /* q continua em x */
*q = 9; /* x passa a 9, y continua 3 */
p+1avança um elemento;a[i]é*(a+i)com índice válido. O fim do array serve de limite, não de leitura.sizeof a / sizeof a[0]só conta elementos no âmbito do array; emint a[]como parâmetro, passa o comprimento.void *guarda endereços sem tipo: sem desreferência nem aritmética em C17.
Tempo de vida
- Automático morre no fim do âmbito. Devolver
&localé comportamento indefinido, com ou sem falha visível. mallocnão inicializa;calloczera. ConfereNULL, define quem liberta.- Em
realloc, guarda o retorno num temporário. Com tamanho pedido maior que zero, a falha conserva o bloco antigo e o sucesso invalida o endereço antigo.realloc(p, 0)tem contrato que varia por edição e implementação, por isso não assumas libertação nem bloco válido. - Depois de
free, o bloco morreu; pôr um alias aNULLnão salva os outros.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *original = malloc(sizeof *original);
int *copia = malloc(sizeof *copia);
if (original == NULL || copia == NULL) {
free(original);
free(copia);
return 1;
}
*original = 4;
*copia = *original;
*copia = 9;
printf("original=%d copia=%d\n", *original, *copia);
free(copia);
free(original);
return 0;
}Resultado
Executa o código para ver a saída e os gráficos.
Dá original=4 copia=9: dois blocos independentes, não dois nomes do mesmo inteiro.
Strings, argumentos e listas
"ola"ocupa 4 bytes.strlenconta até\0numa string válida; não mede a capacidade do buffer.strcmpsó garante o sinal.strcpy(dst, src)exigestrlen(src)+1bytes no destino;srctem de ser uma string válida e as regiões não se podem sobrepor.strcat(dst, src)exigestrlen(dst)+strlen(src)+1bytes;dstjá tem de ser uma string válida e as regiões não se podem sobrepor. Não medirstrlende um destino ainda não inicializado.strtokaltera o buffer e trata delimitadores como conjunto;strseppode dar tokens vazios.argcinclui o nome;argvsão strings. Valida comstrtol(ERANGE, sem dígitos, resto) e confirmaINT_MIN/INT_MAXquando precisas deint.- Para um máximo de números que podem ser negativos, inicializa com o primeiro valor validado, não com zero.
- Lista vazia: cabeça
NULL. Quem muda a cabeça recebestruct no **; guardaseguinteantes defree.