INTRODUÇÃO À LINGUAGEM C Prof. Bruno Feijó, Dept. de Informática, PUC-Rio (2017) C foi criado no início da década de 70, quando os programas mais eficientes eram escritos em linguagem Assembly, bem próxima à máquina. C surgiu como uma substituição ao assembly, porém mais fácil e com eficiência próxima - tanto que o Sistema operacional Unix e vários jogos da época foram escritos em C. Programadores de C trabalham muito mais próximos da máquina do que em outras liguagens high level e por isto precisam entender como a memória do computador funciona. 1
O sistema de numeração decimal (ou sistema de numeração posicional de base 10) requer 10 dígitos diferentes (0,1,2,3,4,5,6,7,8,9) para representar números. Por exemplo, o número 253 é a seguinte soma: 2 5 3 BITS E BYTES 3 x 10 0 = 3 5 x 10 1 = 50 2 x 10 2 = 200 253 O sistema binário (ou de base 2) usa 2 dígitos (0,1). Por exemplo, 1101 equivale ao número 13 no sistema decimal: 1 0 1 1 x 2 0 = 1 0 x 2 1 = 0 1 x 2 2 = 4 1 x 2 3 = 8 Vamos usar o sistema binário para armazenar números no computador. bit (abreviação de binary digit) é a menor unidade de armazenamento (um bit armazena apenas um 0 ou 1) byte (lê-se baite) é uma unidade de informação formada por 8 bits. Menor número: 0; maior número: 255, total de números diferentes: 256 1 13 2
BITS, BYTES E TIPOS Poderíamos pensar em usar o bit mais à esquerda do byte para armazenar o sinal. Neste caso, o maior número positivo seria 127, i.e. [0111 1111]: sinal 0 1 1 1 1 1 1 1 E como seria o número -2? Seria [1000 0010]? Nos computadores, -2 seria [1111 1110]!! Note que desta maneira: 2 + (-2) = 0. Isto é: [0000 0010] + [1111 1110] = [0000 0000] Nos computadores, usamos um artifício matemático chamado de Two s Complement (complemento de dois) para representar números negativos. Isto também facilita a implementação em hardware das operações com números binários. Com este artifício, o maior número negative seria -128 (e não -127). A faixa de valores seria -128 a 127. 1 byte é muito pouco para representar números inteiros. Por isto adotamos 1 byte para representar caracteres, como A, z, [,. E a ideia é bem simples: estabelecemos uma correspondência entre caracteres e códigos numéricos. Por exemplo, 65 representa a letra A, 91 representa o abre cochete [, 122 representa a letra z,. E dizemos que caracteres são do tipo char. O tamanho de um char é 1 byte! Para números inteiros, que chamamos de tipo int, juntamos 4 bytes (32 bits) e consideramos um bit para o sinal. Desta maneira, podemos representar números de -2,147,483,648 a +2,147,483,647. Se não usarmos o bit do sinal, podemos ter números de 0 a 4,294,967,295 e chamamos de tipo unsigned int. float tem 4 bytes, 32 bits (aprox. 6 casas decimais de precisão), faixa: 3.4 10 38 a +3.4 10 38. double tem 8 bytes, 64 bits (aprox. 15 casas decimais de precisão), faixa: 1.7 10 308 a +1.7 10 308. Os tamanhos de int, float e double podem variar (com tipo de máquina e sistema operacional). 3
MEMÓRIA Uma vez que definimos tipos (vimos alguns até agora: char e int), podemos armazenar dados numéricos em blocos de bytes que são identificados por um número chamado endereço (address). Endereço 1023 1022 1021 1020 Memória Uma variável é um nome dado a uma área da memória que armazena o valor (i.e. o conteúdo) de um determinado tipo. Portanto, uma variável tem um nome (identificador), um tipo de dado e um valor. Por exemplo, as instruções int x; x = 2; fazem o seguinte: Em C, o delimitador de int x; : a variável x representa uma área de memória reservada de 4 bytes (tipo int) uma instrução é o ; x = 2; o número inteiro 2 é colocado na memória reservada 3 2 1 0 Endereço da variável x é 1020 Uma variável é equivalente ao valor armazenado. Portanto se y = x + 2; então y contém 4. O código do programa (instruções) também são transformados em blocos de bytes (e.g. 64 bits) e armazenados. x 1027 1026 1025 1024 1023 1022 1021 1020 0000 0010 0000 0000 0000 0000 0000 0000 Tipo int ocupa 4 bytes 4
FUNÇÕES Um programa em C consiste basicamente de variáveis e funções. Uma função em C recebe valores através de seus argumentos, realiza tarefas e retorna um valor. C tem uma função principal, chamada main, que é chamada pelo Sistema Operacional quando o usuário roda o programa. Portanto, a função main é sempre o primeiro ódigo executado quando um programa começa. Uma função pode chamar outras funções auxiliares. Algumas destas funções você mesmo escreveu e outras estão em bibliotecas (libraries) que são disponibilizadas pela linguagem para você. As funções de bibliotecas requerem definições e declarações que estão em arquivos texto com extensão.h, chamados de header files. Depois veremos o que são estes arquivos.h. 5
Equação de uma reta y = ax + b, com a = 2 e b = 1: #include <stdio.h> int equation1(int x) { int a = 2; int b = 1; return a*x + b; } int main(void) { int x = 10; int y; y = equation1(x); printf("hello\n"); printf("%d resultado %d\n", x, y); return 0; } UM PROGRAMA EM C Início e fim de bloco: { } O cabeçalho de uma função é tipoderetorno nome(argumentos) Não pode ter duas funções com o mesmo nome. printf() tem um número variável de argumentos O primeiro argumento é uma cadeia de caracteres (string), onde cada %d indica onde cada um dos outros argumentos deve ser inserido e em que forma deve ser impresso. Por exemplo, %d especifica um argumento inteiro. Especificação de formato: %c um char %d um int %u um unsigned int %f um double (ou float) %e um double (ou float) no formato científico %g um double (ou float) no formato mais apropriado (%f ou %e) %s uma cadeia de caracteres %p um ponteiro (endereço) 6
ENDEREÇOS O tamanho de um tipo é dado pelo operador sizeof() e o endereço de uma variável é obtido com o operador &: #include <stdio.h> int main(void) { char c = 'A'; int a = 5; printf("tamanho char = %d bytes\n",sizeof(char)); printf("endereco de c que contem %c(%d): %p\n", c, c, &c); printf("proximo endereco (+1): %p\n", &c + 1); printf("\ntamanho int = %d bytes\n", sizeof(int)); printf("endereco de a: %p\n", &a); printf("proximo endereco (+1): %p\n", &a + 1); return 0; } Endereços são números inteiros (mas não do tipo int) no sistema Hexadecimal, que é um sistema de numeração posicional de base 16 (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F) 7
COMPILER & LINKER prog.c prog.obj prog.exe 8