Curso : Engenharia Electrotcnica e de Computadores - Bolonha Matria : Introduo Linguagem C
Dulce Mota 2009/10
Dulce Mota ISEP 2 Programao em C Introduo
A linguagerm C evoluiu de duas linguagens B e BCPL e foi desenvolvida nos Bell Telephone Laboratories em 1972 por Brian W. Kerninghan e Dennis M. Ritchie. A linguagem C est associada ao desenvolvimento de sistemas operativos, nomeadamente o sistema UNIX, e uma linguagem independente do hardware. Com algum cuidado na implementao de programas em C, possvel que os mesmos corram em diversas plataformas. A rpida expanso da linguagem C levou a que surgisse muitas variantes que eram similares mas muitas vezes incompatveis. Em 1989 foi aprovado um documento, e actualizado em 1999, que teve como objectivo criar uma verso standard do C (ISO/IEC 9899:1999). Basicamente, um programa em C est dividido em mdulos designados de funes. Todas as funes podem ser programadas por ns mas a linguagem C possui uma grande coleco de funes designadas de C Standard Library. Assim, para programarmos em C necessrio por um lado, conhecer a linguagem propriamente dita, e por outro lado, aprender a usar as funes das bibliotecas standard do C.
Passos para a construo de um programa em C, pronto a ser executvel:
1 Passo: Edio do ficheiro fonte. Existem vrios utilitrios para editar, escrever, o cdigo fonte, como por exemplo:vi, emacs e notepad. Os ambientes de desenvolvimento integrados de programao so tambm bastante utilizados uma vez que integram uma srie de funcionalidades dentro do prprio ambiente para desenvolvimento de programas. As funcionalidades fazem parte de um ambiente grfico normalmente bastante fcil de usar. Mais importante gravar o ficheiro fonte com a extenso .c.
2 Passo: Compilao do ficheiro fonte. O compilador verifica se a sintaxe das instrues de um programa est correcta e traduz o programa para linguagem mquina. Se no houver erros de compilao, ser ento criado um ficheiro objecto, com o nome igual ao nome do programa e extenso .obj (em Dos) ou .o (em Unix). Antes de criar a linguagem mquina, o compilador invoca o pr-
Dulce Mota ISEP 3 Programao em C processador de C para executar possveis comandos, designadamente directivas (iniciadas por um cardinal #) de pr-processamento. Estas directivas consistem maioritariamente na incluso de outros ficheiros no programa.
3 Passo: Linkagem do programa objecto. Os programas em C contm referncias a funes definidas fora do programa, nomeadamente, aquelas existentes em bibliotecas standard do C e bibliotecas privadas. O cdigo obtido na fase de compilao possui buracos devido a essas partes que faltam. Nesta fase, ligado o cdigo produzido anteriormente com o cdigo que falta produzindo o ficheiro executvel. Esquema geral:
Estrutura bsica de um programa em C
Num programa em C, possvel destacar diferentes blocos de cdigo, nomeadamente: Bloco de comandos que no so instrues C, tais como: incluso de bibliotecas, directivas de compilao e definio de constantes (na figura: Bloco A). Bloco de funes do programador (na figura: Bloco B). Todo cdigo tem de ser desenvolvido e divido em funes. O programador cria as suas prprias funes para construir um programa. Bloco principal: Caracteriza-se por conter a funo principal do programa, a funo main(). Esta funo contm o conjunto de instrues responsveis por Ficheiro objecto
Dulce Mota ISEP 4 Programao em C dar incio execuo do programa. O cdigo de qualquer funo tem de ser escrito entre { } (na figura: Blocos B e C). O bloco B pode tambm ser colocado depois da funo main(). Para isso, necessrio colocar os prottipos das funes, referentes ao bloco B, antes de qualquer chamada s mesmas por parte de outras funes.
Quando for compilado o programa, se o compilador apresentar um aviso com uma mensagem do tipo: Function should return a value, deve-se ao facto de se estar a usar um compilador de C++. Este aviso pode ser simplesmente ignorado, ou ento, para ser eliminado, suficiente colocar a palavra void (que significa nada) antes da funo main(). De notar, que a funo main() pode ser definida com um cabealho mais elaborado, conforme se mostra a seguir: main(int argc, char *argv[]) A sua utilizao justifica-se quando um programa precisa de receber dados, atravs dos parmetros da funo, que foram passados na linha comando. O parmetro argc indica quantos argumentos foram passados na linha de comando (incluindo o prprio nome do programa), e argv um vector com todas as cadeias de caracteres (strings) passadas na linha de comando. #include<stdio.h> .... #define MAX 100 f1() { . } main() {
f1(); . } Bloco A Bloco B Bloco C
Dulce Mota ISEP 5 Programao em C O programa abaixo apresentado, imprime para o ecr a mensagem Boas Vindas e pretende mostrar a estrutura bsica de um programa em C.
A funo padro printf(), tais como outras funes para Input/Output, encontram- se na biblioteca <stdio.h>. Sempre que so utilizadas num programa, necessrio adicionar uma directiva para incluir a biblioteca de funes respectiva. Na escrita do cdigo fonte, a linguagem C muito flexvel na medida em que permite que qualquer instruo seja codificada numa s linha, ou dividida por diversas linhas, isto , no tem colunas ou linhas dedicadas para se comear a escrever as instrues, como o caso das linguagens COBOL e RPG. No programa anterior a nica instruo da funo main() poderia ser escrita da seguinte maneira:
Terminada a execuo do programa, temos a visualizao da mensagem, ficando o cursor colocado a seguir ao ltimo carcter. Se pretendssemos, o que muito comum, que aquele fosse posicionado na linha imediatamente a seguir apresentao da mensagem, tnhamos de adicionar funo printf(), um carcter especial para esse fim. Esse carcter \n (New Line). O programa ficaria assim: #include<stdio.h>
O compilador quando encontra o smbolo \ espera encontrar imediatamente a seguir a este, outro smbolo com uma funo especial. A tabela abaixo, apresenta um conjunto significativo de smbolos usados na linguagem C.
\7 Bell (sinal sonoro do computador) \a Bell (sinal sonoro do computador) \b BackSpace \n New Line (mudana de linha) \r Carriage return \t Tabulao horizontal \v Tabulao vertical \\ Carcter \ \ Carcter (plica) \ Carcter (aspas) \? Carcter ? (ponto de interrogao)
No se pode falar de um programa em C, sem se falar do carcter ponto e vrgula ;. Este smbolo indica ao compilador o fim de uma instruo e importante a sua colocao para se evitar erros de compilao.
Comentrios
Os comentrios tm como objectivo fornecer notas e/ou esclarecimentos teis sobre os blocos e/ou linhas de cdigo de um ficheiro fonte. Seguindo esta prtica, ser certamente mais fcil e rpido, quer para quem faz o programa quer para outros que o venham a alterar, entender o que se pretende em determinado ponto do programa. O compilador reconhece que determinada linha ou linhas de cdigo so comentrios se estas estiverem limitadas pelos smbolos /* e */. Podem ser usados os caracteres // quando se pretende comentar s uma linha de cdigo do programa. #include<stdio.h>
main() { printf(Boas Vindas\n); }
Dulce Mota ISEP 7 Programao em C Os comentrios no so alvo de compilao.
Por exemplo:
Palavras reservadas, tipos de dados bsicos, constantes e operadores
Palavras reservadas
O conjunto de palavras reservadas em C relativamente pequeno uma vez que muitas das suas capacidades encontram-se nas bibliotecas da linguagem concebidas para realizar todo tipo de tarefas. No quadro seguinte so apresentadas as palavras reservadas da linguagem C. medida que forem utilizadas sero dadas as explicaes necessrias.
asm double int struct auto else long switch break enum near typedef case extern register union char far return unsigned const float short void continue for signed volatile default goto sizeof while do if static
/* Programa: prog01.c Data: 99/10/20 */ .... /* Metodo principal da aplicao */ main() { ... }
Dulce Mota ISEP 8 Programao em C Tipos de dados
Os dados so armazenados na memria primria do computador em estruturas primitivas (variveis) ou em estruturas no primitivas, como por exemplo vectores e matrizes (estruturas multi-dimensionais). Em C, como na maior parte das linguagens, necessrio associar um tipo de dados estrutura. Esta etapa feita quando se faz a declarao da estrutura. Os tipos de dados disponveis para esta linguagem so cinco: int (para inteiros), float (para reais), double (para reais), char (para caracteres) e (Apontador).
A declarao segue o seguinte formato: tipo var1 [, var2,...,varn];
Exemplos:
int i; char c1,c2; float salario;
Notas gerais sobre as variveis:
Os nomes das variveis devem ser sugestivos, isto , os nomes devem expressar o tipo de informao ao qual se referem (ex: soma, total, valor_mensal,). A declarao das variveis deve ser sempre feita antes da sua utilizao. O tipo que lhe est associado indica o n de Bytes que iro ser precisos para guardar um valor nessa varivel. A linguagem C Case Sensitive o que quer dizer que diferencia letras minsculas de maisculas. O nome de uma varivel no deve ser escrito em maisculas e o primeiro carcter deve ser uma letra ou o smbolo _.
Dulce Mota ISEP 9 Programao em C Uma varivel pode ser inicializada com um valor atravs de uma operao de atribuio. Esta operao destri o contedo actual da varivel, a qual ficar com o novo valor. A inicializao de uma varivel pode acontecer tambm quando se faz a sua declarao. Exemplos:
int soma=0; char c=s; double salario=0;
A atribuio pode ser feita a vrias variveis num nico passo, sendo essa operao realizada da direita para a esquerda.
Exemplo: soma1=soma2=soma3=0;
Dados do tipo inteiro
Uma varivel do tipo inteiro pode armazenar inteiros positivos e negativos. O tamanho em Bytes de um inteiro varia de arquitectura para arquitectura, sendo o valor mais comum 2 Bytes. No sentido de se poder correr um programa C, independentemente da mquina onde vai ser executado, necessrio adicionar qualificadores ao tipo de dados inteiro. Em C, existem os seguintes qualificadores:
short (inteiro pequeno) long (inteiro grande) signed (inteiro com sinal) unsigned (inteiro sem sinal)
Estes qualificadores permitem fixar o tamanho dos valores inteiros, independentemente das caractersticas do sistema onde vo funcionar.
Dulce Mota ISEP 10 Programao em C O quadro seguinte apresenta as vrias categorias para os inteiros, o espao que ocupam em memria e o mbito das mesmas:
Tipo N de Bytes Valor mnimo Valor mximo int 2 (ou 4) -32 768 32 768 short int 2 -32 768 32 768 long int 4 -2 147 483 648 2 147 483 647 unsigned int 2 0 65 535 unsigned short int 2 0 65 535 unsigned long int 4 0 4 294 967 295
Escrita e leitura de inteiros
Normalmente utilizada a funo printf(), para escrita formatada de informao. O smbolo % seguido de um ou mais caracteres indica o tipo de dados que ir ser mostrado. No caso dos inteiros, o carcter o d. Exemplo:
Output deste programa : Contedo de n1 = 12 e de n2 = 16 A funo printf() substitui os locais onde aparece o smbolo de formatao pelos valores das variveis que se encontram a seguir ao primeiro argumento. A ordem destas variveis importante uma vez que as substituies so realizadas segundo essa ordem. No que respeita leitura de valores, via teclado, normalmente utilizada a funo scanf(). Esta funo s deve conter o formato das variveis que se pretende ler. #include<stdio.h>
main() { int n1=12; int n2=16; printf(Contedo de n1 = %d e de n2 = %d\n,n1,n2); }
Dulce Mota ISEP 11 Programao em C Exemplo: .... int n3; scanf(%d,&n3); ....
O primeiro argumento uma string (cadeia de caracteres) e deve indicar a formatao do valor ou valores a ler. Cada valor lido deve ter uma correspondncia com um smbolo de %. Nos argumentos seguintes da funo, deve-se colocar as variveis precedidas do operador & (excepto se forem strings). A presena deste smbolo, deve-se ao facto desta funo precisar de conhecer o endereo onde a varivel reside para poder alter-la. Mais tarde ser explicado como realizada tal alterao. Outro exemplo:
O formato de leitura e escrita de variveis inteiras short e long nas funes scanf() e printf() deve ser precedido dos prefixos h (short) e l (long), respectivamente. Para o tipo unsigned deve-se substituir %d por %u.
Dados do tipo real
A declarao de variveis reais pode ser feita recorrendo aos seguintes tipos:
Tipo N de Bytes float 4 double 8 #include<stdio.h> main() { short int x,y; printf(Introduza dois nmeros: ); scanf(%d%d,&x,&y); printf(O resultado de %hd+%hd =%hd\n,x,y,x+y); }
Dulce Mota ISEP 12 Programao em C
O formato de escrita e leitura segue as mesmas regras do tipo inteiro sendo agora utilizado o %f para reais float e %lf para reais double (long float). Exemplo:
Dados do tipo carcter
Uma varivel do tipo char contm apenas um nico carcter o qual sempre armazenado num nico Byte. Exemplo: char ch=A, ch1=\n; O formato de leitura e escrita para caracteres %c. Exemplo:
Os formatos de leitura e escrita devem estar de acordo com o tipo das variveis, caso contrrio, podero ocorrer situaes indesejveis. #include<stdio.h> main() { float raio, perimetro; double pi=3.1415927,area; printf(Digite o valor do raio da circunferencia:); scanf(%f,&raio); printf(Area = %lf\n Perimetro = %lf\n,pi*raio*raio, 2*pi*raio); } #include<stdio.h> main() { char ch; printf(Introduza um carcter: ); scanf(%c,&ch); printf(O carcter =%c\n,ch); }
Dulce Mota ISEP 13 Programao em C Muitas outras funes de leitura e escrita esto disponveis na linguagem C, ficando esse estudo para mais tarde.
Resumo dos Formatos de Leitura e Escrita
Tipo printf scanf Significado char %c %c Um nico carcter int %d %d Um inteiro (base decimal) int %o %o Um inteiro (base octal) int %x ou %X %x ou %X Um inteiro (base hexadecimal) short int %hd %hd Um inteiro pequeno long int %ld %ld Um inteiro grande unsigned int %u %u Um inteiro positivo unsigned short int %hu %hu Um inteiro pequeno positivo unsigned long int %lu %lu Um inteiro grande positivo float %f ou %e ou %E %f ou %e ou %E Um real (e/E-notao cientfica) double %lf ou %e ou %E %lf ou %e ou %E Um real (e/E-notao cientfica) long double %Lf %Lf Real grande
Constantes
Uma constante corresponde a um valor fixo, o qual no pode ser alterado ao longo da execuo do programa. A vantagem est na rpida substituio do valor da constante, que existe num s local do programa fonte, por outro valor, ficando todo o programa consistente com a nova actualizao. Existem dois tipos de definio de constantes em C: Atravs da palavra reservada const. Sintaxe: const tipo simbolo = valor;
Atravs da directiva de prprocessamento #define (constante simblica). Sintaxe: #define simbolo valor
Exemplos:
const int n =100; #define N 100
Dulce Mota ISEP 14 Programao em C A principal diferena entres estas duas definies relaciona-se com o seguinte: na fase de pr-processamento, o smbolo existente na directiva #define substitudo, ao longo de todo o programa, pelo valor que lhe foi atribudo, enquanto que na definio const, a constante existe fisicamente numa determinada posio de memria durante a execuo do programa. No fim da instruo #define no deve ser colocado o smbolo ponto e vrgula. As declaraes de constantes devem ser colocadas depois das directivas do tipo #include.
Operadores
Operadores para dados numricos
A tabela seguinte apresenta os operadores bsicos usados nas instrues de clculo aritmtico.
Oper ao Significado + Soma - Subtraco * Multiplicao / Diviso inteira (os dois operandos tm de ser inteiros) / Diviso real (pelo menos um operando tem de ser real) % Mdulo Resto da diviso inteira
Operadores relacionais
A tabela seguinte apresenta os operadores bsicos usados nas instrues que envolvem testes condicionais.
Operador Designao Exemplo Significado == Igualdade a==b Testa se a igual a b > Maior que a>b Testa se a maior do que b >= Maior ou Igual que a>=b Testa se a maior ou igual a b < Menor que a<b Testa se a menor do que b <= Menor ou Igual que a<=b Testa se a menor ou igual a b != Diferente de a!=b Testa se a diferente de b
Dulce Mota ISEP 15 Programao em C Uma expresso que contenha um operador relacional, devolve sempre como resultado o valor lgico Verdadeiro (true) ou Falso (false).
Operadores lgicos
Esta classe de operadores permite interligar duas ou mais condies tendo como resultado dessas combinaes um nico valor lgico (Verdadeiro ou Falso). Quadro resumo:
Operador Significado Exemplo && AND (E lgico) y<2 && y<=6 || OR (Ou lgico) y==2 || y==3 ! NOT (Negao lgica) if (!(a==2))
Operadores de incremento e decremento
A linguagem C possui um conjunto de mecanismos que reduzem significativamente o cdigo editado. Por exemplo, instrues do tipo: i = i + 1; ou j = j 1; podem ser simplificadas se forem usados os operadores ++ e --, respectivamente. As mesmas instrues podem ser reescritas da seguinte maneira: i++; /* Incremento de 1 */ e j--; /* Decremento de 1*/ O primeiro operador incrementa uma unidade varivel i, enquanto o segundo decrementa uma unidade varivel j.
Dulce Mota ISEP 16 Programao em C
Operador Exemplo Equivalente i ++ i++ ou ++i i=i+1 i -- i -- ou -- i i=i-1
Alguns operadores podem ser colocados antes ou depois da varivel mas preciso cuidado quando na mesma expresso existem outros operadores. Por exemplo, as instrues seguintes fazem as mesmas operaes, no entanto, no so equivalentes. y = x ++; e y = ++ x; No primeiro caso, o valor de x atribudo a y e s depois a varivel x incrementada de uma unidade. No segundo caso, o incremento feito em primeiro lugar e s depois realizada a atribuio. Analise o programa abaixo apresentado e indique os resultados que so mostrados para o ecr juntamente com o valor das variveis depois de realizado cada printf().
#include<stdio.h>
main() { int x,y; x=y=2; printf(x=%d e y=%d\n,++x,y--); printf(x=%d e y=%d\n,x,y); }
Dulce Mota ISEP 17 Programao em C Atribuio composta
tambm possvel, em C, reduzir a quantidade de cdigo em expresses do tipo: x = x + 2; x = x * ( 3 + y); A atribuio composta facilita a escrita destas expresses, conforme se pode verificar atravs dos exemplos: x += 2; equivalente a: x = x + 2; x *= 3 + y; equivalente a: x = x * ( 3 + y); O formato geral da atribuio composta o seguinte: varivel operador_aritmtico= expresso Para ser possvel a utilizao da atribuio composta necessrio que a varivel que vai ser alterada esteja esquerda e direita do operador de atribuio. Operadores de atribuio composta mais usados: +=, -=, *=, /=, %=. Mais alguns exemplos:
Operador sizeof
Este operador tem como objectivo informar qual a dimenso, em Bytes, de qualquer tipo de dados ou varivel. A sintaxe deste operador a seguinte: sizeof <expresso> ou sizeof( <tipo> )
Exemplos Significado z += 1 z = z + 1 z -= y+2 z = z (y+1) z *= y + 3 z = z * (y+3)
Dulce Mota ISEP 18 Programao em C Exemplo :
Converso de tipos de dados
A converso de tipos de dados normalmente til quando necessrio que um dado valor pertencente a um tipo de dados seja convertido para outro tipo de dados sem que, para isso, sejam criadas novas variveis. A converso de tipos pode ser realizada de forma implcita ou de forma explcita. Modo Implcito: Ocorre quando numa expresso esto envolvidas variveis de tipos de dados diferentes. Nesta situao, o resultado automaticamente convertido para o tipo de dados de maior amplitude, ou seja, numa expresso aritmtica, o operando cuja representao em memria de menor dimenso, convertido para a representao com maior dimenso. Exemplos: int x; long int i; char c; O resultado da expresso x+i torna-se do tipo long int. Na expresso x+c, o resultado do tipo int.
Modo Explcito: Neste caso, o utilizador que informa explicitamente o compilador do casting (converso) que deseja ver efectuado. Se o valor resultante da converso passar para um tipo superior diz-se que se trata de uma promoo, caso contrrio, diz-se despromoo. #include <stdio.h>
Todos os caracteres possuem um cdigo, designado de cdigo ASCII (American Standard Code for Information Interchange) e na linguagem C todos os caracteres so tratados como valores inteiros. Neste programa lido um valor inteiro (entre 0 e 255, porque o intervalo de cdigos onde se incluem todos os caracteres visveis) e imprime esse nmero. Paralelamente, mostrado o carcter que corresponde a esse valor inteiro. Nesse sentido, foi necessrio colocar explicitamente o casting (char) antes da varivel n para ser mostrado o carcter correspondente ao inteiro lido. Resultado do programa: Digite um valor inteiro (0-255): 65 Digitou o n 65 cujo carcter = A De salientar que a utilizao da funo scanf() com formatos inadequados pode levar a erros muito graves. Como referido anteriormente, os formatos de leitura introduzidos no primeiro argumento desta funo, informam o compilador do nmero de bytes necessrios para guardar os valores das variveis. Se, por exemplo, tivermos um formato do tipo %c e em seguida for lido um inteiro, como consequncia haver perda de informao porque os tamanhos no correspondem. #include<stdio.h>
main() { int n; printf(Digite um valor inteiro (0-255): ); scanf(%d,&n); printf(Digitou o n %d cujo carcter = %c\n,n, (char) n); }
Dulce Mota ISEP 20 Programao em C Analise o seguinte programa:
Output: Digite um carcter: C O contedo de n=835 corresponde ao carcter=C Qual a explicao que d para este resultado?
Precedncia de operadores
A precedncia de operadores identifica a ordem pela qual as operaes envolvidas numa dada expresso so executadas. O compilador precisa de saber sem qualquer ambiguidade qual a operao a executar, por isso, todos os operadores precisam de ter associado um atributo que identifica a precedncia. Em expresses aritmticas, a multiplicao e a diviso tm a mesma precedncia mas a adio j tem menor precedncia do que estas ltimas, por isso a expresso: c = 2 + 5 * a equivalente a termos c = 2 + (5 * a).
Quando numa mesma expresso existem operadores com a mesma precedncia, o compilador resolve a expresso segundo a associatividade atribuda a esses operadores. Este atributo diz respeito ao sentido (esquerda para a direita ou direita para a esquerda) da execuo das operaes. #include<stdio.h>
main() { int n=999; printf("Digite um carcter: "); scanf("%c",&n); printf("O contedo de n=%d corresponde ao carcter=%c\n", n,(char)n); }
Dulce Mota ISEP 21 Programao em C Exemplos: A expresso: 2+3+5 equivalente a: (2 + 3) + 5, por isso, o operador + associativo esquerda. J a expresso: a=b=c equivalente a: a=(b=c) e por isso, o operador = associativo direita. Finalmente, a tabela abaixo apresentada, mostra a precedncia e respectiva associatividade de vrios operadores.