EI SO D+PL 2023-24 Cap04 Linguagemc v01
EI SO D+PL 2023-24 Cap04 Linguagemc v01
EI SO D+PL 2023-24 Cap04 Linguagemc v01
Programação em C
Ambientes Linux
2024
• Patrício R. Domingues
• Departamento de Eng Informática
• ESTG/Politécnico de Leiria
CICLO DE DESENVOLVIMENTO DE
SOFTWARE
Imagem: http://w3processing.com/index.php?subMenuItemId=222
Patricio Domingues
11
O PRÉPROCESSADOR
DE C
▪ #include "ficheiroUtilizador.h"
▪ Compilador procura o ficheiro .h nos diretórios do
utilizador (usualmente diretório corrente)
▪ Opção -I do compilador permite especificar diretórios
alternativos
▪ Exemplo
#include <stdio.h>
#include <math.h>
#include "util.h" (c) Patricio Domingues
18
Préprocessador (3) - constantes
https://xkcd.com/303/
(c) Patricio Domingues
22
Préprocessador (6) - condicional
• Exemplo
#ifdef WIN32
printf("Código para ambiente Windows WIN32\n");
#else
printf("Código para ambiente NÃO Windows\n");
#endif
(c) Patricio Domingues
23
Préprocessador (7) - exemplos
• Condicional - Código só é considerado se a constante/macro
DEBUG estiver definida
#define DEBUG
+info: Capítulo 10, “Practical C Programming”, Steve
... Oualline, O’Reilly. 3rd Edition, 2011.
#ifdef DEBUG
printf(“mensagem quando DEBUG está definido\n”);
#endif
• printf(“Linha:%d, Ficheiro fonte: %s\n”, __LINE__,__FILE__);
• __FILE__ e __LINE__ __ corresponde a dois underscores
Patricio Domingues
26
Sistemas Operativos
Programação em C
para ambientes Linux
assert e static_assert
Patricio Domingues
27
A macro assert (#1)
• assert(condição) #include <stdio.h>
#include <assert.h>
– Tradução “afirmar” size_t num_chars(const char *ptr){
#include <assert.h> assert(ptr != NULL );
void assert(scalar expression); const char *workptr = ptr;
• Macro empregue para validar size_t num_elms = 0;
while( workptr && (
código *workptr!='\0')){
• Auxiliar o programador a num_elms++;
detetar situações erradas na workptr++;
aplicação }
return num_elms;
• Caso a condição seja avaliada
}
como falsa (valor lógico FALSO), Se condição avaliada como falsa
a aplicação é terminada com
mensagem de erro a.exe: numchars.c:5: num_chars:
Assertion `ptr != ((void *)0)' failed.
Aborted (core dumped)
Código: https://pastebin.com/hTKsBpKu
(c) Patricio Domingues 28
A macro assert (#2)
Atividade (Linux)
• Como desativar a macro Considere o código do programa divide.c
assert? double divide(int a, int b){
assert(b!=0);
– A macro assert não deve double result = (a*1.0) / (b*1.0);
return result;
ser mantida em código de }
Gera número
produção int main(void){
inteiro aleatório
while(1){
no intervalo [0,9]
– Desativada definindo-se a int a = random() % 10;
int b = random() % 2;
macro NDEBUG printf("%d / %d = %f\n", a, b, divide(a,b));
• Ler: “No debug” usleep(100000); // 100 uSeconds
}
• Desativar }
a) Compile o código: gcc -Wall -Wextra divide.c -o
gcc –DNDEBUG ... divide.exe
- Completar com os includes necessário
b) Execute: ./divide.exe
OU no código O que sucede?
c) Compile, acrescentando -DNDEBUG na linha de
#define NDEBUG compilação. Execute. O que sucede?
(c) Patricio Domingues
29
static_assert – C11
#include <assert.h>
• Exemplo
static_assert( #include <assert.h>
expr,string-literal); #include <stdio.h>
Condição
– Macro avaliada durante a int main(void){
compilação static_assert(sizeof(void*)==8,
"Only 8-byte addresses");
– Se a expressão expr for zero printf("Done\n");
(falsa), então é mostrada a String
return 0;
string-literal e a compilação }
é interrompida
• static_assert
– Surgiu na versão 2011 da
norma C, denominada C11.
– Requer um compilador que
implemente a norma C11
static_assert vs. assert
• static_assert • assert
– avaliada durante a – avaliada em durante a
compilação (compile time) execução (runtime)
– Requer compilador que – É uma macro definida em
suporte a norma C11 <assert.h>
• #include <assert.h>
– É uma macro definida
• Leitura recomendada
em assert.h
– Casalnuovo, Casey, et al. "Assert use in
• #include <assert.h> github projects." 2015 IEEE/ACM 37th IEEE
• A macro encapsula o International Conference on Software
Engineering. Vol. 1. IEEE, 2015.
operador C11
_Static_assert
Sistemas
Operativos
Patricio Domingues
32
Sistemas Operativos
Programação em C
para ambientes
Linux
Utilitário make
Patricio Domingues
33
UTILITÁRIO MAKE
sum (exe)
main.o sum.o
Dependência
entre ficheiros
(c) Patricio Domingues
38
.h e dependências
▪ Automatizar a determinação das dependências de um ficheiro
de código C relativamente aos ficheiros .h
▪ Ficheiros .h que são incluídos (#include) no ficheiro .c
▪ Uso do compilador gcc com a opção -MM
gcc -MM *.c
sum (exe)
main.o sum.o
▪ Exemplo
▪ gcc -MM *.c
main.o: main.c sum.h
Saída produzida por: gcc -MM *.c
sum.o: sum.c sum.h
(c) Patricio Domingues
39
Ficheiro makefile
# Ficheiro com 3 regras (# é indicador de comentário)
# Regra = linha de dependência seguida de linha(s) de ação
sum: main.o sum.o Linha de dependência
40
Sintaxe do makefile
Ficheiro alvo
Continua >>
42
makefile avançado (2)
# Objectos necessarios para criar o executavel
PROGRAM_OBJS=initC.o debug.o ${PROGRAM_OPT}.o
.PHONY: clean all: ${PROGRAM}
# compilar com depuracao
depuracao: CFLAGS += -D SHOW_DEBUG
depuracao: ${PROGRAM}
${PROGRAM}: ${PROGRAM_OBJS}
${CC} -o $@ ${PROGRAM_OBJS} ${LIBS}
Continua >>
43
makefile avançado (3)
# Dependencias
initC.o: initC.c debug.h #${PROGRAM_OPT}.h
${PROGRAM_OPT}.o: ${PROGRAM_OPT}.c ${PROGRAM_OPT}.h
Continua >> 44
makefile avançado (4)
clean: rm -f *.o core.* *~ ${PROGRAM} *.bak
${PROGRAM_OPT}.h ${PROGRAM_OPT}.c
docs: Doxyfile
doxygen Doxyfile
Doxyfile:
doxygen -g Doxyfile
indent:
dos2unix *.c *.h indent ${IFLAGS} *.c *.h
▪ doxygen, http://www.doxygen.org
49