Programação em Sistemas Computacionais Linguagem C Introdução, tipos Centro de Cálculo Instituto Superior de Engenharia de Lisboa Jorge Martins (jmartins@isel.pt) baseado no slides de Pedro Pereira
Enquadramento CCISEL, 2012 2
Programa Introdução à linguagem de programação C Compilação e ligação Representação de números; Manipulação bit a bit; Tipos. Definição de tipos complexos através arrays de estruturas Ponteiros e aritméticas entre ponteiros. Representação de programas C em assemblyx86 Conjunto de instruções IA-32 Convenção de chamada e retorno entre funções C e assembly Ponteiros para função e ponteiros não tipificados Avaliação e controlo de desempenho Ideia geral de sistemas de cache; Impacto no desenho dos programas Análise de programas gerados pelo compilador com optimização Produção e execução de programas C Pré-processamento; Ficheiros header; Ligação estática Visibilidade de nomes e tempo de vida de instâncias Alocação dinâmica de memória Desenvolvimento modular e object-oriented Modelo de despacho dinâmico. Como traduzir para C a herança e o polimorfismo do Java. Ligação dinâmica na produção de software modular CCISEL, 2012 3
Avaliação 4 séries de exercícios realizadas em grupo (2 a 3 alunos) 3 mini-testes individuais: Nota mínima de 8 para a média dos dois melhores testes - MT 1 Teste final (nota mínima 9,5) -TF 1 Discussão final em grupo - DF Nota final(individual) = MT* 0,2 + TF* 0,4 + DF* 0,4 Todos os intervenientes em cópias, detectadas em qualquer elemento de avaliação, terão o respectivo elemento anulado. CCISEL, 2012 4
Ambiente de Desenvolvimento Sistema operativo Linux Instalar uma distribuição de Linux (Xubuntu) No Windows instalar uma máquina virtual (VMwarePlayer) Imagem com instalação pronta a usar (disponível em http://www.deetc.isel.pt/programacao/psc/ferramentas.html) Ferramentas Editor de texto (gedit) Compilador e linker(gcc) Debugger(insight ou ddd) CCISEL, 2012 5
Bibliografia CCISEL, 2012 6
Antes do C Linguagens de programação nos anos 60: COBOL Para tratamento de ficheiros de dados Utilização comercial (Bancos, Seguradoras, ) FORTRAN Para cálculo numérico Utilização científica LISP e Prolog Para dedução lógica Utilização em Inteligência Artificial Assembly Para código de baixo nível e onde o tempo de execução é critico Utilizado no desenvolvimento de sistemas operativos e drivers Laboratórios Bell (AT&T): desenvolvimento de sistemas operativos Ken Thompson: linguagem B (evolução do Assembly) Dennis Ritchie: linguagem C (B com tipos) CCISEL, 2012 7
C versus Java C Dennis Ritchie: 196?- 197? Programação de sistemas Desenhado para estar perto do hardware Acesso directo à memória (eficiência tempo/espaço) Permite portabilidade entre várias plataformas de hardware Portabilidade ao nível do código fonte Linguagem procedimental Java James Gosling: 199? Sintaxe semelhante a C Suporte de OOP com mais mecanismos automáticos mas menos liberdade nos paradigmas suportados CCISEL, 2012 8
Perigos e desvantagens face a Java Gestão de memória feita explicitamente Java tem gestão automática garbage collection Iniciação explícita Java inicia os campos e detecta utilização sem iniciação Detecção de erros explícita Java gera excepção (referência a null, indexação fora dos limites, ) Mais linhas de código para a mesma funcionalidade Fácil cometer erros não detectados pelo compilador Não existe portabilidade de código já compilado As bibliotecas não são portáveis Não existe uma interface gráfica standard e portável CCISEL, 2012 9
Exemplo em C #include <stdio.h> words.c int main() { int nextchar; /* char readed */ int count = 0; /* words counter */ int inword = 0; /* current state */ } while (( nextchar = getchar() )!= EOF) { if (nextchar == '\n' nextchar == ' ') inword = 0; else if (! inword) { inword = 1; ++count; } } printf("words=%d\n",count); return 0; CCISEL, 2012 10
Compilar, Ligar e Executar (Linux / GNU) gcc -Wall pedantic -g -c words.c Compila o ficheiro fonte words.c e gera o ficheiro words.o com o código compilado. Neste passo são detectados os erros de compilação pre-processador; sintaxe; semânticos gcc words.o o words Liga words.o com a biblioteca standard e gera o ficheiro executável words Neste passo são detectados erros de ligação Símbolo não encontrado words < abc.txt Executa o programa dando como entrada (input) o conteúdo do ficheiro abc.txt Neste passo são detectados os erros de execução O programa não cumpre o objectivo CCISEL, 2012 11
Exemplo em C #include <stdio.h> pc.c void printchar( char c ) { int code = c; printf( Char %c code=%d hex=%x\n,c,code,code); } int main() { printchar( A ); printchar( H ); return 0; } Char A code=65 hex=41 Char H code=72 hex=48 CCISEL, 2012 12
Identificadores, Tipos e Constantes Identificadores As mesmas regras de Java: Tipos básicos ( char, int, float, double ) Modificadores de dimensão (short, long) aplicáveis a int Modificadores de sinal (signed, unsigned) aplicáveis a int e char Constantes (literais) int: 23 023 0x23 23L 23U double ou float: 23.5 23.5F 23. 23.F 12.3e-4 12.3e10F char: K \n \t \\ \0 \113 \x48 string: abc aspas=\ linha\n CCISEL, 2012 13
Variáveis char c int count = 0 Nome Zona de memória associada a um nome Tipo Significado e dimensão dos valores armazenados Âmbito (scope) Onde é vista a variável Bloco de função, Argumento de função, Global, outros blocos Tempo de vida Desde a reserva de memória à libertação Automático (sujeito ao bloco) Estático (sujeito ao programa) CCISEL, 2012 14
Conversão de tipos Conversão implícita Verificada em tempo de compilação Promoção char int float double short int int long int Em expressões quando os operandos são de tipos diferentes Conversão para o tipo mais abrangente int small = 10L; long large;... large = small;??? any; any = large + small; Conversão explícita (cast) Para realizar despromoções small = (int) large; Podem gerar código short int val = -1; small = (int) val; CCISEL, 2012 15
Operadores Aritméticos: Quatro operadores entre inteiros e reais: +, -, * e / Resto de divisão inteira: % Operadores unários: + e Incremento e decremento (prefixo e sufixo): ++ e - Relacionais: >, >=, <, <=, == e!= Lógicos: &&, e o unário! Bit a bit: &,, ^, <<, >> e o unário ~ Afectação: = Compostos: +=, -=, *=, /=, %=, &=, =, ^=, <<= e >>= Precedência e Associatividade () [] ->.! ~ ++ -- + - * & (type) sizeof * / % + - << >> < <= > >= ==!= & ^ &&?: = += -=, CCISEL, 2012 16
Funções Porquê? Divisão: Dividir para reinar Problemas em sub-problemas Compilação separada Testar separadamente Trabalho por equipas Reutilização noutros contextos Esconder detalhes de implementação Declaradas antes da utilização Podem só ser definidas depois Assinatura: nome tipo dos parâmetros (nomes opcionais) tipo do retorno Passagem de parâmetros por valor int power( int, int ); int main() { int i; for( i=0 ; i<10 ; ++i ) printf( %d %d\n, i,power(2,i)); return 0; } int power(int b, int n) { int res = 1; for(; n>0 ; --n) res *=b; return res; } CCISEL, 2012 17
typedef Definir outro nome para um tipo Sintaxe semelhante à declaração de variável, mas prefixada por typedef Os dois tipos são iguais. typedef unsigned int uint;... uint value; CCISEL, 2012 18
enum CCISEL, 2012 19