0% acharam este documento útil (0 voto)
53 visualizações62 páginas

Introdução à Linguagem C e Estruturas

aPOSTILA DE c_++

Enviado por

Edson Melo
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
53 visualizações62 páginas

Introdução à Linguagem C e Estruturas

aPOSTILA DE c_++

Enviado por

Edson Melo
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

A Linguagem C

A Linguagem C

Indice :

1. Introdução à linguagem C
1.1 Introdução
1.2 Características
1.3 Estrutura de um programa
1.4 Instruções
2. Operandos e Operadores
2.1 Introdução
2.2 Nomes
2.3 Tipos de Dados
2.4 Classes de Armazenamento
2.4.1 Tipos de Classes de Armazenamento
2.5 Constantes
2.6 Operadores
2.6.1 Operadores Aritméticos
2.6.2 Operadores Incremento e Decremento
2.6.3 Operadores Relacionais e Operadores Lógicos
2.6.4 Operador Condicional
2.6.5 Operadores Bit a Bit
2.6.6 Operadores de Ponteiros
2.7 Precedências
2.8 Conversão de Tipos
2.9 Typedef
3. Instruções de Controle de Sequência
3.1 Instrução IF
3.2 Instrução SWITCH
3.3 Ciclo WHILE
3.4 Ciclo DO-WHILE
3.5 Ciclo FOR
4. Operações de Entrada / Saida
4.1 Introdução
4.2 Saída Formatada
4.2.1 Especificações da Saída Formatada
4.3 Entrada Formatada

[Link] (1 of 2) [21/10/2002 [Link]


A Linguagem C

4.3.1 Especificações da Entrada Formatada


4.4 Outras funções da Biblioteca Standard
4.5 Outras Funções
5. Funções
5.1 Introdução
5.2 Definição
5.3 Parâmetros de uma Função
5.4 Conversão de Tipos
5.5 Argumentos da linha de comandos
5.6 Conclusão
6. Vectores
6.1 Introdução
6.2 Vectores na Linguagem C
6.3 Vectores como argumentos de Funções
6.4 Strings
7. Estruturas
7.1 Introdução
7.2 Definição
7.3 Operações com Estruturas
7.4 Vectores de Estruturas
7.5 Uniões
8. Ficheiros
8.1 Introdução
8.2 Abertura e Fecho de Ficheiros
8.3 Leitura e Escrita de Ficheiros
8.4 Acesso aleatório
8.5 Outras funções de Entrada / Saída
9. O Pré-Processador
9.1 Introdução
9.2 INCLUDE
9.3 DEFINE
9.4 DEFINE com argumentos
10. Bibliografia

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (2 of 2) [21/10/2002 [Link]


A Linguagem C - Introdução à Linguagem C - Dennis Ritchie Dec PDP-11 Unix Características instruções basico básico de C++ borland tutorial tutor

Introdução à Linguagem C

1.1 Introdução

As linguagens de programação evoluiram exponencialmente desde que os primeiros computadores


electrónicos foram feitos para calcular dados de telemetria durante a 2.ª Guerra Mundial, onde os
programadores trabalhavam apenas com as mais primitivas instruções, a linguagem máquina. Essas
instruções consistiam em longas cadeias de uns e zeros.

De seguida apareceram os assembladores que mapeavam mnemónicas (mais facilmente utilizadas) para a
linguagem máquina.

Com o passar do tempo, apareceram linguagens de mais alto nível como BASIC e COBOL. Estas
linguagens permitiram que os programadores utilizassem algo parecido com palavras e frases usadas
normalmente como "Let I = 100". Essas instruções eram então traduzidas para linguagem máquina por
interpretadores e compiladores.

Durante alguns anos, o primeiro objectivo de programação foi escrever pequenas porções de código que
eram executadas rapidamente. O programa precisava de ser pequeno, visto que a memória era cara e
precisava de ser executado rapidamente, porque o poder de processamento também era dispendioso. à
medida que os computadores se tornaram mais pequenos, mais baratos, mais rápidos e a memória mais
barata, as prioridades mudaram. Hoje em dia, o tempo dispendido por um programador numa aplicação é
muito mais caro do que o hardware utilizado. Código bem escrito e fácil de actualizar é a prioridade da
maioria das aplicações de hoje.

A linguagem C foi criada e implantada pela primeira vez por Dennis Ritchie num Dec PDP-11, utilizando o
sistema operativo Unix.

A linguagem C foi desenvolvida nos laboratórios Bell na década de 70, tendo surgido a partir da
necessidade de escrever programas, que utilizassem as potencialidades da linguagem máquina, mas de
uma forma mais simples e portátil que esta.

Usada inicialmente para a programação de sistemas, viria pela sua flexibilidade e poder, a tornar-se numa
linguagem de uso geral nos mais diversos contextos, sendo actualmente muito utilizada pelos
programadores profissionais.

A linguagem C pode ser considerada uma linguagem de médio nível, porque para além de possuir
instruções de alto nível e ser tão estruturada como por exemplo o PASCAL, também possui instruções de
baixo nível.

1.2 Características

As suas principais características são :

● Potencialidades e conveniência das linguagens quer de alto nível quer de baixo nível.
● Pequeno conjunto de palavras reservadas.
● Permitir a criação de novos tipos de dados pelo utilizador.
● Portabilidade. Os programas escritos em linguagem C podem ser transportados entre máquinas de

[Link] (1 of 5) [21/10/2002 [Link]


A Linguagem C - Introdução à Linguagem C - Dennis Ritchie Dec PDP-11 Unix Características instruções basico básico de C++ borland tutorial tutor

diferentes arquitecturas, com um número muito reduzido de alterações.


● Eficiência, através de uma boa ligação aos recursos da máquina.

Existem algumas particularidades na linguagem C que a tornam especialmente interessante :

● Permite conversões de quase todos os tipos de dados. (Os tipos caracter e inteiro podem ser
misturados na maioria das expressões).
● Não possui nenhuma verificação de erros em tempo de processamento (fim de vector ou
compatibilidade do tipo de argumento), cabe inteiramente ao programador saber o que o programa
está a fazer.

1.3 Estrutura de um Programa

Um programa em linguagem C é constituído por uma ou mais funções e variáveis.

Uma função contém instruções que especificam as operações de computação a serem executadas,
enquanto as variáveis armazenam os valores.

A função permite encapsular (esconder certa complexidade) alguma computação, podendo depois ser
utilizada sabendo-se apenas o que faz e sem preocupações quanto à forma como o faz.

As funções em C assemelham-se aos procedimentos e funções do Pascal. A execução de um programa


começa tipicamente numa função de nome main, que deverá existir em qualquer parte do programa.

O aspecto geral de uma função é o seguinte :

tipo_retornado nome_função(declarações de parâmetros){


declarações locais;
instruções;
}

Assim, uma função é composta por um cabeçalho seguido do respectivo corpo.

O cabeçalho é constituído pelo nome da função a que se segue entre parêntesis, uma lista de declarações
de parâmetros. Caso estes não existam, os parêntesis surgem vazios.

Quanto ao corpo da função, este é delimitado por chavetas

{ }

e contêm, declarações de variáveis, ou mesmo de outras funções, a serem utilizadas, seguidas de


instruções.

Sempre que se pretenderem incluir comentários num programa, pode-se fazê-lo colocando esses
comentários entre /* e */.

Uma função pode retornar um valor para a função que a chama, o que é conseguido com a instrução
return, sendo o seu aspecto:

[Link] (2 of 5) [21/10/2002 [Link]


A Linguagem C - Introdução à Linguagem C - Dennis Ritchie Dec PDP-11 Unix Características instruções basico básico de C++ borland tutorial tutor

return expressão;

em que,

expressão

pode ser qualquer expressão . Por exemplo :

return 5; /*Retorna a constante inteira 5 */


return val*val; /*Retorna o resultado do produto entre as variáveis

As funções são chamadas (invocadas para execução) dando-se o nome da função, juntamente com os
argumentos, entre parêntises:

nome_função(prim_arg, seg_arg, ...);

Os valores dos argumentos na chamada da função, são atribuidos aos parâmetros da função pela ordem
em que se encontram.

Exemplo 1 : Programa que imprime no ecrâ : "O meu primeiro programa !"

#include <stdio.h> /* Inclui dados sobre funções de entrada e saída


standards (standard input output), como a printf */

main(){ /* Definição da função main */


printf (O meu primeiro programa !); /*Chama a função printf */
}

O resultado da execução do programa será a impressão no ecrâ do texto contido entre aspas na função
printf. A instrução #include <stdio.h> tem por finalidade incluir no programa informação sobre funções de
entrada e saída de dados, tal como a função printf que será explicada no Capítulo 4 .

Exemplo 2 : O programa seguinte chama uma função mul(), que multiplica dois números inteiros e retorna o
resultado.

O valor retornado passa a ser o argumento da função printf() que o imprime.

Os dois parâmetros a e b da função mul(), recebem respectivamente os dois argumentos 5 e 4, com que a
função é chamada.

#include <stdio.h>

main(){
printf( A multiplicação de 5 com 4 é igual a %d,mul(5,4));
}

int mul(int a,int b){

[Link] (3 of 5) [21/10/2002 [Link]


A Linguagem C - Introdução à Linguagem C - Dennis Ritchie Dec PDP-11 Unix Características instruções basico básico de C++ borland tutorial tutor

return (a*b);
}

A impressão no ecrâ será : A multiplicação de 5 com 4 é igual a 20, o que significa que %d vai ser
substituido pelo valor retornado pela função mul().

Notar ainda que as variáveis a e b, definidas na função mul() só são reconhecidas no interior desta.

Uma variável é o nome que é dado a uma zona de memória, cujo tamanho varia conforme o tipo dessa
variável. No exemplo anterior, a e b são variáveis capazes de armazenar inteiros. Este assunto será
abordado detalhadamente na secção 2.3 .

A produção e execução de programas, depende do sistema operativo em que se esteja a trabalhar, bem
como do compilador utilizado.

A função main(), como função que é, também pode retornar um valor. Neste caso, o valor será retornado ao
ambiente exterior, responsável pela execução do programa.

Habitualmente o valor 0 significa um final sem erro, e um valor diferente de 0 um final com erro. No entanto,
e para simplificação não será utilizada a instrução return 0 nas várias funções main() aqui apresentadas.

1.4 Instruções

Uma expressão seguida de ; (ponto e virgula) é uma instrução.

Expressões são formadas por constantes, variáveis e operadores combinados de uma forma válida.

As instruções dividem-se em simples e compostas.

Simples quando se trata de apenas uma instrução, e compostas quando se trata de um conjunto (bloco) de
instruções.

Estes conceitos, de instrução simples e composta, farão mais sentido quando, no capítulo 3, forem
discutidas as instruções de controle de sequência.

Instrução simples : expressão;

Exemplo :

printf(O meu primeiro programa!);

Instruções Compostas : Instruções simples dentro de chavetas.

{
instrução;
instrução;
instrução;

[Link] (4 of 5) [21/10/2002 [Link]


A Linguagem C - Introdução à Linguagem C - Dennis Ritchie Dec PDP-11 Unix Características instruções basico básico de C++ borland tutorial tutor

...;
}

Exemplo:

{
X=10;
Y=X+X;
}

O sinal '=' significa atribuição, isto é, para o exemplo acima apresentado, à variável X foi-lhe atribuido o
valor 10.

UP FORWARD
Up Forward

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (5 of 5) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

2. Operandos e Operadores

2.1 Introdução

Na base de qualquer programa estão os operandos e operadores, pois é através destes, que
se constroem as expressões que acabarão por formar um programa.

As variáveis e as constantes constituem os operandos que representam os dados, enquanto


os operadores determinam o que lhes fazer.

Os operandos classificam-se através de três atributos:

● nome
● tipo
● classe de armazenamento

As próximas secções tratam exactamente destes atributos, fundamentais para um correcto


entendimento da linguagem C.

2.2 Nomes

Um nome ou identificador, é uma sequência de letras ou dígitos que começa


obrigatoriamente por uma letra. O sinal _ (underscore) conta como uma letra, e é
normalmente usado para simular um espaço num nome.

Nomes com letras maiúsculas são diferentes de nomes com letras minúsculas. Assim sendo,
A e a representarão dois nomes distintos.

Normalmente na linguagem C, usam-se letras minúsculas para representar as variáveis, e


letras maiúsculas para representar as constantes.

Esta utilização de maiúsculas e minúsculas não é uma regra da linguagem, mas ao ser
seguida por quem programa facilita a leitura dos programas.

As palavras reservadas int,if,else, etc. da linguagem C, não são permitidas como nomes.

Essas palavras são reservadas ao compilador para utilização da linguagem. Não podem ser
definidas classes, variáveis ou funções com esses nomes. A lista seguinte é um pouco
arbitrária, visto que algumas palavras reservadas são específicas a um tipo de compilador.

Palavras Reservadas :

[Link] (1 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

auto break case catch char class const continue default delete do double else enum extern
float for friend goto if int long mutable newo perator private protected public register return
short signed size of static structs witch template this throw type def union unsigned virtual
void volatile while

2.3 Tipos de Dados

Todas as variáveis são de um determinado tipo de dado que é especificado na definição da


variável.

Ao definir-se uma variável, seja qual for o tipo, o compilador reserva o espaço na memória
necessário a essa variável.

Em C existem quatro tipos de dados básicos, que são:

● char - caracter : 1 byte


● int - inteiro; normalmente uma palavra de computador : 2 ou 4 bytes
● float - número de virgula flutuante :normalmente 4 bytes
● double - não inferior à precisão do float; normalmente o dobro da precisão do float : 8
bytes.

Para além dos tipos de dados existem qualificadores que lhes podem ser aplicados, e que
são :

● short, long, signed, unsigned.

O qualificador short aplica-se a inteiros e tem como objectivo reduzi-los para metade do seu
tamanho (ex: numa máquina em que os inteiros (int) sejam de 4 bytes, o short int será de 2
bytes).

O long aplicado a inteiros tem a função inversa do short. O qualificador long também se
aplica ao tipo double, mas com efeitos que dependem da sua implementação no compilador.

Os qualificadores signed e unsigned são aplicados ao tipo char ou a qualquer inteiro, e


indicam se o número tem ou não sinal. No caso dos signed o seu bit mais significativo está
reservado ao sinal. Números unsigned são sempre superiores ou iguais a zero, enquanto os
signed poderão ser negativos.

Exemplificando, para o caso do char, uma variável signed char tomaria valores entre -128 e
127, enquanto que se fosse unsigned char, tomaria valores entre 0 e 255. Isto significa que
uma variável char pode conter qualquer caracter ASCII, mais exactamente os respectivos

[Link] (2 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

códigos, pois estes variam de 0 a 127 ( Existem extensões a este código onde se incluem
caracteres de desenho).

Todas as variáveis devem ser declaradas antes de serem utilizadas. Uma declaração
especifica um tipo, e contém uma ou mais variáveis desse tipo.

Exemplos disso são :

int ano,mes,dia;

que declara três variáveis do tipo inteiro cujos nomes são ano, mes e dia.

unsigned char tamanho;

declara uma variável do tipo char sem sinal, e cujo nome é tamanho. Para este caso o
compilador alocaria espaço para um caracter (1 byte).

As variáveis podem ser inicializadas no momento da sua declaração:

int x=-691;
double media=0;

Existe em C um operador para a determinação do espaço em memória ocupado por um


determinado tipo de dado, e cujo nome é sizeof. O operador sizeof devolve um valor inteiro
que é o número de bytes correspondente ao tamanho desse objecto. Por exemplo para
determinar o espaço ocupado por um inteiro usa-se :

sizeof (int);

Exercicio : Escreva um programa que diga qual o espaço reservado em memória para os
seguintes dados: char;short int; long int; float e double.

Resolução :

#include <stdio.h>
#include <conio.h>

main(){
clrscr();
printf (Tamanho dos Short Int =%d\n,sizeof (short int));
printf (Tamanho dos Long Int =%d\n,sizeof (long int));

[Link] (3 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

printf (Tamanho dos Caracteres =%d\n,sizeof (char));


printf (Tamanho dos Float =%d\n,sizeof (float));
printf (Tamanho dos Double =%d\n,sizeof (double));
}

Saída:

Tamanho dos Short Int =2


Tamanho dos Long Int =4
Tamanho dos Caracteres =1
Tamanho dos Float =4
Tamanho dos Double =8

2.4 Classes de Armazenamento

As classes de armazenamento de um identificador definem o modo como o compilador lhes


reserva espaço.

A classe de armazenamento determina para uma variável o seu tempo de vida, e o seu
âmbito (escopo) , isto é :

● tempo de vida : Tempo de vida da variável no programa.


● escopo : Porção de programa onde a variável é reconhecida.

Os objectos em C caem em duas classes gerais dependendo onde são definidas.

● locais - objectos definidos dentro de um bloco, normalmente numa função.


● globais - objectos definidos no nível mais exterior, fora da função.

As declarações/definições das variáveis incluido a sua classe de armazenamento têm a


forma geral:

classe_armazenamento tipo_dado nome_variável ;

2.4.1 Tipos de Classes de Armazenamento

São quatro as classes de armazenamento de objectos em C:

● auto: Classe de armazenamento interna para variáveis locais que existem e são
reconhecidas somente ao longo da duração da função. Todas as variáveis locais são
implicitamente auto.

[Link] (4 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

● static: O seu significado varia consoante o objecto é definido dentro ou fora de uma
função. Uma variável static quando é inicializada na sua definição só é inicializada na
primeira vez que a função é chamada. Nas chamadas seguintes vai apresentar o valor
da sua última utilização. O interesse desta classe surge quando por exemplo se
pretende que o valor de uma variável de uma função não seja destruído por uma nova
chamada a essa função. O tempo de vida destas variáveis é o da duração do
programa.
● extern:Para variáveis globais a todo o programa. Nesta classe caem por exemplo as
variáveis definidas externamente num ficheiro e que se pretende utilizar noutro ficheiro
do mesmo programa.
● register: O mesmo que auto, excepto que o compilador, se possível, escolhe locais de
memória de acesso mais rápido (registos). É normalmente utilizada para variáveis de
ciclo. Só é aplicável a variáveis do tipo int ou char.

2.5 Constantes

As constantes são, como o seu nome indica, valores fixos que não podem ser alterados
durante o programa e, têm associado a cada uma delas um determinado tipo de dado.

Os tipos de constantes inteiras são:

● Decimal
● Octal
● Hexadecimal

Para identificar o tipo de dado como unsigned usa-se o sufixo u ou U, enquanto para
significar long usa-se o sufixo l ou L, e o sufixo ul ou UL para unsigned long. O tipo int é
assumido por defeito, desde que a constante seja inteira e portanto não necessita de sufixo.

Um ponto decimal numa string (cadeia) de dígitos indica que o objecto é do tipo double.

O expoente pode ser denotado usando e ou E.

Uma constante de vírgula flutuante com o sufixo l ou L é considerada do tipo long double.
Para significar float usa-se o sufixo f ou F.

Os caracteres são denotados através de plicas, por exemplo, 'q' representa o caracter q.

Os caracteres têm uma representação interna numérica.

No código ASCII o caracter q é representado pelo inteiro (em octal ) 0161. Então, c=0161; é
equivalente a c='q';

[Link] (5 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

c=49; é equivalente a c='1';

Vários caracteres especiais podem ser representados como se segue :

\n ->newline
\t ->tab
\b ->backspace
\\ ->backslash
\r ->carriage return

Qualquer caracter pode ser especificado pelo seu equivalente numérico usando a notação
\ddd onde ddd é um inteiro octal,ou por \xddd, onde ddd é um inteiro em hexadecimal.

As sequências de escape para caracteres de não impressão são também válidas dentro de
strings de caracteres.

Por exemplo:

main()
{
printf (%s,OLA\n);
}

imprime no ecra a palavra OLA e em seguida há uma mudança de linha provocada pelo
caracter \n.

Uma constante também pode ser uma string, ou melhor, um array (vector) de caracteres em
que o último elemento é o caracter nulo (i.e, caracter cujo código ASCII é 0.

Por Exemplo para a constante ARRAY (string de caracteres), a sua representação interna
seria o conjunto de caracteres, 'A' 'R' 'R' 'A' 'Y' '\0'.

2.6 Operadores.

Os operadores em C podem dividir-se em três classes :

● Aritméticos.
● Relacionais e Lógicos.
● Bit a Bit (binários).

[Link] (6 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

Consoante os operadores envolvam um,dois ou três operandos, classificam-se em unários,


binários, ternários.

2.6.1 Operadores Aritméticos

Os operadores aritméticos são :

+ Adição

- Subtracção

* Multiplicação

/ Divisão

% Módulo (resto da divisão de inteiros)

O operador % não pode ser aplicado a números de virgula flutuante. Na divisão de inteiros a
parte fraccionária é sempre truncada. Por exemplo de 5/2 resultaria 2.

Na Linguagem C qualquer operador aritmético pode ser combinado com a atribuição, o que
significa que :

x+=2 <=> x=x+2


a/=b+c <=> a=a/(b+c)

2.6.2 Operadores Incremento e Decremento.

Os operadores incremento e decremento, ++ e -- respectivamente, podem ser usados tanto


na forma prefixa como na forma sufixa. O operador ++ soma uma unidade à variável,
enquanto o operdor -- subtrai, como se pode ver nos casos que se seguem:

● x++; <=> x=x+1;


● y=x++; <=> y=x; x=x+1;
● y=++x <=> x=x+1; y=x;

Como se constata, na forma prefixa acontece primeiro o incremento e só depois a atribuição,


enquanto na sufixa sucede o contrário.

[Link] (7 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

2.6.3 Operadores relacionais e Operadores lógicos

Estes operadores permitem a comparação de expressões.

No caso de a relação ser verdadeira, resulta o valor 1 (verdade), no caso de a relação ser
falsa resulta o valor 0.

Relacionais:

x<y menor que

x<=y menor ou igual

x>y maior que

x>=y maior ou igual

x==y comparar igualdade

x!=y comparar diferença

Lógicos:

&& and (e)

|| or (ou)

! not (negação)

2.6.4 Operador Condicional

O operador condicional é um operador ternário usado em C. O valor da expressão:

expr0 ? expr1:expr2

é o valor de expr1 se expr0 for verdadeira ou o valor de expr2 se expr0 for falsa.

[Link] (8 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

Por exemplo, a instrução

x=a>b?a:b;

é exactamente equivalente à combinação das seguintes instruções :

if (a>b)
x=a;
else
x=b;

2.6.5 Operadores Bit a Bit

Os operadores bit a bit (binários) permitem, como o nome implica, operações ao nível dos
bits. São seis os operadores bit a bit, os quais só poderão ser aplicados a expressões do tipo
inteiro:

~ complementa bits (inverte o estado dos bits)

<< desloca para a esquerda os bits

>> desloca para a direita os bits

& conjunção

^ ou exclusivo

| disjunção

As tabelas de verdade para E,OU,OU exclusivo são respectivamente :

& 0 1 | 0 1 ^ 0 1
0 0 0 0 0 1 0 0 1
1 0 1 1 1 1 1 1 0

Exemplos :

[Link] (9 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

Supôr duas variáveis x e y do tipo char, cuja representação binária é :

x=10111011
y=10101010

Os resultados de expressões envolvendo várias operações são (as operações são


executadas sobre os valores originais de x e y):

~x = 01000100
x<<2 = 11101100
y>>2 = 01010100
x&y = 10101010
x|y = 10111011
x^y = 00010001

Outros exemplos de carácter mais prático:

a=b&037 -> Atribuir a a os 5 bits de menor ordem de b.


a|=0200 ->O 8.º bit de a é posto a 1.
a&=017 -> limpa todos os bits excepto os 4 finais.
a^=077 -> reversa os últimos 6 bits
a<<=2 -> a é multiplicado por 4.
a~=b ->a fica complementar de b
a=b&1 ->a será 1 se o primeiro bit de b estiver a 1.

Atenção : Ter sempre cuidade em não confundir os operadores lógicos && e || com os
operadores binários & e |.

2.6.6 Operadores de Ponteiros

Operadores de ponteiro são importantes em C. Permitem a passagem de vectores, strings e


estruturas para funções, além de permitir que essas mesmas funções alterem o conteúdo
dos argumentos chamados. Os dois operadores de ponteiros são & e *.(Esses operadores
usam os mesmos símbolos da multiplicação e do E bit a bit, que são completamente des-
relacionados dos operadores de ponteiros).

O operador & retorna o endereço da variável a que precede.

O operador * leva o valor da variável à que precede e usa este valor como endereço da
informação na memória.

O estudo deste tipo de operadores devido à sua dimensão e complexidade, foi deslocado

[Link] (10 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

para capítulo próprio, merecendo neste espaço apenas um lugar de referência.

2.7 Precedências

O conhecimento da ordem de precedência dos vários operadores é fundamental para que se


possam construir expressões correctamente.

A tabela seguinte lista as precedências por ordem decrescente bem como o sentido de
avaliação (associatividade). Ter em atenção que alguns dos operadores indicados na tabela
ainda não foram discutidos.

Operadores Associatividade

() [] -> . da esquerda para a direita

! ^ ++ -- + - * & (tipo) sizeof da direita para a esquerda

*/% da esquerda para a direita

+- da esquerda para a direita

<< >> da esquerda para a direita

< <= > >= da esquerda para a direita

== != da esquerda para a direita

& da esquerda para a direita

^ da esquerda para a direita

| da esquerda para a direita

&& da esquerda para a direita

[Link] (11 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

|| da esquerda para a direita

?: da direita para a esquerda

= += -= *= /= %= &= ^= |= <<= >>= da direita para a esquerda

, da esquerda para a direita

2.8 Conversão de Tipos

Por vezes surge a necessidade de trabalhar operandos cujos tipos de dados diferem uns dos
outros.

Nestas situações há que proceder à conversão de tipos, isto é a conversão desses diferentes
tipos num tipo comum, de forma a possibilitar a resolução das expressões. As conversões
caem em três classes : automática, requerida pela expressão e forçada.

Automática

Feita automaticamente pelo compilador sempre que a variável seja do tipo char, short ou
float, não existindo possibilidade de perda de informação. As converssões automáticas são
feitas do seguinte modo :

char => int


short => int
float => double

Requerida pela expressão

Quando há mistura de tipos, sendo necessária para a resolução da expressão.

Exemplo:

int x;
double y; /* conversão num double seguida de */
x=x+y; /* uma conversão num inteiro */

A conversão para inteiro faz com que o resultado seja truncado.

[Link] (12 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

Forçada (cast)

Este tipo de conversão pode ser requerido pelo utilizador sempre que este o considere
necessário, e faz-se, precedendo a variável pelo novo tipo entre parêntises. Ter em atenção
que a conversão para tipos menores pode truncar a variável.

Forma Geral:

(tipo de dado) expressão;

Exemplo : A seguinte função devolve o resto da divisão de duas variáveis de virgula


flutuante.

double mod(double a,double b)


{
double temp;
temp = (int) (a/b);
temp *= b;
return (a-temp);
}

Neste exemplo o cast tornou-se necessário para que o resultado da divisão fosse um inteiro,
perdendo-se a parte fraccionária.

2.9 Typedef

Se um tipo de dado é precedido pela palavra typedef então o identificador na declaração é


entendido pelo compilador como um novo nome para esse tipo de dado.

Exemplo :Programa que calcula a área de um rectângulo . O resultado (área) é guardado


numa variável do tipo AREA, definido usando-se typedef. Assim em todas as declarações de
variáveis que representem áreas, poder-se-ia usar AREA em vez de float.

/* programa area.c */
#include <stdio.h>
typedef float AREA;
main()
{

AREA x;
float lado1, lado2

[Link] (13 of 14) [21/10/2002 [Link]


A Linguagem C - Operandos e Operadores - char int float double - escopo loca...tic extern register - aritméticos relacionais typedef precedência conversão

printf (\nIntroduza os valores dos lados: );


scanf (%f%f,&lado1,&lado2); /* scanf lê dados do teclado com o
tipo indicado entre aspas.*/ /*Neste caso 2 floats %f%f */
x=lado1*lado2;
printf (A área é igual a %f,x); /* %f indica um float para escrita */

Ter em atenção que em última instância a variável x é um float, como se prova pela
formatação (com %f) utilizada no printf().

A utilização de typedef é mais frequente com tipos de dados compostos, como se poderá ver
no capítulo dedicado a esses tipos de dados.

No exemplo anterior foi utilizada a função scanf() com dois ou mais argumentos. O primeiro
argumento, entre aspas (string), indica os tipos de dados a ler para as variáveis que ocupam
os argumentos seguintes.

BACK UP FORWARD
Back Up Forward

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (14 of 14) [21/10/2002 [Link]


A Linguagem C - Intruções de Controle e de Sequência - if switch do while for borland c++ C

3. Instruções de Controle e de Sequência

A linguagem C, como já foi dito, apresenta características de uma linguagem estruturada.


Assim sendo, possui instruções de controle de sequência, que permitem especificar a ordem
pela qual são executadas as instruções de um programa. As intruções de controle de
sequência são de dois tipos: condicionais (if e switch) e de ciclo (while, do/while e for).

Ter em atenção que quando se tem mais do que uma instrução (instrução composta) estas
deverão ser colocadas entre chavetas, como já foi afirmado anteriormente.

Existem duas instruções que permitem alterar a sequência normal de execução dos ciclos: a
instrução break e a instrução continue. A intrução break interrompe definitivamente a
execução de um ciclo , enquanto que a instrução continue interrompe a execução de uma
iteracção saltando para o inicio da iteracção seguinte. A instrucção break também é usada na
instrução switch.

3.1 Instrução IF

Esta é a instrução mais simples para controle de sequência. O seu funcionamento é o


seguinte:

Faz-se a avaliação de uma expressão, e caso ela seja verdadeira é executado um primeiro
bloco contendo uma ou mais instruções, caso contrário, será executado se existir, um
segundo bloco iniciado pela palavra else.

Existem duas formas de utilização:

if (expressão)
instrução;

ou

if (expressão)
instrução;
else
instrução;

Exemplo : Neste exemplo, a função idade(), verifica em que intervalo se situa uma idade i
dada como argumento. No caso de i ser maior do que 70 imprime Idoso, senão, se for maior
do que 30 imprime Adulto senão imprime Jovem.

[Link] (1 of 4) [21/10/2002 [Link]


A Linguagem C - Intruções de Controle e de Sequência - if switch do while for borland c++ C

void idade(int i) /* 'void' antes do nome da função para significar que esta não retorna
qualquer valor. */
{
if (i>70) printf (Idoso);
else
if (i>30) printf (Adulto);
else
printf (Jovem);
}

3.2 Instrução SWITCH

Esta instrução avalia uma expressão do tipo inteiro ou caracter, e depois compara-a com
constantes de tipo inteiro ou caracter, permitindo várias decisões(vias). Esta instrução usa-se
normalmente em situações em que existam várias possibilidades de decisão.

Sintaxe :

switch (expressão)
{
case constante1 : Instrução;
break;
case constante2 : Instrução;
break;
...
default : Instrução
break;
}

A instrução break permite sair (quebrar) do switch. Caso esta não seja incluída todas as
instruções abaixo do case seriam executadas até que surgisse um break ou a chaveta que
termina o switch. A instrução default é opcional e é avaliada quando nenhuma das
constantes coincide com o resultado da expressão.

3.3 Ciclo WHILE

Esta instrução é usada quando se pretende que um bloco de instruções seja executado
enquanto uma determinada condição for verdadeira. O teste da condição é feito no inicio de
cada ciclo, sendo possível que as instruções não sejam executadas uma única vez. O ciclo
while sem nenhuma condição é considerado sempre verdadeiro, dando origem a um ciclo
infinito (do forever).

[Link] (2 of 4) [21/10/2002 [Link]


A Linguagem C - Intruções de Controle e de Sequência - if switch do while for borland c++ C

Sintaxe :

while (expressão)
instrução simples ou composta;

A instrução é executada enquanto a expressão é verdadeira.

3.4 Ciclo DO-WHILE

Esta construção é idêntica ao ciclo while. Enquanto que no ciclo while o teste da condição é
feito no fim de cada iteracção, no do-while o teste é feito no fim. Assim, mesmo que a
condição seja sempre falsa, o bloco de instruções é executado pelo menos uma vez (a
primeira).

Sintaxe:

do
instrução simples ou composta
while (expressão);

3.5 Ciclo FOR

A instrução for é aquela que habitualmente mais se utiliza na construção de ciclos em C. Isto
deve-se ao seu poder e flexibilidade, como poderá ser observado. Identicamente ao while, a
condição de teste é feita no inicio do ciclo.

Sintaxe:

for (inicio;teste;incremento)
instrução

Gramaticalmente, os três componentes são expressões.

A inicio correspondem expressões normalmente da inicialização da(s) variável(is) de controle


do ciclo (se correspondem a mais do que uma as expressões devem ser separadas por
virgula.

A teste correspondem as condições de execução de cada ciclo.

Em incremento são normalmente efectuados os incrementos das variáveis de ciclo (se forem
mais do que uma as expressões deverão ser separadas por virgula).

[Link] (3 of 4) [21/10/2002 [Link]


A Linguagem C - Intruções de Controle e de Sequência - if switch do while for borland c++ C

Na primeira iteração do ciclo for é executado inicio, depois teste, em seguida se teste resultar
verdadeiro é executado instrução (composto por uma ou mais instruções), e por último
incremento nas restantes iteracções do for, inicio não é executado.

O ciclo for pode ser facilmente convertido num ciclo while com o seguinte aspecto:

inicio;
while (teste)
{
instrução;
incremento;

BACK UP FORWARD
Back Up Forward

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (4 of 4) [21/10/2002 [Link]


A Linguagem C - Operações de Entrada e Saída - printf scanf stdio.h

4. Operações de Entrada e Saída

4.1 Introdução

Nos capitulos anteriores utilizaram-se algumas funções de entrada e saída de dados que, só
agora serão explicadas com mais pormenor. Estas funções, não são intrínsecas à linguagem,
tendo sendo desenvolvidas à parte e encontram-se em bibliotecas (conjunto de ficheiros
fonte compilados e agrupados num ficheiro). As funções básicas de input e output
disponíveis em todas as implementações de C constituem a biblioteca de rotinas standard
(Standard library routines). Várias declarações e macros necessárias a estas rotinas são
incluidas num programa através da linha

#include <stdio.h>

4.2 Saída Formatada

As rotinas de output formatado aqui apresentadas são :

printf (s_control,arg1,arg2,...);

Escreve a string de controle 's_control' no terminal. Os argumentos serão introduzidos na


string de controle de acordo com as especificações nelas existentes.

sprintf (buf,s_control,arg1,arg2,...);

O mesmo que printf() excepto que o output é colocado num buffer (i.e. um array)
especificado por buf.

4.2.1 Especificações da Saída Formatada

As especificações do formato para printf() começam com um caracter % e terminam com um


caracter de conversão. Existem várias opções e caracteres de conversão possíveis. Os
caracteres de conversão, e as resultantes interpretações dos correspondentes argumentos
são os seguintes:

● c => Um caracter simples.


● d => Inteiro na notação decimal
● o => Inteiro na notação octal (não esquecer o zero do número, que deve ser incluido
explicitamente)
● x => Inteiro na notação hexadecimal (não esquecer o '0x' do número
● u => Inteiro sem sinal em notação decimal

[Link] (1 of 5) [21/10/2002 [Link]


A Linguagem C - Operações de Entrada e Saída - printf scanf stdio.h

● s => Array de caracteres; os caracteres são imprimidos em sucessão até o caracter


nulo '\0' ser alcançado
● f => float ou double, imprimido em notação decimal de acordo com a especificação
adicional descrita abaixo.
● e => float ou double, imprimido em notação cientifica de acordo com a especificação
adicional descrita abaixo.
● g => float ou double, imprimido como um %e ou %f.

Qualquer outro caracter é imprimido literalmente; por exemplo, printf (%%) imprime o sinal de
percentagem. Os números são escritos justificados à direita.

As especificações podem opcionalmente incluir (na ordem seguinte):

● Um sinal menos que indica que o argumento deve ser justificado à esquerda no campo
de output.
● Uma string de dígitos que especifica a largura mínima do campo para este
[Link] o argumento convertido tiver menos caracteres é encostado à esquerda
(ou à direita se o argumento é um ente justificado à esquerda).
● Um ponto que separa a largura do campo de precisão.
● Uma string que especifica o n.º máximo de caracteres a ser imprimidos da string, ou
(se foi imprimido um n.º de virgula flutuante) o n.º de digitos a ser imprimido à direita
do ponto [Link] isto é omitido para o n.º de virgula flutuante, a precisão por
defeito é 6.
● O caracter l indica que o argumento é um long.

Exemplos : Saídas da impressão com printf da string Instituto Politécnico, simulando os


espaços em branco com _ (Underscore).

%24s ________Instituto Politécnico


%-24s Instituto Politécnico________
%24 16s ________Instituto Polité
%-24 16s Instituto Polité________
%16s Instituto Polité

4.3 Entrada Formatada

A rotina scanf() de input formatado torna o input numa forma que é rigorosamente o inverso
do printf(). A sintaxe é:

scanf(s_control,arg1,arg2,...);

[Link] (2 of 5) [21/10/2002 [Link]


A Linguagem C - Operações de Entrada e Saída - printf scanf stdio.h

onde s_control é uma string. O input é lido e interpretado de acordo com a string de controle.
Cada um dos restantes argumentos deverá ser um endereço, o input é armazenado nesse
endereço tendo em atenção as especificações de conversão da string de controle.
Se se pretender ler um inteiro, a tendência será para escrever

int i;
scanf (%d,i);

tal, no entanto, não funciona, porque os argumentos da scanf devem ser endereços.

Assim, dever-se-á escrever,

scanf (%d,&i);

em que,& é o operador que permite obter o endereço da variável.

Deve-se ter em atenção que a situação é distinta quando se pretende ler uma string, pois o
nome da string é um endereço, como se discutirá no capítulo sobre arrays.

Um dos erros mais comuns com scanf é esquecer isto; fazer sempre com que todos os
argumentos da função scanf sejam endereços.

A função

sscanf (buf,s_control,arg1,arg2,...);

funciona mais ou menos como a scanf excepto que lê dados de uma string buf em vez de os
ler do teclado.

A string de controle das funções scanf, ou sscanf pode conter espaços brancos (os quais são
ignorados), especificações de conversão e caracteres vulgares.

4.3.1 Especificações da entrada formatada

Especificações de conversão consistem no caracter %, no caracter opcional de supressão de


atribuição *, num n.º opcional especificando a largura máxima do campo, e no caracter de
conversão.

Os caracteres vulgares são esperados para combinar com o próximo caracter não branco do
input. Se a supressão de atribuição é indicada com *, então o próximo campo de input é

[Link] (3 of 5) [21/10/2002 [Link]


A Linguagem C - Operações de Entrada e Saída - printf scanf stdio.h

saltado. Os caracteres de conversão possíveis e as correspondentes interpretações de input


são :

d => Inteiro decimal


o => Inteiro octal
x => Inteiro hexadecimal
c => Caracter simples: neste caso o salto normal de espaçoes brancos é suprimido no array
de caracteres.
s => neste caso o argumento deve ser o endereco de um array de caracteres
suficientemente grande para armazenar o input (incluindo o caracter nulo). Os caracteres são
lidos até ser encontrado um espaço.
f => N.º de virgula flutuante, possivelmente incluindo o sinal e expoente.
e => o mesmo que 'f'.

Se os caracteres de conversão d,o ou x, são precedidos por um l, o input correspondente é


interpretado como um número de vírgula flutuante de precisão dupla, double.

O argumento correspondente deve ser um endereço de um double em vez de um float.


Esquecer isto é outro erro comum quando se utiliza a função scanf.

A função scanf pára quando atinge o fim da string de controle ou quando o input falha ao
tentar cumprir com a especificação de controle. Retorna como valor, o n.º de campos de
entrada que cumpriram e aos quais tenham sido atribuídos valores.

4.4 Outras funções da Biblioteca Standard.

Para além das funções de entrada e saída formatada já estudadas, existem outras funções
também muito importantes. Estas funções tambem requerem a instrução de inclusão do
ficheiro stdio.h.

Ler um caracter do standard input (teclado) :

int c;
c=getchar();

Esta funcao retorna um inteiro correspondente ao caracter entrado, ou o valor da constante


EOF se atingiu o fim do ficheiro ou ocorreu um erro.

Escrever um caracter no standard output:

char string[80]
puts(string);

[Link] (4 of 5) [21/10/2002 [Link]


A Linguagem C - Operações de Entrada e Saída - printf scanf stdio.h

Ler uma string do standard input terminada com \n:

gets(string);

A string lida é colocada em string. A função retorna o valor da constante NULL quando
encontra o fim do ficheiro ou em caso de erro.

4.5 Outras funções

Todas as funções apresentadas têm em comum, o fazer parte da livraria (biblioteca)


standard, no entanto os compiladores oferecem outras funções. Estas dependem
normalmente do sistema, e como tal, exploram bastante bem as suas potencialidades.

São apresentadas as duas funções seguintes que existem na generalidade dos


compiladores:

c=getche();

em que c é um inteiro. Esta função permite ler um caracter do teclado,sem necessidade de


em seguida se digitar a tecla [ENTER]. O caracter lido é mostrado (ecoado) no ecrâ.

c=getch();

Idêntica à anterior apenas com a diferença de não mostrar o caracter lido no ecrã (stdout). O
facto de estas funções não necessitarem que a tecla [ENTER] seja premida, faz com que
seja de grande interesse a sua utilização.

Normalmente, é necessário a inclusão da instrução:

#include <conio.h>

para a sua utilização.

BACK UP FORWARD
Back Up Forward

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (5 of 5) [21/10/2002 [Link]


A Linguagem C - Funções function declaração int float char argumentos parâmetrosstatic extern argc argv

5. Funções

5.1 Introdução.

Um programa em linguagem C pode ser composto por uma (função main()) ou mais funções,
distribuídas por um ou mais ficheiros.

As funções são a única forma de se agruparem as instruções que se pretendem executar,


constituindo assim uma unidade básica na programação em C.

A linguagem C está feita de modo a que se construam facilmente funções muito eficientes,
de tal forma que podem ser utilizadas em diferentes programas sem alterações.

5.2 Definição.

Relembrando do primeiro capítulo, a forma geral da definição de uma função é :

classe_armazenamento tipo_dado nome(declarações_lista_de_parâmetros)


{
declarações das variáveis locais
instruções
}

Sempre que se pretenda que uma função retorne um valor, então deverá ser incluída a
instrução return.

As variáveis da lista de parâmetros podem ser consideradas como variáveis locais, que são
inicializadas com os valores dos argumentos da chamada da função.

O tipo de dado que precede o nome da função é o tipo do objecto que a função retorna. Por
exemplo, a definição double raiz(double num) significa uma função que retorna um double.

Os tipos podem ser portanto os mesmos que os definidos para as variáveis.

Se o tipo de uma função não é declarado explicitamente, então o tipo retornado por defeito é
int. E se algum dos parâmetros não tiver a declaração explicita do tipo, este é também
assumido como int.

Uma função retorna automaticamente quando atinge o fim do corpo da função, a não ser que
antes encontre a instrução return. A sintaxe da instrução return é :

[Link] (1 of 7) [21/10/2002 [Link]


A Linguagem C - Funções function declaração int float char argumentos parâmetrosstatic extern argc argv

return(expressão);

Os parêntises em torno da expressão são opcionais. O tipo da expressão deverá estar de


acordo com o tipo da função. Se uma função retorna um não inteiro então qualquer rotina
que a chame deve declarar o tipo do objecto que ela retorna. Eis a distinção entre :

● Definição da função -> Dá o código da função.


● Declaração da função -> Somente informa o compilador do tipo de objecto retornado.

Exemplo : Neste exemplo é calculada a raiz quadrada de um número, pelo método de


Newton. Em main() é declarada a função raiz(), para que o compilador saiba qual o tipo de
dado que ela retorna.

/* program raiz.c */
main()
{
float a,r,raiz(); /* Declaração da função raiz() */
printf (\n Introduza um número:);
scanf(%f,&a);
r=raiz(a);
printf (\nA raiz quadrada de %f é %f,a,r);
}

/* Função Raíz Quadrada através da iteracção do método de Newton. */


float raiz(float x) /* Definição da função 'raiz' que retorna um float . */
{
float y,z
y=x;
do
{
z=y;
y=(z+x/z)/2;
}
while (z!=y);
return (y);
}

No contexto das funções existem dois conceitos importantes que por vezes dão origem a
alguma confusão:

● Argumentos - Lista de variáveis, constantes ou expressões colocados entre os


parêntises da função aquando da chamada desta. No exemplo anterior, na chamada

[Link] (2 of 7) [21/10/2002 [Link]


A Linguagem C - Funções function declaração int float char argumentos parâmetrosstatic extern argc argv

raiz(a), a é o argumento.
● Parâmetros - Lista de declarações de variáveis aquando da definição da função. No
exemplo anterior a lista de parâmetros da função raiz(float x) é apenas float x.

Muitas funções, não retornam qualquer valor. A forma de o declarar explicitamente é usando
o tipo de dado void. Uma declaração deste tipo, pode ser :

void inverte(char str[]) /* Função que não retorna qualquer valor */


{
...
}

Quanto à classe de armazenamento de uma função pode ser :

● static, significando que a função só é visível no ficheiro onde está definida.


● extern, significando que a função já foi definida em outro local ou ficheiro
● não existir classe de armazenamento tratando-se portanto de uma função global.

5.3 Parâmetros de uma Função

Em C, os argumentos para as funções são passados via chamada por valor, ao passo que
em Pascal e Fortran são chamados via chamada por referência.

A passagem por valor significa que a uma função (mais concretamente aos seus parâmetros
), são apenas passados os valores dos argumentos, enquanto na chamada por referência é
como se fossem passadas as próprias variáveis.

Em Pascal, duas variáveis podem ser trocadas através da chamada ao seguinte


procedimento:

procedure troca(var x,y:integer)


var
temp:integer
begin
temp:=x
x:=y;
y:=temp;
end

O equivalente em Fortran,seria :

[Link] (3 of 7) [21/10/2002 [Link]


A Linguagem C - Funções function declaração int float char argumentos parâmetrosstatic extern argc argv

SUBROUTINE TROCA(X,Y)
INTEGER X,Y,TEMP
TEMP=X
X=Y
RETURN
END

O equivalente em C, seria ineficaz:

troca(x,y)
int x,y
{
int temp;
temp=x;
x=y;
y=temp;
}

Esta rotina troca unicamente os valores das variáveis da função na stack, e deixa os valores
originais da rotina chamadora inalteráveis. Supondo que troca() era invocada do seguinte
modo:

int a=1,b=2;
troca(a,b);

seriam trocados os valores de x e y da função mas manter-se-iam inálteráveis os de a e b.


Para que na função se pudessem alterar os valores das variáveis da função chamadora,
haveria que passar os endereços dessas variáveis, e os parâmetros da função teriam que
ser apontadores. Então a função troca() seria invocada do seguinte modo:

int a=1,b=2;
troca(&a,&b);

e teria o seguinte aspecto, com as variáveis X e Y definidas como apontadores para inteiros
(ou seja, variáveis que guardam endereços de posições de memória onde estão
armazenados inteiros):

troca (int *x, int*y)


{
int temp;
temp=*x;
*x=*y;

[Link] (4 of 7) [21/10/2002 [Link]


A Linguagem C - Funções function declaração int float char argumentos parâmetrosstatic extern argc argv

*y=temp;
}

Quer isto dizer que X e Y receberam os endereços de a e b respectivamente, e que através


do operador de conteúdo de um endereço (*), podem aceder aos conteúdos desses
endereços.

5.4 Conversão de Tipos.

O valor de uma expressão numa instrução return é convertido para o tipo da função através
das regras de conversão de tipos de dados. Com efeito, um cast para o tipo apropriado é
inserido automaticamente em qualquer instrução return. Por exemplo, a função atoi() (que
converte uma string num inteiro) pode ser escrita em termos duma rotina de biblioteca atof()
(a qual converte uma string para um número de vírgula flutuante) como se segue :

atoi(char s[])
{
double atof();
return atof(s);
}

O valor produzido pela função atof() é automaticamente convertido para inteiro na instrução
return, em virtude da função atoi() retornar um inteiro.

As únicas conversões de tipo efectuadas durante a avaliação de expressões numa lista de


argumentos são as conversões de tipo automático: Assim, nas outras situações há que forçar
a conversão, como no exemplo seguinte, em que a função log() espera um argumento do
tipo double:

int n;
double x,log();
x=log((double)n);

e em que foi feito o cast da variável n de inteiro para um double.

5.5 Argumentos da Linha de Comandos

É possível em C passar valores para o programa através da linha de comandos. Estes


valores são passados à função main(). Nesta função usam-se habitualmente 0 ou 2

[Link] (5 of 7) [21/10/2002 [Link]


A Linguagem C - Funções function declaração int float char argumentos parâmetrosstatic extern argc argv

parâmetros formais. Esses dois parâmetros formais da main() estão relacionados com os
argumentos de linha de comando que são dados na chamada do programa. A maior parte
dos programadores escolhe os nomes argc e argv para estes dois parâmetros:

main( int argc, char argv[])


{
...
}

O primeiro parâmetro argc é o número de argumentos da linha de comando (isto é, palavras


na linha de comando separadas por espaços brancos).

O segundo parâmetro argv é um array de strings (cada string é um array de caracteres)


representando os argumentos da linha de comando.

Como o nome do próprio programa que é executado está em argv[0], então o argc é sempre
no mínimo 1. O primeiro argumento verdadeiro está em argv[1] e o último está em argv[argc-
1].

argv[argc] possui normalmente um valor para distinção (por exemplo NULL).

Compreender-se-á melhor esta secção após a leitura do capítulo 6 sobre vectores.

5.6 Conclusão

Como conclusão, recapitulam-se em seguida alguns aspectos mais importantes sobre


funções:

● Permitem dividir o programa em partes funcionais mais pequenas.


● Podem residir em bibliotecas e/ou noutros ficheiros fonte.
● A comunicação do exterior para a função é feita através dos argumentos.
● A comunicação da função para o exterior é feita através de um valor de retorno, sendo
este do mesmo tipo da função.
● Todas as funções têm um determinado tipo associado.
● A definição da função pode ser feita em qualquer ponto.
● A função pode invocar-se a si própria (recursividade).
● Uma função cujo tipo é antecedido por static só é visível no ficheiro onde está definida.

BACK UP FORWARD
Back Up Forward

[Link] (6 of 7) [21/10/2002 [Link]


A Linguagem C - Funções function declaração int float char argumentos parâmetrosstatic extern argc argv

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (7 of 7) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

[Link]

6.1 Introdução

Supor, que se pretendia um programa para ler a média das notas de cada um dos alunos de
uma escola, calcular a média das médias, e depois para cada aluno determinar o desvio da
sua média relativamente à média das médias. Uma solução para guardar cada uma das
médias, seria definir por exemplo 3000 variáveis (número hipotético de alunos), por exemplo
:

float med_1,med_2,med_3,med_4,med_5,med_6,med_7,med_8, ... ;

até med_3000, mais as instruções para a leitura das médias:

printf (\n Introduza a média do aluno n.º1:);


scanf (%f,med_1);

3000 vezes, o que se revela completamente impraticável. Seria preferível a possibilidade de


definir as 3000 variáveis de uma só vez, por exemplo da seguinte forma:

float media[3000];

em que media[0] guardaria a média do aluno 1, media [1] a do aluno 2, e assim


sucessivamente fazendo variar o valor do indice até 2999. Para melhorar o processo seria
conveniente definir uma variável para indice, por exemplo:

int num;

Deste modo, para a leitura das 3000 variáveis, poder-se-ia utilizar um ciclo, como a seguir se
ilustra:

for (num=0;num<3000;num++)
{
printf (\n Introduza a média do aluno n.º %d,num);
scanf (%f,media[num]);
}

o que representaria uma melhoria extraordinária relativamente à primeira solução.


Felizmente a generalidade das linguagens de programação fornecem este tipo de dados,

[Link] (1 of 8) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

chamados vectores (neste texto é usado também o termo array para significar vector), os
quais se explicam nas próximas secções.

6.2 Vectores na Linguagem C

A linguagem C permite definir novos tipos de dados a partir dos existentes. Os arrays, ou
vectores, são um conjunto de elementos do mesmo tipo, agrupados com o mesmo nome, e
diferenciados através de um índice entre parêntises rectos. Antes de mais, convém salientar
que os arrays estão fortemente ligados aos apontadores, os quais não serão aqui abordados.

Em C existem apenas arrays unidimensionais e o tamanho de um array deve ser fixo e


definido por uma constante na altura da compilação. No entanto, um elemento de um array
pode ser um objecto de qualquer tipo, inclusivé outro array. Isto faz com que seja possível
simular array multidimensionais.

A melhor forma de entender o modo de funcionamento dos arrays, é perceber a sua


declaração. Por exemplo,

int a[4];

diz que a é uma variável do tipo array de 4 elementos do tipo int. A sua representação será:

___ ___ ___ ___


a[0]a[1]a[2]a[3]

em que cada posição quarda um inteiro.

Como se pode ver, os elementos do array ocupam posições de memória contíguas e o seu
índice varia obrigatoriamente de 0 a 3. Ou seja, tem-se, para essas 4 posições os elementos

a[0], a[1], a[2], a[3]

que são tratados como se fossem quatro variáveis distintas.


Atribuindo os valores 1,2 e 3 repectivamente, aos três primeiros elementos,

a[0]=1;
a[1]=2;
a[2]=3;

virá:

[Link] (2 of 8) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

_1_ _2_ _3_ ___


a[0]a[1]a[2]a[3]

Convém ainda saber que o nome array é uma constante e representa o endereço da 1.ª
posição do array. Isto é:

a==&a[0] /* O operador & dá o endereço da variável. Neste caso dá o endereço de a[0]*/

Supondo que o vector se iniciava na posição de memória com o endereço 100, e que cada
inteiro gasta 2 bytes, ter-se-ia:

a==100
&a[0]==100
&a[1]==102
&a[2]==104
&a[3]==106

Em virtude de ser uma constante, não é possível atribuir valores ao nome de array, como se
ilustra no seguinte caso:

int a[4];
a=2

a[0]=2;
a[0]++;
a[1]=2*a[0];

A atribuição na segunda instrução é inválida. Também quando se passa um array como


argumento de uma função, na realidade o que é passado para a função é o seu endereço,
como se viu com a função scanf.

A dimensão de um vector é determinado pelo produto das suas linhas pelas suas colunas. A
seguinte declaração:

int ecra[25][80];

diz que ecra é um array de 25 arrays de 80 elementos inteiros cada. Assim, sizeof(ecra) será
2000 (25*80).
A inicialização de um array pode ser feita no momento da sua definição:

int a[4]={1,2,3};

[Link] (3 of 8) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

irá definir (criar) um vector de quatro inteiros e inicializar a[0] a 1, a[1] a 2, e a[2] a 3. No
entanto a definição:

int a[]={1,2,3};

irá definir um vector de apenas três elementos e inicializa-los de forma idêntica ao anterior. O
vector é criado com apenas 3 posições em virtude de não ser explicitado entre parêntises o
número de elementos, e portanto este número será determinado pela lista de inicialização.
No caso de um array ser multidimensional a inicialização obedece às mesmas regras.
Por exemplo :

int m[][3]={1,2,3,11,22,33};

ou

int m[][3]={{1,2,3},{11,22,33}};

em que se obtém os seguintes valores para cada elemento:

m[0][0] é igual a 1
m[0][1] é igual a 2
m[0][2] é igual a 3
m[1][0] é igual a 11
m[1][1] é igual a 22
m[1][2] é igual a 33

1 2 3

11 22 33

Exemplo 1: O programa media.c lê 100 notas para um array, e calcula a média das notas.

/* Programa media.c*/

#include <stdio.h>

main()
{

[Link] (4 of 8) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

int i;
float notas[100],soma;

/* Ciclo que lê 100 notas e armazena-as no vector notas.*/


for (i=0;i<100;i++)
{

printf (Nota %d=?,i+1);


scanf(%f,&notas[i]);

/* A variável acumuladora soma inicializada a zero.*/


soma=0;
/* Ciclo que soma as 100 notas. */
for (i=0;i<100;i++)

soma=soma+notas[i];

printf (A média é = %f,soma/100);

Como cada elemento do vector notas é um inteiro, há necessidade na função scanf de lhe
aplicar o operador & como acontece com qualquer outro inteiro.

6.3 Vectores como Argumentos de Funções

Para melhor se compreender este assunto observe o seguinte exemplo:

O seguinte programa testa uma função que troca os dois primeiros elementos de um vector
dado como argumento.

#include <stdio.h>
void troca(); /*Declara a função como não retornando qualquer valor*/
main()
{

int v[2];
v[0]=2;
v[1]=3;

[Link] (5 of 8) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

troca (v);
printf (v[0]=%d,v[1]=%d,v[0],v[1]);

void troca(int x[2])


{

int t;
t=x[0];
x[0]=x[1];
x[1]=t;

O resultado será v[0]=3 e v[1]=2. Neste exemplo é passado como argumento da função o
nome do vector, que é o endereço da 1.ª posição do array. Assim x vai representar também
um endereço, o de v[0] que é o mesmo de x[0], e portanto as alterações feitas na função
terão repercussões nas variáveis da função chamadora.

Na definição da função também seria possível e com os mesmos resultados, ter int x[] em
lugar de int x[2], sendo nesse caso x dimensionado automaticamente a 2.

Supôr que o endereço de v[0] é 200, então é porque v=200 como mostra a figura:

(Supondo uma máquina de inteiros com 2 bytes, v[1] virá 2 bytes à frente (202)).

v=200

Designação: v[0] v[1]


Conteúdo: 2 3
Endereço: 200 202

então a chamada da função

troca(v); <=> troca(200);

em que ao nome do array x corresponderá o valor de 200, ou seja, x será igual a 200

[Link] (6 of 8) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

x=200

Designação: x[0] x[1]


Conteúdo : 2 3
Endereço : 200 202

o que implica que após as trocas ficará:

Conteúdo : 3 2
Endereço : 200 204

Estas posições de memória(endereços) correspondem também a v[0] e a v[1],


respectivamente.

6.4 Strings

Em C, não existe o tipo de dado string. Pode no entanto ser simulado através de um array de
caracteres. Por convenção, delimita-se a string com o caracter nulo (\0). Isto é, coloca-se o
caracter nulo na primeira posição não preenchida do array. Assim quando se define o
tamnho do array de caracteres para ser usado como string é necessário contar com mais
uma posição.

A standard library fornace um conjunto de funções para a manipulação de strings. Estas


funções pressupõem que as strings que lhes são passadas são terminadas com o caracter
nulo.

int strlen(char s[]);

devolve o comprimento da string s. Exemplo:

char s[]=OLA;
printf (Comprimento da String==%d,strlen(s));

A definição anterior além de inicializar o array com a string, também o dimensiona como um
vector de quatro caracteres, como mostra a figura seguinte:

'O' 'L' 'Á' '\0'

Quanto à saída de printf, ela seria: Comprimento da String == 3.

[Link] (7 of 8) [21/10/2002 [Link]


A Linguagem C - Vectores - apontador argumento função string char array

strcpy (char destino[], char origem[]);

Copia origem para destino. Exemplo:

char destino[]=ADEUS,origem[]=OLA;
strcpy(destino,origem);
printf (%s,destino);

a saida é OLA.

strcat (char primeira[], char segunda[]);

concatena (acrescenta) a string segunda à string primeira.

int strcmp(char s1[],char s2[]);

Compara s1 com s2,e devolve 0 se s1 igual a s2, >0 se s1>s2 e <0 se s1<s2.

Uma lista completa destas funções pode ser encontrada nos manuais de qualquer
compilador de C. Para a utilização destas funções, é requerida a linha

#include <string.h>

Estas funções podem ser facilmente construídas pelo programador.

BACK UP FORWARD
Back Up Forward

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (8 of 8) [21/10/2002 [Link]


A Linguagem C- Estrutura struct unions union - definição

7. - Estruturas

7.1. Introdução

Para resolver o problema de ter uma variável constituída por tipos de dados diferentes,
utilizam-se as estruturas que são explicadas em seguida.

7.2. Definição

Uma estrutura é um tipo de dado composto que consiste em uma ou mais variáveis
agrupadas sob um nome. As variáveis na estrutura podem ter tipos diferentes, mas
normalmente existe uma relação entre eles que faz com que seja conveniente tratá-los
conjuntamente como um objecto no programa. Em Pascal a noção análoga é um tipo de
dado, definido pelo utilizador,chamado record. Os componentes individuais de uma estrutura
são chamados membros. Uma declaração de estrutura tem a forma:

struct nome_estrutura
{

Declarações_dos_membros

};

Isto tem o efeito de definição de um novo tipo de dado. Aqui nome_estrutura é um nome
arbitrário e struct nome_estrutura pode ser pensado como o nome de um novo tipo de dado.
As Declarações_dos_membros são como quaisquer outras declarações, excepto que não
definem variáveis mas nomes de componentes de uma instância da estrutura
nome_estrutura.

Alguns exemplos:

struct num_complexo
{

double real;
double imaginário;

};

struct data
{

[Link] (1 of 6) [21/10/2002 [Link]


A Linguagem C- Estrutura struct unions union - definição

int ano;
char mes[10];
int dia;

};

struct venda
{

char comprador[SIZE];
double quantidade;
struct data quando;

};

Neste último caso existe uma estrutura encaixada noutra. Estas declarações não definiram
quaisquer variáveis, elas meramente definiram novos tipos de dados e portanto, não lhes foi
reservado espaço de memória. Qualquer definição de variáveis do tipo destas anteriores
utiliza as mesmas regras que para qualquer outro tipo de dado. Como exemplo:

struct data d; /* d é uma variável do tipo struct


data */
struct venda a[20] /* a é um array de 20 estruturas*/
struct num_complexo x,y,z;

nestes casos são definidas variáveis e consequentemente é-lhes reservado espaço em


memória.

Os membros das estruturas são acedidos da seguinte forma:

variável_estrutura.membro;

Exemplos :

struct data d;
[Link]=1993
strcpy([Link],Fevereiro);
[Link]=4;

struct venda s;
[Link]=24

[Link] (2 of 6) [21/10/2002 [Link]


A Linguagem C- Estrutura struct unions union - definição

[Link]=1994

Repare-se que o membro da estrutura imbricada foi acedido da mesma [Link]


exemplos são:

struct complexo x,y


[Link]+=[Link];
[Link]ário+=[Link]ário;

As variáveis do tipo estrutura podem ser inicializadas na altura da sua definição, colocando-
se a lista de inicializações a seguir à definição. Por exemplo,

struct complexo z={1,-1};

7.3 Operações com Estruturas

As operações fundamentais que podem ser aplicadas às estruturas são:

● Tomar o endereço de uma estrutura com o operador &


● Aceder aos membros da estrutura com o operador.
● Atribuição de variáveis de estrutura, por exemplo,

struct data d1,d2;


d1=d2;

● Passar uma estrutura para uma função, por exemplo,

struct data d;
imprime_data(d);

● Retorno de uma estrutura por uma função, por exemplo,

struct data d,aniversario();


d = aniversario(Portugal);
em que aniversario é uma função que retorna uma estrutura struct data.

Exemplo : A função soma_complexo, adiciona dois números complexos e retorna o


resultado.

struct complexo soma_complexos(struct complexo n1, struct complexo n2)


{

[Link] (3 of 6) [21/10/2002 [Link]


A Linguagem C- Estrutura struct unions union - definição

struct complexo soma;


[Link]=[Link]+[Link];
[Link]=[Link]+[Link];
return soma;

Apesar de não existir qualquer conflito entre membros e variáveis com o mesmo nome, é
necessário ter o maior cuidado com esta prática, de forma a que não prejudique a clareza
dos programas.

7.4 Vectores de Estruturas

As estruturas, como qualquer outro tipo de dado podem ser agrupadas em vectores.

Exemplo 1 : Neste exemplo é criado um novo tipo de dado struct data e definida uma variável
feriado do tipo array de 5 estruturas struct data.

struct data {int dia, char mes[10], int ano};


struct data feriado[5] = {{1,Janeiro,1993},
{10,Junho,1993},
{25,Dezembro,1993}};

Para simplificar as declarações muito extensas, é conveniente atribuir nomes aos tipos de
estruturas. Por exemplo:

typedef struct data {int dia,char mes[10], int ano} DATA;

agora DATA representa o tipo de dado struct data, passando a poder ser usado em lugar
deste.

7.5 Unions

Uma union (união) permite criar variáveis capazes de suportar diferentes tipos de dados, no
mesmo espaço de memória em momentos diferentes. A declaração de uma union é similar à
declaração de uma estrutura. A diferença é que com uma struct é alocado de uma vez
espaço suficiente para todos os objectos, enquanto que com uma union só é alocado espaço
para o maior dos objectos que a compõem, A declaração,

union Valor{

[Link] (4 of 6) [21/10/2002 [Link]


A Linguagem C- Estrutura struct unions union - definição

int ivalor;
double dvalor;
char cvalor;

}val;

significa que val poderá armazenar ou um inteiro, ou um double, ou um char.

O programador é responsável pelo conhecimento de qual dos tipos foi armazenado mais
recentemente na variável val. A sintaxe para aceder ao conteúdos de uma variável union é
exactamente a mesma que para as estruturas. Seguidamente é mostrado o extracto de um
programa em que é utilizada a union acima descrita.

/* Definição de constantes */
#define INT 0
#define DOUBLE 1
#define CHAR 2

int tipo;
...
switch (tipo)
{

case INT:

printf (%d,[Link]);
break;

case DOUBLE:

printf (%lf,[Link]);
break;

case CHAR:

printf (%c,[Link]);
break;

O programa imprime um inteiro, um double ou um caracter dependendo do valor de tipo.

[Link] (5 of 6) [21/10/2002 [Link]


A Linguagem C- Estrutura struct unions union - definição

BACK UP FORWARD
Back Up Forward

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (6 of 6) [21/10/2002 [Link]


A Linguagem C - Ficheiros file stdin stdout stderr fopen fclose fread fwrite fprintf fscanf feof

8. - Ficheiros

8.1. Introdução

Até ao momento, todos os dados têm sido inseridos nos programas através do teclado,
sendo guardados em variáveis, as quais residem em memória central (também chamada de
R.A.M, memória primária ou volátil) . Esta apresenta no entanto os inconvenientes de ser
volátil e cara, pelo que se torna desinteressante para o armazenamento durante periodos
que excedam o de execução de um programa. Para armazenamentos mais demorados é
utilizado outro meio, a que se chama memória secundária ( i.e. o disco rígido, ou a disquete),
em que a informação é armazenada sob a forma de ficheiros. A utilização destas estruturas
(ficheiros) na linguagem C será o assunto deste capítulo. As funções que irão ser
estruturadas fazem parte da biblioteca padrão, e portanto obrigam à inclusão nos programas
da seguinte linha, já conhecida:

#include <stdio.h>

Qualquer processo (programa) tem 3 ficheiros automáticamente abertos : o da entrada


padrão ( standar input), o da saída padrão ( standard output), e o da saída de erro ( standard
error output). A menos que redireccionados, estão normalmente associados ao terminal, isto
é , ao teclado, ao monitor e monitor respectivamente. A cada um destes ficheiros
corresponde uma constante, definida em stdio.h que o identifica:

● stdin standard input (teclado)


● stout standard output (monitor)
● stderr standard error (monitor)

O ficheiro de saída de erro é geralmente usado para escrever mensagens de erro que não
dizem respeito às saidas normais. Por exemplo, se ocorresse um erro grave seria aborrecido
se a mensagem de erro fosse redireccionada para o ficheiro de saída sem que o utilizador se
apercebesse disso. A solução seria escrever a mensagem para o standard error.

A linguagem C permite dois tipos de ficheiros : binário, ou texto. Estes são um conjunto de
linhas, com zero ou mais caracteres cada, sendo cada uma terminada pelo caractere newline
(\n). Estas linhas estão sujeitas a algum processamento feito pelo sistema operativo. Por
exemplo o DOS na escrita, substitui o \n por carriage return e mudança de linha (line feed). A
substituição inversa é feita na leitura.

Um ficheiro binário, é composto por uma sequência de bytes(caracteres) que não são
alterados pelo sistema.

[Link] (1 of 7) [21/10/2002 [Link]


A Linguagem C - Ficheiros file stdin stdout stderr fopen fclose fread fwrite fprintf fscanf feof

8.2. Abertura e Fecho de Ficheiros

O ficheiro stdio.h contém definições e declarações necessárias às funções standards de


manipulação de ficheiros. Esse ficheiro contém um typedef que define um tipo de dado
chamado file. Nos programas em linguagem C um ficheiro é especificado em termos de um
apontador para um FILE que é obtido pela chamada à função fopen. O utilizador não
necessita conhecer os membros de uma estrutura FILE. A sintaxe da função de abertura de
ficheiros num programa em C é:

FILE *fopen(char nome_do_ficheiro[], char modo[]);

A função fopen() devolve um apontador para um FILE, que passa a ser utilizado em todos os
acessos ao ficheiro. O primeiro argumento é o nome do ficheiro a ser aberto. O segundo
argumento é o modo de abertura. Algumas das possibilidades para o argumento modo são:

● R :Abertura para leitura.Dá erro se o ficheiro não existe.


● W :Abertura para [Link] o ficheiro existir o conteúdo é apagado. Se não existir, o
ficheiro é criado.
● A :Abertura para adição no fim do [Link] este existir então os novos dados serão
escritos no fim do [Link] o ficheiro não existir então será criado.
● R+ :Abertura do ficheiro para leitura e escrita.
● b,t :Conforme se trate de um ficheiro do tipo binário ou do tipo texto, adiciona-se b ou t
a qualquer uma das opções anteriores (e.g.:wb).

A função fopen() retorna NULL se ocorrer um erro na abertura. Após ser realizado o
processo sobre um ficheiro aberto à que fechá-lo. A operação de fecho de um ficheiro é feita
pela função :

fclose (FILE *fp);

Esta função desaloca a estrutura FILE respectiva e fecha o ficheiro apontado por fp. Em caso
de erro (i.e. fechar um ficheiro que ainda não foi aberto) retorna EOF, caso contrário retorna
zero.

Exemplo : Exemplo de chamadas às funções fopen e fclose.

#include <stdio.h>
FILE *fp,*fopen();
...
fp=fopen(dados,r);
...
fclose (fp);

[Link] (2 of 7) [21/10/2002 [Link]


A Linguagem C - Ficheiros file stdin stdout stderr fopen fclose fread fwrite fprintf fscanf feof

Neste exemplo o valor (apontador para um FILE ) retornado por fopen(), é guardado na
variável fp. A partir daqui todas as referências ao ficheiro são feitas usando fp.

8.3. Leitura e Escrita de Ficheiros

Funções Gerais

A função de leitura geral da bibloteca padrão é :

fread(void *buffer, unsigned size, unsigned num, file *fp);

A função fread lê num objectos de tamanho size de um ficheiro especificado pelo apontador
fp para a posição de memória indicada por buffer. Retorna o n.º dos objectos completamente
lidos, ou retorna 0 se fim de ficheiro. A declaração void * significa apontador para qualquer
tipo de variável, ou seja, um qualquer endereço.
A função de escrita geral da standard library é :

fwrite (void *buffer, unsigned size, unsigned num, FILE *fp);

a qual escreve num objectos de tamanho size contidos em buffer, para um ficheiro
especificado por fp. Retorna o número de objectos completamente escritos, o qual será igual
a num a menos que tenha ocorrido um erro. Notar que, programas escritos com fread e fwrite
são portáteirs, mas os ficheiros que foram escritos através destas rotinas poderão não ser,
visto as representações dos tipos de dados serem dependentes da máquina.

Orientada à palavra

A linguagem C fornece funções para leitura e escrita de palavras de computador. Assim,


palavras individuais (com o tipo de dado int) podem ser lidas e escritas usando as rotinas:

● getw(FILE *fp);
● putw(int word,FILE *fp);

O seguinte extracto de um programa

int x;
FILE *fp;
...
putw(x,fp);

[Link] (3 of 7) [21/10/2002 [Link]


A Linguagem C - Ficheiros file stdin stdout stderr fopen fclose fread fwrite fprintf fscanf feof

irá escrever a palavra x no ficheiro especificado por fp. A função retorna a palavra escrita ou
EOF caso ocorra um erro. A linha

x=getw(fp);

irá retornar a próxima palavra do ficheiro referido por fp.

Orientada ao Caractere

As rotinas mais primitivas de input e output são getc e [Link] rotinas lêm ou escrevem
um caracter de cada vez, de e para um ficheiro que é especificado pelo apontador FILE
obtido da chamada de fopen(). A chamada

c=getc(fp);

retorna o próximo caracter de um ficheiro especificado por fp ou EOF se foi encontrado o fim
do ficheiro (ou, se ocorreu um erro). A chamada

putc(c,fp);

escreve o caracter c no ficheiro especificado por fp. retorna também o caracter c. A ideia que
getchar e putchar são funções pode agora ser exposto como uma fraude. Elas são definidas
como macros no ficheiro stdio.h da seguinte forma:

#define getchar() getc(stdin)


#define putchar() putc(c,stout)

De facto, getc e putc são igualmente macros definidas no stdio.h. A entrada e a saída
parecem funcionar caracter a caracter para conveniência do utilizador, mas na realidade eles
já são bufferizados.

Com formatação

Existem rotinas para entrada/saída formatada de dados, definidas na biblioteca padrão. Para
saída tem-se,

fprintf (FILE *fp, char controle[], arg1, arg2,...)

que é da família da printf, excepto que a saída é escrita para um ficheiro especificado por fp.
A função fprintf pode ser usada para escrever num canal diferente do standard output. Caso
se especificasse o ficheiro dado pela constante stdout, então fprintf seria o mesmo que printf.

[Link] (4 of 7) [21/10/2002 [Link]


A Linguagem C - Ficheiros file stdin stdout stderr fopen fclose fread fwrite fprintf fscanf feof

Como exemplos ,

FILE *alunos;
...
alunos=fopen(...);
...
fprintf(alunos,%d, %s\n,numero,nome);
...
fprintf(stderr,Este é o %d-ésimo erro\n,nerro);

As especificações do formato para fprintf são as mesmas das do printf. Ter em atenção, que
o printf não trunca o argumento convertido para o ajustar à largura do campo.
Para a leitura formatada a partir de um ficheiro existe a função fscanf, que possui a seguinte
sintaxe:

fscanf(fp,controle,arg1,arg2,...)

Funciona de forma idêntica ao scanf, excepto que, lê o input de um ficheiro especificado por
fp. A string de controle da função fscanf, é igual à da scanf já estudada. Caso se
especificasse o ficheiro dado pela constante stdin, então fscanf seria o mesmo que scanf.

Orientada à Linha

A orientação de linha na entrada e saída pode ser obtida usando as funções fgets, e fputs. A
função fgets tem a seguinte sintaxe:

fgets(char linha[],int n, FILE *fp);

Esta função lê a próxima linha de input, incluindo o caracter newline (\n) se existir, de um
ficheiro especificado por fp para o array linha. São lidos todos os caracteres até ao caractere
newline, a não ser que encontre o fim de ficheiro antes, ou atinja o limite n, e então o array
linha é terminado automaticamente com o caracter nulo. Se atingir o fim de ficheiro, ou
houver erro, a função retorna NULL.

A função de escrita orientada à linha é a fputs, cuja sintaxe se segue:

fputs(char linha[], FILE *fp);

A função escreve a string linha num ficheiro apontado por fp.

8.4 Acesso Aleatório

[Link] (5 of 7) [21/10/2002 [Link]


A Linguagem C - Ficheiros file stdin stdout stderr fopen fclose fread fwrite fprintf fscanf feof

Um ficheiro de input e output é normalmente sequencial. O acesso aleatório do ficheiro pode


ser obtido usando

fseek(FILE *fp, long deslocamento, int origem);

Uma chamada a fseek força o próximo input ou output do ficheiro fp a tomar lugar numa
posição deslocada deslocamento bytes relativamente à origem. Os valores possíveis para
origem são:

SEEK_SET => Início do ficheiro


SEEK_CUR => posição corrente no ficheiro
SEEK_END => fim do ficheiro

A função que retorna o deslocamento (Offset) desde o inicio do ficheiro fp é:

long ftell(FILE *fp);

Para voltar ao início do ficheiro apontado por fp existe a função:

rewind(fp);

Esta função é equivalente a : fseek(fp,0L,0);

8.5 Outras Funções de Entrada / Saída

Para completar esta apresentação sobre ficheiros, abordam-se em seguida as funções de


controlo de erros e fim de ficheiro.

ferror(fp);

Retorna um número não nulo se ocorreu um erro durante a leitura ou escrita do ficheiro
especificado por fp. A função de controle de fim de ficheiro é:

feof(fp);

que retorna um número não nulo se foi atingido o fim de ficheiro senão retorna zero.

BACK UP FORWARD
Back Up Forward

[Link] (6 of 7) [21/10/2002 [Link]


A Linguagem C - Ficheiros file stdin stdout stderr fopen fclose fread fwrite fprintf fscanf feof

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (7 of 7) [21/10/2002 [Link]


A Linguagem C - O Pré-Processador - #include #define

9. O Pré-Processador

9.1 Introdução

O pré-processador é o responsável pela primeira fase da compilação de um programa em C.


Nesta fase são processadas todas as linhas começadas pelo caracter #. São várias as
directivas de pré-processamento.

9.2 Include

Se um programa em C contém a linha

#include FILE

então o pré-processador irá substituir essa linha pelo conteúdo do ficheiro referido por FILE.
Isto é feito antes de qualquer compilação. Isto é por vezes usado por ficheiros header
contendo definições dos dados usados em ficheiros diferentes. FILE pode ter uma das duas
formas:

nome-ficheiro => Ficheiro do utilizador

<nome-ficheiro> => Normalmente ficheiro do compilador.

Na primeira forma o pré-processador primeiro procura o ficheiro no directório corrente, e só


depois, caso não o encontre, é que o procura no directório include (directório onde se
encontram todas as headers do sistema). Na segunda forma o pré-processador apenas
procura o ficheiro no directório include. Como exemplo, um programa poderá começar com
as linhas :

#include pilha.h
#include <stdio.h>
#include <ctype.h>
#include <math.h>

que inclui um ficheiro do utilizador e três ficheiros do compilador. O ficheiro do utilizador


contém instruções em C, como qualquer outro programa escrito nesta linguagem.

9.3 Define

Se um ficheiro contém uma linha da forma

[Link] (1 of 3) [21/10/2002 [Link]


A Linguagem C - O Pré-Processador - #include #define

#define nome string

então cada ocorrência do identificador nome no resto do ficheiro irá ser substituída por string.
Isto é feito pelo pré-processador antes da compilação.

É um bom estilo de programação usar #define para todas as constantes. É muito mais
simples alterar uma linha da forma,

#define SIZE 1024

que modifica correctamente todas as ocorrências de SIZE no ficheiro.

Alguns pontos técnicos sobre o define:

● A string inclui todos os caracteres (incluindo o espaço branco) até encontrar o caracter
newline.
● o nome segue exactamente as regras dos nomes das variáveis.
● Uma convenção standard é usar nome em maiusculas para se distinguir as macros
das variáveis vulgares.
● Não são possíveis substituições nas strings, isto é, vendo no fragmento,
#define SIM 1
printf (SIM=%d\n,SIM);
o pré-processador só faz uma substituição.
● A string no define pode ser superior a uma linha; para isso o caracter newline terá de
ser precedido pelo caracter \ Barra Invertida (backslash).

9.4 Define com argumentos

Uma das facilidades da linguagem C consiste em invocar #define com argumentos. Por
exemplo,

#define isdigit(c) (0<=^(c)&&(c)<=9)

pode ser usado exactamente como se existisse uma finção que determine quando é que o
caracter c é um digito. Outro exemplo é a definição,

#define ABS(x) ((x<0? (-x):(x))

a qual faria com que uma linha da forma

y=ABS(a+b)

[Link] (2 of 3) [21/10/2002 [Link]


A Linguagem C - O Pré-Processador - #include #define

fosse substituida (pelo pré-processador antes da compilação ) por

y=( a+b<0 ? -a+b;a+b);

Alguns pontos sobre o uso de #define com argumentos:

#define pode ter vários argumentos:

Em :

#define nome(arg1,arg2,...)

não deverá ser deixado qualquer espaço entre o identificador nome e o


parêntises esquerdo.

Os argumentos arg1,... obedecem às mesmas condições dos nomes das


variáveis.

O uso abusivo do #define com argumentos pode levar a alguns erros aborrecidos. Notar que
a macro anterior ABS tem a vantagem de que trabalhará para variáveis de diferentes tipos.
Se uma macro tem uma string de substituição muito longa ou complicada, talvez seja
preferível implementá-la como uma função.

BACK UP FORWARD
Back Up Forward

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] (3 of 3) [21/10/2002 [Link]


A Linguagem C - Bibliografia - Biografia - Links

Bibliografia

Linguagem C

Instituto Superior de Engenharia do Porto, Isabel Sampaio, Alberto Sampaio

C Avançado

McGraw-Hill, Helbert Schildt

Teach Yourself C++ in 21 Days, Second Edition

Sams Publishing
BACK UP
Back Up

BackTo front page Pages by Nuno Nunes. Updated on: undefined

[Link] [21/10/2002 [Link]

Você também pode gostar