Você está na página 1de 33

Aspectos bsicos de linguagem C

Robson Ribeiro Linhares , Professor do Departamento Acadmico de Informtica(DAINF) da Universidade Tecnolgica Federal do Paran(UTFPR) Este documento est disponvel na HomePage:http://www.dainf.cefetpr.br/~robson/ Consideraes gerais Muitas linguagens foram desenvolvidas e por muitos anos utilizadas com diferentes objetivos e caractersticas, tais como: Fortran, Cobol, Basic, Algols, Pascal e etc. Mas o que C? C o nome de uma linguagem atualmente utilizada em diferentes reas e propsitos. Faz parte hoje de uma linguagem considerada avanada, desenvolvida nos laboratrios Bell nos anos 70. A definio formal da linguagem pode ser encontrada no livro The C Programming Language de Brian W. Kernighan e Dennis M. Ritchie (os pais da linguagem). Nos anos 80 iniciou-se um trabalho de criao de um padro chamado C ANSI (American National Standardization Institute). uma linguagem de nvel mdio, pois pode-se trabalhar em um nvel prximo ao da mquina ou como uma linguagem de alto nvel como outras existentes. Com o C podemos escrever programas concisos, organizados e de fcil entendimento, mas infelizmente a falta de disciplina pode gerar programas mal escritos, difceis de serem lidos e compreendidos. No se deve esquecer que C uma linguagem para programadores, pois impe poucas restries ao que pode ser feito. O C amigvel e estruturado para encorajar bons hbitos de programao; cabe ao programador exercitar esses hbitos. A necessidade de escrever programas, que faam uso de recursos da linguagem de mquina de uma forma mais simples e porttil, fez com que a principal utilizao do C fosse a reescrita do sistemas operacional UNIX. Sua indicao principalmente no desenvolvimento de programas, tais como: compiladores, interpretadores, editores de texto; banco de dados. Computao grfica, manipulao e processamento de imagens, controle de processos, Principais caractersticas da linguagem C a serem ponderadas: Portabilidade Gerao de cdigos executveis compactos e rpidos Interao com o sistema operacional Facilidade de uso Linguagem estruturada Confiabilidade Simplicidade

1. Elementos bsicos
1.1 Identificadores So utilizados para dar nomes a constantes, variveis, funes e vrios objetos definidos pelo usurio. As regras para formao desses nomes so: 1) Todo identificador deve iniciar por uma letra (a..z ou A..Z) ou um sublinhado 2) No pode conter smbolos especiais. Aps o primeiro caracter pode ser utilizado: letras, sublinhados e/ou dgitos. 3) Utiliza-se identificadores de, no mximo, 32 caracteres por estes serem significativos. 4) No pode ser palavra reservada e nem nome de funes de bibliotecas. Obs: letras maisculas e minsculas so tratadas de forma diferente. 1.2 Tipos de dados bsicos Tipo char int float double void 1.3 Modificadores Tipo unsigned char unsigned int Short int unsigned short int long int unsigned long int long double Nmero de bytes 1 21 2 2 4 4 10 Escala 0 a 255 0 a 655351 -32768 a 32767 0 a 65535 -2147483648 a 2147483647 0 a 4294967295 3.4E-4932 a 1.1E+4932 Nmero de bytes 1 21 4 8 0 Escala -128 a 127 -32768 a 327671 3.4E-38 a 3.4E+38 (+-) 1.7E-308 a 1.7E+308 (+-) sem valor

Observaes: 1) O modificador signed eventualmente pode ser utilizado, porm o seu uso equivale a
utilizar um tipo sem qualquer modificador. 2) A palavra int pode ser omitida. Ex: unsigned long int unsigned long

O tamanho do tipo int dependente da plataforma sobre a qual o programa compilado. Usualmente, um dado do tipo int ocupa dois bytes de tamanho.
1 1 1

1.4 Declarao de variveis A forma geral para declarao de uma varivel : tipo_da_varivel lista_de_variveis; onde tipo_da_varivel um tipo vlido em C (Sees 1.2 e 1.3) e lista_de_variveis pode ser um ou mais nomes de identificadores separados por virgula. Exemplos:
int f, i, k; float a, A, b; /* todas variveis do tipo int */2 /* todas variveis do tipo float */

1.5 Constantes Em C, constantes so valores fixos que no podem ser alterados por um programa.

1.5.1 Constantes em base decimal 1) Constantes numricas inteiras: podem ser atribudas a variveis dos tipos char e int,
modificados ou no, dependendo do valor da constante e da faixa de valores aceita pela varivel. Exemplos: 345 10 0 5000000

2) Constantes numricas no inteiras: podem ser atribudas a variveis dos tipos float e
double, modificados ou no, dependendo do valor da constante e da faixa de valores aceita pela varivel. Exemplos: -56.897 1.2E+5

3) Constantes em forma de caracter: podem ser atribudas a variveis do tipo char,


modificadas ou no. O valor da constante igual ao valor numrico da tabela ASCII 3 do caracter representado entre (comumente chamados de plicas)

1.5.2 Constantes em bases hexadecimal e octal4


Constantes em base hexadecimal iniciam com 0x, ao passo que constantes em base octal iniciam com um 0. Exemplos:
2

0xAB (hexadecimal)

016 (octal)

/* e */ delimitam um comentrio textual, que no compilado mas que auxilia o programador na documentao do seu cdigo. Note-se que existe uma verso alternativa para delimitar um comentrio at o final da linha, usando //, porm esta verso padro C++ e no deve ser utilizada para compilao de cdigo ANSI C (C padro)
3

A tabela ASCII uma tabela padronizada que relaciona um conjunto de caracteres a valores numricos entre 0 e 255. Por exemplo, o caracter correspondente ao dgito 9 corresponde ao cdigo ASCII 57.
4

Para maiores informaes sobre nmeros octais e hexadecimais, consultar o texto sobre Bases Numricas

1.5.3 Constantes em forma de sequncia de caracteres (strings)


So representadas entre aspas. Exemplo: Esta uma constante em forma de string.

1.5.4 Caracteres de controle da linguagem C


Estes caracteres devem ser representados como caracteres alfanumricos (entre ) ou como contedo de uma string Cdigo \a \b \f \n \r \t \ \ \0 \\ \v \a \N \xN Significado sinal audvel retrocesso do cursor alimentao de formulrio nova linha retorno de carro tabulao horizontal aspas apstrofo nulo (zero) barra invertida tabulao vertical sinal sonoro constante octal (onde N um octal) constante hexadecimal (onde N um hexadecimal)

1.6 Instrues Uma instruo em linguagem C uma expresso seguida de um ponto e vrgula. Pode ser uma atribuio, uma chamada de funo, um teste de desvio ou um teste de lao. Exemplo de instruo de atribuio:
x = 12;

onde o sinal de igual (=) o operador de atribuio. Note-se que o operando do lado esquerdo do operador de atribuio sempre uma varivel, e que o operando do lado direito deve ser de um tipo de dado compatvel com o tipo da varivel. 1.7 Operadores

1.7.1 Operadores aritmticos Adio Subtrao Diviso Multiplicao Resto + / * %

Observaes: 1) Todos os operadores so definidos para os tipos inteiros e no inteiros, exceto o operador resto (%) que no definido para variveis dos tipos no inteiros. 2) Para qualquer tipo inteiro, a adi o de um ao maior nmero da faixa daquele tipo produz o menor nmero da faixa. Os erros de estouro nem sempre so detectados, cabendo ao programador tomar cuidado ao dimensionar as variveis do programa para que eles no ocorram. Exemplo:
unsigned char x; x = 255; x = x + 1; /* x deveria assumir 256, no entanto estoura a faixa retorna para o menor valor que 0 */

1.7.2 Operadores relacionais Menor que Maior que Menor ou igual Maior ou igual Igualdade Desigualdade
Observaes: 1) Todas as operaes relacionais tem como resultado um inteiro representando um valor lgico (1 = true e 0 = false). 2) No confundir o operador de atribuio (= ) com o operador de igualdade ( = = ).

< > <= >= == !=

1.7.3 Operadores lgicos e (conjuno) ou (disjuno) no (negao) && || !

Os operadores lgicos podem receber qualquer valor de operando, porm os valores diferentes de zero so sempre interpretados como true (verdadeiro) e os iguais a zero so interpretados como false (falso). O resultado de uma operao lgica sempre um valor lgico. Tabela da verdade p 0 0 1 1 Q 0 1 0 1 p && q 0 0 0 1 p || q 0 1 1 1 !p 1 1 0 0

1.7.4 Operadores de atribuio combinados


+= -= *= /=

Exemplos:
a a a a += -= *= /= b; b; b; b; /* /* /* /* a a a a = = = = a a a a + * / b; b; b; b; */ */ */ */

Observaes: 1) Todos os operadores de atribuio atribuem o resultado de uma expresso a uma varivel Se o tipo do lado esquerdo no for o mesmo do lado direito, o tipo do lado direito ser convertido para o tipo do lado esquerdo. Isto pode causar a perda de preciso em alguns tipos de dados e deve ser levado a srio pelo programador.

1.7.5 Operadores ps-fixados e pr-fixados


Operador ++variavel Varivel++ --variavel variavel-Exemplos:
int a = b = c =

Significado incrementa a varivel antes de usar o seu valor incrementa a varivel depois de usar o seu valor decrementa a varivel antes de usar o seu valor decrementa a varivel depois de usar o seu valor

a, b, c; 6; ++a; /* a recebe 7 e depois b tambm recebe 7*/ a++; /* c recebe 7 e depois a recebe 8 */

1.7.6 Operadores em nvel de bit Deslocamento esquerda (shift left) Deslocamento direita (shift right) e (and) ou (or) ou exclusivo (xor) no (not) << >> & | ^ ~

Para uma discusso mais aprofundada sobre o uso de bits e nmeros binrios, consultar o texto sobre Bases Numricas

1.7.7 Operadores de endereo


& - retorna o endereo da varivel * - retorna o contedo do endereo armazenado em uma varivel do tipo ponteiro Para saber mais sobre operadores de endereo, consultar o texto sobre Ponteiros.

1.7.8 Outros operadores


sizeof(operando) fornece o tamanho em bytes do seu operando Ex:
int x; float y; char c; x= sizeof(int); x= sizeof(y); x= sizeof(c);

/* fornece o tamanho do tipo int (2 bytes) */ /* fornece o tamanho da varivel y (4 bytes) */ /* fornece o tamanho da varivel c (1 byte) */

1.8 Expresses Operadores, constantes, variveis e funes constituem expresses. As principais regras algbricas so consideradas nas expresses. Alguns aspectos das expresses so especficos da linguagem C e so explicados a seguir.

1.8.1 Converso automtica de tipos


Quando constantes, variveis e funes de tipos diferentes so misturados em uma expresso, elas so todas convertidas para o tipo do operando maior. Isto feito operao a operao, de acordo com as seguintes regras: 1) Todos os operandos dos tipos char e short int so convertidos para int. Todos os operandos do tipo float so convertidos para double. 2) Para todos os pares de operandos envolvidos em uma operao, se um deles long double o outro operando convertido para um long double. Se um double, o outro convertido para double. Se um long, o outro convertido para long. Se um unsigned, o outro convertido para unsigned. Ex:
float x, res; char c; ... res = x/c; /* o valor de x/c convertido para um float, embora c seja originalmente um char */

1.8.2 Converso explcita de tipos (type casts)


possvel forar uma expresso a ser de um tipo especfico, sem no entanto mudar os tipos das variveis envolvidas nesta expresso. A esse tipo de operao chama-se converso explcita de tipo, ou type cast. A forma geral de um type cast : (tipo) expresso; onde tipo um dos tipos de dado padro da linguagem C. As operaes de type cast so muito teis em expresses nas quais alguma operao resulta em perda de preciso devido ao tipo das variveis ou constantes envolvidas. Por exemplo:

float res; int op1,op2; op1 = 3; op2 = 2; res = op1 / op2;

/* res recebe 1, j que op1 e op2 so ambos nmeros do tipo int e o resultado da sua diviso tambm int */ res = (float)op1 / op2; /* res recebe 1.5, j que o type cast forou o operando op1 a ser um float nesta operao. O resultado da diviso, por consequncia, tambm float */

1.8.3 Espaamento e parnteses


Podemos colocar espaos em uma expresso para torn-la mais legvel. O uso de parnteses redundantes ou adicionais no causar erros ou diminuir a velocidade de execuo da expresso. Ex:
a=b/9.67-56.89*x-34.7; a = (b / 9.67) (56.89 * x) 34.7; /* equivalente */

2. Estrutura de um programa em C
Uma particularidade interessante no programa C seu aspecto modular e funcional, em que o prprio programa principal uma funo. Esta forma de apresentao da linguagem facilita o desenvolvimento de programas, pois permite o emprego de formas estruturadas e modulares encontradas em outras linguagens. A estrutura de um programa em C possui os seguintes elementos, sendo que aqueles delimitados por colchetes so opcionais: [ [ [ [ [ main ( ) { /* definies de variveis */ /* corpo da funo principal, com declaraes de suas variveis, seus comandos e funes */ } Definies de pr-processamento so comandos interpretados pelo compilador, em tempo de compilao, que dizem respeito a operaes realizadas pelo compilador para gerao de cdigo. Geralmente iniciam com uma cerquilha (#) e no so comandos da linguagem C, por isso no sero tratados aqui com maiores detalhes. definies de pr-processamento definies de tipo declaraes de variveis globais prottipos de funes funes ] ] ] ] ]

Ex:
#include <stdio.h> /* comando de pr-processador, utilizado para indicar ao compilador que ele deve colar as definies do arquivo stdio.h neste arquivo antes de compil-lo */

Definies de tipos so definies de estruturas ou tipos de dados especiais, introduzidos pelo usurio para facilitar a manipulao de dados pelo programa. Tambm no sero tratados aqui em maiores detalhes. Declaraes de variveis globais so feitas quando necessrio utilizar variveis globais no programa. O conceito de varivel global e as vantagens e desvantagens do seu uso dizem respeito modularizao de um programa em C (consultar o material sobre modularizao e funes). Prottipos de funes e funes tambm dizem respeito a questes de modularizao. main() a funo principal de um programa em C, contendo o cdigo que ser inicialmente executado quando o programa em si for executado. Todo programa em C deve conter a funo main(), do contrrio ser gerado um erro durante o processo de gerao do programa (mais especificamente, na etapa de ligao).

3. Funes bsicas de E/S


Esta seo descreve algumas das funes bsicas de E/S, que sero utilizadas inicialmente para prover o programador de um canal de entrada de dados via teclado e um canal de sada de dados via monitor. 3.1 Funo printf( ) (biblioteca stdio.h) A funo printf( ) basicamente utilizada para enviar informaes ao monitor, ou seja, imprimir informaes. O seu prottipo o seguinte: printf( string de dados e formato, var1, var2,..., varN); onde string de dados e formato formada por dados literais a serem exibidos no monitor (por exemplo, um texto qualquer) mais um conjunto opcional de especificadores de formato (indicados pelo smbolo % e um conjunto de caracteres). Estes especificadores determinaro de que forma o contedo dos argumentos var1 a varN ser exibido. var1 a varN indicam, por sua vez, os argumentos (variveis ou constantes) cujos valores sero exibidos no local e no formato determinado pelos especificadores de formato, dentro da string de dados e formato. O nmero N deve ser igual ao nmero de especificadores de formato fornecidos.

Especificadores de formato mais utilizados: %c %d %e %f %g %o %s %u %x %lf %u %ld Exemplos: 1)


int n = 15; printf(O valor de n eh %d, n); /* exibe O valor de n eh 15. Note-se que todo o contedo da string de dados e formato exibido literalmente, com exceo do especificador %d, que substitudo pelo valor em formato inteiro da varivel n */

caracteres simples (tipo char) inteiro (tipo int ) notao cientfica ponto flutuante (tipo float) %e ou %f (mais curto) octal string inteiro sem sinal hexadecimal tipo double inteiro no sinalizado (tipo unsigned int) tipo long int

2)
char carac = A; float num = 3.16; printf(A letra eh %c e o numero eh %f, carac, num); /* exibe A letra eh A e o numero eh 3.16. Neste caso, o especificador %c (primeiro da string) substitudo pelo valor da varivel carac e o especificador %f substitudo pelo valor da varivel num. Note-se que os tipos dos especificadores e das variveis so compatveis */

3.2 Funo scanf() (biblioteca stdio.h) A funo scanf utilizada para receber dados de uma entrada de dados padro. Consideraremos, para fins de simplificao, que essa entrada padro sempre o teclado. O prottipo de scanf o seguinte: scanf (string de formato, &var1, &var2, , &varN); onde a string de formato contm os especificadores de formato na sequncia e relativos a cada um dos dados que se pretende receber. Para uma lista dos especificadores de formato mais utilizados, ver seo 3.1. var1 a varN identificam as variveis nas quais sero armazenados os valores recebidos por scanf, na mesma ordem determinada pelos especificadores de formato. O nmero N deve ser igual ao nmero de especificadores de formato fornecidos.

IMPORTANTE: o operador de endereo (&) DEVE obrigatoriamente ser utilizado diante dos identificadores das variveis, do contrrio ocorre um erro. Para maiores detalhes, consultar a teoria sobre ponteiros. Exemplos: 1)
int t; printf(Digite um inteiro: ); scanf(%d, &t); /* aguarda a digitao de um nmero do tipo int. O nmero digitado armazenado na varivel t quando o usurio digita ENTER */

2)
char carac1; int i; printf(Digite um caracter e um int, separados por vrgula: ); scanf(%c, %d, &carac1, &i); /* neste caso, os especificadores de formato %c e %d esto separados por vrgula, o que significa que o usurio deve digitar os valores tambm separados por vrgula e na ordem correta */

3.3 Funo getch() (biblioteca conio.h) A funo getch utilizada, basicamente, para esperar o pressionamento de uma tecla pelo usurio. A tecla pressionada pode ser capturada atravs do valor de retorno da funo (para maiores detalhes sobre valor de retorno, consultar a teoria sobre funes). Pelo fato de interromper a execuo at o pressionamento de uma tecla, a funo getch pode ser utilizada no final de um programa de console para permitir que o usurio visualize o resultado do programa antes que a sua janela se feche. Exemplo:
printf(Estou mostrando uma frase\n); printf(Digite qualquer tecla para sair do programa); getch(); /* aguarda aqui at uma tecla ser pressionada */ /* fim do programa */

Observao: a funo getche funciona de forma semelhante, porm exibe na tela o caracter digitado (o nome significa get char with echo).

4. Estruturas de controle
Comando simples Uma linha de comando em C sempre termina com um ponto e vrgula (;) Exemplos:
x = 443.7; a = b + c; printf(Exemplo);

4.2 Bloco de comandos Utiliza-se chaves ( { } ) para delimitar blocos de comando em um programa em C. Estes so mais utilizados no agrupamento de instrues para execuo pelas clusulas das estruturas condicionais e de repetio. 4.3 Estruturas condicionais

4.3.1 Estrutura if-else


Formato: if ( condio ) { bloco de comandos 1 } else { bloco de comandos 2 } condio qualquer expresso que possa ser avaliada com o valor verdadeiro (true) ou falso (false). No caso de expresses que possuam um valor nmerico ao invs de um valor lgico, se o valor diferente de zero a expresso avaliada com valor lgico true, do contrrio avaliada com o valor lgico false. Caso a condio possua um valor lgico true, bloco de comandos 1 executado. Se o valor lgico da condio for false, bloco de comandos 2 executado. Para qualquer um dos blocos, se este for formado por um nico comando as chaves so opcionais. A estrutura if-else semelhante a uma estrutura condicional composta, em que um ou outro bloco de comandos executado; a clusula else, no entanto, opcional, e se for omitida a estrutura passa a funcionar como uma estrutura condicional simples, em que um bloco de comandos (no caso, o bloco 1) somente executado se a condio for verdadeira.

Exemplos: 1)
int num; printf(Digite um numero: ); scanf(%d, &num); if (num < 0) /*testa se num menor que zero */ { /* bloco de comandos executado se a condio verdadeira. Neste caso, como printf um nico comando as chaves poderiam ser omitidas */ } else { printf(\nO nmero menor que zero);

/* bloco de comandos executado se a condio falsa. Neste caso, como printf um nico comando as chaves poderiam ser omitidas */ } printf(\nO nmero maior que zero);

2)
if ((a == 2) && (b == 5)) /* condio com operao lgica */ printf(\nCondio satisfeita); /* bloco de comandos */ getch(); /* esta instruo no faz parte da estrutura condicional, logo sempre executada */

3)
if (m == 3) { if ((a >=1) && (a <= 31)) /* este if faz parte do bloco de comandos do if anterior */ { printf(Data OK); } else /* este else do if mais proximo (que faz parte do bloco de comandos) */ { printf(Data invlida); } }

4.3.2 Estrutura switch


Formato: switch (expresso) { case valor1: seq. de comandos 1 break; case valor2: seq. de comandos 2 break; ... case valorN: seq. de comandos N break; default: seq. padro } O comando switch avalia expresso e compara sucessivamente com uma lista de constantes valor1 a valorN (menos constantes strings). Quando encontra uma correspondncia entre o valor da expresso e o valor da constante, salta para a clusula case correspondente e executa a sequncia de comandos associada at encontrar um comando break, saindo em seguida da estrutura. A clusula default executada se nenhuma correspondncia for encontrada. Esta clusula opcional e, se no estiver presente, nenhuma ao ser realizada se todas as correspondncias falharem. usada normalmente para direcionar qualquer final livre que possa ficar pendente na declarao switch. OBSERVAES: se o comando break for esquecido ao final de uma sequncia de comandos, a execuo continuar pela prxima declarao case at que um break ou o final do switch seja encontrado, o que normalmente indesejado. nunca duas constantes case no mesmo switch podem ter valores iguais. uma declarao switch mais eficiente do que um encadeamento de if-else, alm do que pode ser escrito de forma muito mais elegante. valor1 a valorN DEVEM ser valores constantes. Exemplos: 1)
int dia; printf(Digite um dia da semana, de 1 a 7); scanf(%d, &dia); switch(dia) /* testa o valor da varivel dia */ { case 1: printf(Domingo); break; case 2: printf(Segunda); break; case 3:

printf(Tera); break; case 4: printf(Quarta); break; case 5: printf(Quinta); break; case 6: printf(Sexta); break; case 7: printf(Sbado); break; default: printf(Este dia no existe); /* s entra aqui se o usurio no digitar um dia entre 1 e 7 */ break;

4.4 Estruturas de repetio


4.4.1 Estrutura while
Formato: while (condio) { sequncia de comandos } O comando while avalia o valor lgico de condio; se o valor lgico for verdadeiro (true) a sequncia de comandos executada, caso contrrio a execuo do programa continua aps a estrutura while. Caso a sequncia de comandos seja formada por um nico comando, o uso das chaves opcional. Aps a execuo da sequncia de comandos, o valor lgico de condio reavaliado, e se continuar sendo verdadeiro (true) a sequncia de comandos executada novamente. Este comportamento se repete at que o valor lgico da condio seja falso (false), quando a execuo da estrutura while interrompida e continua na instruo seguinte. Cada uma das execues da sequncia de comandos chamada de iterao do lao. No caso da estrutura while o nmero de iteraes pode variar de 0 at N, sendo N o nmero da iterao aps a qual o teste da condio resulta em um valor lgico falso. OBSERVAO: caso a condio seja verdadeira no primeiro teste e a sequncia de comandos seja executada, necessrio que esta torne a condio falsa em algum momento; do contrrio, a condio sempre ser reavaliada como verdadeira e a sequncia de comandos ser executada em um nmero infinito de iteraes5.

Estamos considerando programas executados linearmente, ou seja, sem a ocorrncia de eventos assncronos (p. ex., interrupes).

Exemplo:
int x = 0; /* imprime os valores de x de 0 at 9 o valor 10 no impresso porque, ao testar a condio para x igual a 10, o valor lgico falso e a execuo do while interrompida */ while (x < 10) { printf(\nx = %d, x); x++; /* faz a condio tornar-se falsa em algum momento */ }

4.4.2 Estrutura do while


Formato: do { sequncia de comandos } while (condio); A sequncia de comandos sempre executada inicialmente em uma estrutura do-while. Aps a sua execuo, o valor lgico da condio avaliado, e se for verdadeiro (true) a sequncia de comandos executada novamente. O ciclo se repete at que o valor lgico da condio seja falso (false), quando a execuo continua na instruo seguinte estrutura do-while. Caso a sequncia de comandos seja formada por um nico comando, o uso das chaves opcional. Diferentemente do que ocorre na estrutura while, na estrutura do-while o nmero de iteraes varia entre 1 e N, onde N o nmero da iterao aps a qual o teste da condio resulta em um valor lgico falso. OBSERVAO: assim como na estrutura while, caso a condio seja verdadeira no primeiro teste necessrio que a sequncia de comandos torne a condio falsa em algum momento. Exemplo:
int num; do { printf(Digite um nmero de 1 a 9: ) scanf(%d, &num); } while (!((num >=1) && (num <=9))); /* nesse caso, a obteno do valor de num via scanf pode tornar a condio falsa */

4.4.3 Estrutura for


Formato: for (inicializao; condio; incremento) { sequncia de comandos } A inicializao executada uma nica vez, no incio da execuo da estrutura for, e normalmente uma atribuio utilizada para inicializar alguma varivel de controle do lao. Aps a inicializao, o valor lgico da condio testado. Se for verdadeiro (true), a sequncia de comandos executada, do contrrio a execuo continua aps a estrutura for. Ao final da execuo da sequncia de comandos, o comando correspondente ao incremento executado, e a condio volta a ser testada. O ciclo se repete at que o teste da condio resulte em um valor lgico falso (false), quando ento a execuo prossegue aps a estrutura for. Caso a sequncia de comandos seja formada por um nico comando, o uso das chaves opcional. A estrutura for equivalente a uma estrutura while com o seguinte formato: inicializao while (condio) { sequncia de comandos incremento } OBSERVAES: Qualquer uma das clusulas do cabealho (inicializao, condio ou incremento) pode ser omitida; no caso da omisso da inicializao ou do incremento considera-se que estes so comandos nulos (ou seja, no executam nada), j na omisso da condio considera-se que o seu valor lgico sempre verdadeiro. Os sinais de ponto-e-vrgula que separam cada uma das clusulas no podem ser omitidos. As clusulas de inicializao e incremento podem se constituir de vrios comandos cada uma; nesse caso, os comandos devem ser separados entre si por vrgulas. Exemplos: 1)
/* neste caso, x usado como varivel de controle do lao (controla a execuo entre 1 e 100) e tambm tem o seu valor impresso pela funo printf */ for (x = 1; x <= 100; x++) { printf(%d, x); }

2)
/* neste caso a sequncia de comandos nula, e o lao utilizado somente para gastar tempo contando de 0 a 999 */ for (x = 0; x< 1000; x++);

3)
/* no h incremento, e o lao executado at que o valor digitado pelo usurio seja 10 */ for (x = 0; x != 10;) scanf(%d, &x);

4)
/* duas variveis so inicializadas, testadas e incrementadas */ for (x = 0, y = 0; x + y < 100; x++, y++) printf(%d, x + y);

4.5 Comandos de interrupo


4.5.1 Comando break
O comando break pode ser utilizado para interromper a execuo de um lao a qualquer momento. Somente o lao mais interno interrompido, e a execuo continua no comando seguinte a esse lao. Exemplo:
#include <stdlib.h> #include <stdio.h> void main(void) { int sorteio = rand(); /* gera um nmero aleatrio entre 0 e 32767 */ /* requerida para usar rand() */

int num, x; for (x = 0; x<10; x++) { printf(Tente acertar o nmero (entre 0 e 32767).); printf(Vc tem %d tentativas., 10 x); scanf(%d, &num); if (num == sorteio) /* se acertou o nmero */ { break; /* interrompe o lao (no so necessrias mais tentativas) */ } } /* se x igual a 10, o usurio esgotou suas tentativas sem obter sucesso */

if (x < 10) { printf(Muito bem!);

} else { } } printf(Lamentvel!);

4.5.2 Comando continue


O comando continue tem funcionamento semelhante ao break, com a diferena de que somente a iterao corrente interrompida; ou seja, a execuo do lao continua a partir do incio da prxima iterao. Exemplo:
/* imprime os nmeros pares for (x = 0; x < 100; x++) { /* se o nmero no par, passa para a prxima iterao sem imprimir */ if (x % 2 != 0) continue; } printf(%d, , x);

5. Modularizao em C
Funes Em C no existe uma distino entre funes e subrotinas. Ou seja, todas as subrotinas, do ponto de vista de algoritmos, podem ser tratadas como funes que no retornam nenhum valor. Formato de declarao de funes :
Tipo de retorno identificador_da_funo param2,..., tipoN paramN) { /* corpo da funo */ return valor de retorno; } /* fim da funo */ (tipo1 param1, tipo2

Tipo de retorno especifica o tipo do valor que ser retornado para quem chamou a funo. Quando o tipo de retorno for void isto significa que se trata de uma funo que se comporta como uma subrotina; ou seja, a funo no necessita retornar nenhum valor, apenas ser chamada.

Exemplos de tipos de retorno nos cabealhos das funes:


int func1(...) /* retorna um valor inteiro */ void func2(...) /* no retorna nenhum valor. Comporta-se como subrotina */

O comando return utilizado para realizar o retorno da funo; este pode ser utilizado em qualquer ponto da funo que se deseje finalizar a sua execuo e retornar o valor (se a funo retornar algum valor) para quem a chamou. Valor de retorno o valor a ser efetivamente retornado e pode ser tanto uma varivel como uma constante; nos casos em que a funo no retorna nenhum valor o comando return deve ser utilizado sozinho ou pode-se simplesmente omit-lo, o que far com que a funo retorne automaticamente ao seu final. Exemplos de uso de return:
return 0; /* retorna o valor constante 0 */ return var; /* retorna o valor da varivel var */ return; /* no retorna valor. usado para funes com retorno do tipo void */

Os parmetros param1 a paramN identificam os parmetros que se deseja passar para a funo. Cada um destes parmetros passa a ser uma varivel local da funo de tipo tipo1 a tipoN e inicializado com o valor que foi passado para si no momento da chamada da funo. Funes que no recebem nenhum valor como parmetro devem ser declaradas com a palavra void entre os parnteses. Exemplos de declaraes de parmetros no cabealho das funes:
/* dois parmetros, um int e um char. O ... se refere a um tipo de retorno qualquer */ ... Func1(int var, char var2) { } ... Func2 (void) /* no recebe nenhum parmetro */ { }

Exemplo de funo e programa em C que a chama:


int func1 (char carac, int inteiro, float flutuante) /* declaraco da funo */ { /* pode-se declarar outras variveis aqui dentro, como em um trecho normal de programa estas variveis so locais da funo */ int outra; /* uso das variveis recebidas como parmetro */ printf(%c, carac); printf(%f, flutuante); scanf(%d, &outra); printf(%d, inteiro + outra); return outra; } /* fim da funo */ /* retorna o valor da varivel outra */

void main (void) /* programa principal */ { char c1; float f; int resultado; int inteiro; /*esta varivel inteiro existe no escopo da funo main, logo no tem nada a ver com a varivel inteiro que criada na funo func1 no momento da passagem dos parmetros */ /* l um nmero inteiro, um caracter e um float */ scanf(%d, %c, %f, &inteiro, &c1, &f); /* chama a funo func1 com os parmetros na ordem correta */ resultado = func1(c1, inteiro, f); printf(%d, resultado); /* imprime resultado da funo */ }

Observaes: main () tambm uma funo, porm especial j que ela representa o ponto de partida para qualquer programa em C; O resultado da funo func1, no exemplo acima, no precisa necessariamente ser atribudo a uma varivel (no caso, resultado); se isto no acontecer o valor de retorno da funo simplesmente ser perdido. Porm, como a funo foi feita para retornar um valor inteiro isto deve ser evitado, porque constitui-se em uma m estruturao e uso da funo; Todas as variveis declaradas dentro do corpo de uma funo so locais a ela, ou seja, s existem enquanto a funo est sendo executada.

Todas as funes devem ser conhecidas no local onde forem utilizadas, ou seja, a sua declarao deve vir antes do uso. Caso no se deseje implementar a funo antes do local onde ela vai ser utilizada pode-se escrever um prottipo da seguinte forma:
Tipo de retorno identificador_da_funo param2,..., tipoN paramN); (tipo1 param1, tipo2

O prottipo deve ser colocado antes da chamada da funo, sinalizando ento ao compilador que aquela funo existe e vai ser implementada adiante. No nosso exemplo, se quisssemos escrever a funo func1 depois da funo main deveramos incluir um prottipo de func1 antes dela. CUIDADO!! O prottipo no exatamente igual ao cabealho da funo, ele possui um pontoe-vrgula a mais no final! Variveis globais Em C considera-se como varivel global todas aquelas variveis declaradas fora do escopo de qualquer funo (inclusive da funo main). Qualquer varivel s conhecida aps a sua declarao, logo costuma-se declarar todas as variveis globais no incio do programa, antes da implementao das funes que a utilizam.

Exemplo de declarao e uso de variveis globais:


int c; char t; /* funo que retorna um valor inteiro e no recebe parmetro */ int func1 (void) { /* existe uma varivel t que global, porm esta funciona como uma varivel local */ int t; /* c global, logo pode ser utilizada dentro da funo func1 */ if (c!=0) { c++; t = c*2; /* neste caso o valor de t retornado o da varivel local, j que definies locais sobrepem-se a definies globais nos escopos onde existem */ return t; } else return 0; } void main(void) { int retorno; printf(Entre com um caracter:); scanf(%c, &t); printf(Entre com um inteiro:); scanf(%d, &c); /*as variveis t e c podem ser usadas aqui porque so globais */ retorno = func1(); na varivel retorno */ /* chama a funo func1 e retorna o valor

printf(\nResultado: %d, retorno); }

Passagem de parmetros por valor Na passagem por valor, uma cpia do valor do argumento armazenado no parmetro da funo chamada. Qualquer alterao deste parmetro no se reflete no valor original do argumento. Uma alternativa para a passagem de parmetro de valor, que a passagem de parmetros por referncia utilizando ponteiros, permitiria que a funo alterasse o valor do parmetro de forma que esta alterao se refletisse no valor original do argumento. Este tipo de passagem de parmetros ser melhor estudado no captulo sobre Ponteiros.

Funes com lista varivel de parmetros Em C possvel declarar funes cuja quantidade de parmetros no definida. Cabe ento funo, por meio do uso de funes especficas de biblioteca de C, obter cada um dos parmetros recebidos e convert-lo para o tipo desejado. A biblioteca cstdarg prov alguns tipos de dados e funes utilizadas para a obteno dos parmetros de uma lista: va_list tipo de lista de parmetros variveis, utilizado para declarar uma estrutura (ver o captulo sobre Estruturas de dados) que contm os parmetros variveis recebidos. void va_start(va_list lista, ultimo) macro utilizada para inicializar a lista de parmetros do tipo va_list. Ultimo o identificador do ltimo parmetro direita que no pertence lista varivel de parmetros. tipo va_arg(va_list lista, tipo) permite, a partir da lista do tipo va_list, obter o valor de tipo tipo do prximo argumento da lista. void va_end(va_list lista) finaliza a obteno dos parmetros da lista. Para declarar uma funo com lista varivel de parmetros:
Tipo de retorno identificador_da_funo (tipo1 param1, tipo2 param2, ...);

Onde a elipse (. . .) denota o incio da lista varivel de parmetros. Um exemplo: funo que recebe n valores e retorna a sua mdia:
/* n a quantidade de valores, que vm em seguida na lista de parmetros */ float media (int n, ...) { float soma = 0; int i; va_list valores; /* lista de parmetros */ va_start(valores, n); /* n o ltimo parmetro fixo antes da lista de parmetros variveis */ for (i = 0; i < n; i++) { /* aqui o valor do prximo parmetro, de tipo float adicionado a soma*/ soma += va_arg(valores, float); } va_end(valores); /* finaliza a obteno dos parmetros */ return soma/n; }

6. Vetores e matrizes
Definio de vetor Vetor em C uma varivel composta por um conjunto de dados com um mesmo nome (identificador) e individualizadas por um ndice. Declarao de vetor em C O vetor declarado da seguinte maneira:
tipo nome [tamanho];

Onde tipo o tipo de cada um dos elementos do vetor e tamanho o nmero de elementos do vetor. Para acessar um elemento do vetor a sintaxe :
nome [ndice];

IMPORTANTE! O ndice do primeiro elemento de um vetor SEMPRE ZERO! Assim, ndice pode variar entre 0 e o valor de tamanho 1. Por exemplo, para a declarao de um vetor chamado teste cujo tipo dos dados char e que tenha 4 posies declara-se:
char teste [4];

O ndice do ltimo elemento indexvel do vetor 3, pois em C a primeira posio utilizada a posio 0. Neste caso as posies disponveis no vetor so as seguintes: teste[0] teste[1] teste[2] teste[3] Passagem de vetor como parmetro para funo Existem trs maneiras possveis:
tipo_retorno nome (tipo v[tam], ...); tipo_retorno nome (tipo v[], ...); tipo_retorno nome (tipo * v, ...);

Em todos os casos a funo recebe uma referncia (endereo). Note que na ltima maneira utilizado um ponteiro, que ser explicado mais adiante.

Por ser passada uma referncia, as alteraes feitas nos elementos do vetor dentro da funo sero refletidos nos valores originais do vetor (j que se utilizar sua posio real na memria). Por exemplo:
void troca (int v[]) { int aux; v[0] = v[1]; v[1] = aux; } void main(void) { int nums[2]; nums[0] = 3; nums[1] = 5; troca (nums); /* O argumento o nome do vetor */ /* imprime 5, 3, j que os valores do vetor trocados dentro da funo troca */ printf(%d, %d, nums[0], nums[1]); }

nums

foram

6.4 Declarao de matriz A declarao de matrizes se d da seguinte maneira:


tipo nome[dim1][dim2];

Onde dim1 e dim2 so as duas dimenses da matriz (no caso de uma matriz bi-dimensional). Para se acessar um elemento da matriz a sintaxe :
nome[ind1][ind2];

Onde ind1 e ind2 seguem as mesmas regras dos ndices de vetores unidimensionais (ou seja, podem assumir valores entre 0 e a dimenso 1), sendo ind1 o ndice da linha e ind2 o ndice da coluna. As representao grfica de uma matriz M 3x2 se d da seguinte maneira: M[0][0] M[1][0] M[2][0] M[0][1] M[1][1] M[2][1]

Na memria ela pode ser vista da seguinte forma (obs: os valores da esquerda representam endereos arbitrrios de memria, considerando uma matriz de elementos char de um byte):

0100 0101 0102 0103 0104 0105

M[0][0] M[0][1] M[1][0] M[1][1] M[2][0] M[2][1]

6.5 Passagem de matriz como parmetro para funo As possibilidades so as seguintes:


tipo retorno nome(tipo m[][dim2],...) tipo retorno nome(tipo *m,...)

No primeiro caso, dim2 deve ser fornecido para que o compilador possa calcular o deslocamento em bytes em relao ao endereo do primeiro elemento para uma determinada posio. No segundo caso, m s pode ser utilizado atravs da aritmtica de ponteiros (explicada adiante). Exemplo:
void inverte_linha(int m[][2]) { int aux1, aux2; aux1 = m[0][0]; aux2 = m[0][1]; m[0][0] = m[1][0]; m[0][1] = m[1][1]; m[1][0] = aux1; m[1][1] = aux2; } void main(void) { int m[2][2]; . . . inverte_linha(m); . . . }

6.6 Inicializao de vetores e matrizes Para vetores: valores entre chaves, separados por vrgulas. Por exemplo:
int primos [7] = {2, 3, 5, 7, 11, 13, 17};

Caso o nmero de valores de inicializao seja menor que o tamanho do vetor, as posies restantes sero preenchidas com zeros. Por exemplo:
int teste[5] = {1, 2, 3}; /* teste[3] e teste[4] recebem 0 */

Para matrizes cada linha preenchida entre chaves, com valores separados por vrgulas. Todas as linhas ficam entre chaves. Ex:
int m[5][3] = {{1, 2, 3,}, {3, 2, 1}, {3, 3, 2}, {1, 2, 1} {3, 2, 0}};

Caso algum elemento no seja explicitado, ele ser preenchido com zero.

Ex:
int m2[3][4] = {{3, 2, 5}, {4, 6}, {1, 2, 3, 4}};

3 2 5 0 4 6 0 0 1 2 3 4

7 Ponteiros
Ponteiro em C uma varivel que, ao invs de armazenar um dado de um determinado tipo, armazena o endereo de um dado de um determinado tipo: Ponteiros so usados freqentemente para: Acesso a E/S mapeada em memria Uso de alocao dinmica de memria. Alternativa para passagem de parmetros por referncia (em C++) 7.1 Declarao de ponteiros em C Os ponteiros so declarados da seguinte maneira:
tipo *nome;

Onde nome o identificador do ponteiro e tipo o tipo de dado para o qual ele pode apontar. Ex:
int *d; short int *ptr; float *ptr2;

7.2 Operadores de ponteiro Operador &: Operador de referenciao. Retorna o endereo de uma varivel. Pode ser utilizado para inicializar um ponteiro. Operador *: Operador de derreferenciao. Retorna o contedo do endereo apontado por um ponteiro. Ex:
int int x = ptr . . . a = x,a; *ptr; 30; = &x;

/*

ptr <- endereo de x

*/

*ptr;

/* a recebe o contedo do endereo apontado*/

Um modo didtico para o entendimento de ponteiros ler o significado de * e & como contedo do endereo apontado por e endereo de, respectivamente. Por exemplo no seguinte cdigo:
int *ptr; int x; x = 10; *ptr = 3; /* O CONTEDO DO ENDEREO APONTADO POR ptr recebe 3 */ ptr = &x; /* ptr recebe o ENDEREO DE x */

7.3 Problemas no uso de ponteiros - Ponteiros sempre devem apontar para endereos correspondentes a variveis que tenham sido declaradas ou a regies de memria nas quais no existam dados ou cdigo de outros programas. Por exemplo, o seguinte cdigo armazena o contedo da varivel x em um endereo qualquer, que pode ser um endereo invlido.
int *ptr; int x = 3; *ptr = x; /* ERRO! Para onde o ptr aponta???

*/

- Ponteiros devem apontar para dados do mesmo tipo de sua declarao, do contrrio podem ocorrer interpretaes erradas na operao de derrenferenciao. Por exemplo, o seguinte cdigo no armazena o valor 56 na varivel f, j que o ponteiro para float tentar ler o tamanho de um dado float a partir do endereo de memria da varivel x e no o tamanho de um int, que o tipo declarado da varivel x.
int x = 56; float *ptr; float f; ptr = &x; /* Ponteiro para float aponta para int */ . . . f = *ptr; /* ERRO! Valor de F no 56 */

7.4 Aritmtica de ponteiros Valores numricos inteiros podem ser adicionados ou subtrados de um ponteiro. O resultado um endereo que segue as regras da aritmtica de ponteiro, ou seja: Para um ponteiro declarado da seguinte maneira:
tipo* ptr;

e inicializado com um endereo end1:


ptr = end1;

a operao ptr + N, onde N um nmero inteiro, resulta um endereo que igual a end1 mais N vezes o tamanho do tipo de dado apontado (ou seja, o tamanho em bytes de tipo).

Por exemplo, considerando que a varivel x foi alocada no endereo 120:


int x, y; int * ptr; ptr = &x; /* ptr recebe o endereo 120 */ y = *(ptr + 4); /* y recebe o contedo do endereo 120 + 4*(tamanho do int) == endereo 128 */

Outro exemplo:
float ptr = . . . *(ptr = 112 *ptr; (float*)100; /* ponteiro forado para o end. 100 */

+ 3) = 15; /* Nmero 15 armazenado no endereo 100 + 3x4 */

7.5 Relao ponteiro-vetor Quando um vetor declarado, o identificador deste vetor marca o endereo de incio da rea de memria alocada por ele. Assim, o nome do vetor pode ser usado como referncia de endereo com os mesmos operadores utilizandos para ponteiros. Portanto:
int vetor[10], b; . . . b = vetor[3]; /* vetor alocado no end. 100 (p. ex.) */

/* posio 3 == end. 106 de memria

*/

Equivale a:
int vetor[10], b; /* vetor alocado no end. 100 (p. ex.) */

/* Na memria isso ser guardado na posio 106 -> 100 + 3 x Tamanho do tipo de dado apontado (int = 2 bytes) */ b = *(vetor + 3);

7.6 Uso de ponteiro para passagem de parmetros Em muitos casos interessante que uma funo fornea mais do que um valor de sada como seu resultado. Porm a sintaxe de linguagem C permite somente um valor de retorno direto (atravs do comando return). O uso de ponteiros cria uma alternativa para que uma funo fornea mais do que um valor de sada, baseado no fato de que o conceito de endereo em um programa independente de escopo. Ou seja, se uma funo chamadora fornecer para a funo chamada os endereos de suas variveis, a funo chamada poder receb-los em ponteiros e preencher valores nestes endereos, que por sua vez estaro disponveis para acesso direto pela funo chamadora.

Exemplo:
/* funo recebe dois endereos de int como parmetros */ void troca (int *a, int *b) { int aux; aux = *a; /* contedo do endereo recebido como parmetro */ *a = *b *b = aux; } void main(void) { int n1 = 8, n2 = 5; /* endereos de n1 e n2 so passados para a funo troca() */ troca (&n1, &n2); printf(%d, %d, n1, n2); }

8 Strings
8.1 Definio de string Strings so seqncias de caracteres diversos. So conhecidos por literais na teoria de algoritmos estruturados, sendo representados entre aspas. Alguns exemplos de strings: Fulano da Silva, ? Interrogao? , 1,234, 0. Em C, strings so representadas atravs de vetores de caracteres, terminados com o caractere de fim de string cujo valor na tabela ASCII zero (0 ou \0). 8.2 Declarao de string Um vetor em C que pretenda armazenar uma string n caracteres deve ser alocado com n+1 posies do tipo char para conter o terminador de string. A inicializao de uma string pode ser efetuada com o uso de uma sequncia de caracteres entre aspas. Exemplos de declaraes de string:
char frase[] = Primeira string; /*Inicializao sem a dimenso */ char frase[16] = Primeira string; char frase[6] = {T, e, s, t, e, 0); /* inicializado como um vetor de caracteres comum, forando o caracter terminador */

No caso do primeiro e do segundo exemplo, a representao do vetor da string frase :

P r i m e i r a

f r a s e 0

Onde cada quadrado representa um byte de memria (tamanho de um char).

8.3 Operaes sobre string String no um tipo primitivo da linguagem C, por isso as seguintes operaes NO so vlidas:
char str1[10]; char str2[] = Palavra 2; str1 = str2 /* ERRO! No copia str2 em str1 */ if (str1 == str2) /* ERRO! No compara str1 com str2 */ { . . . }

Para operar sobre strings so utilizadas funes da biblioteca string.h. Esta biblioteca possui algumas dezenas de funes com diversas variaes e por questes de simplificao apenas algumas das principais sero explicadas neste material. Para maiores detalhes sobre as demais funes, consultar documentao sobre a biblioteca (geralmente disponvel nos arquivos de ajuda dos ambientes de desenvolvimento). 8.3.1 strlen Prottipo:
int strlen (char *string)

Descrio: Retorna o nmero de caracteres de uma string (exceto o caractere de fim de string). Exemplo:
char nome[] = Fulano; printf (O nome possui %d letras, strlen (nome));

8.3.2 strcpy Prottipo:


char *strcpy (char *string1, char *string2)

Descrio: Copia o contedo de string2 em string1 e retorna o endereo de string. Exemplo:


char str1[10]; char str2[] = Palavra; strcpy (str1, str2); /* Agora str1 tambm contm Palavra */

8.3.3 strcmp Prottipo:


int strcmp (char *string1, char *string2)

Descrio: Compara os contedos de string1 e string2 caracter a caracter e retorna 0 se string1 = string2 <0 se string1 < string2 >0 se string1 > string2

Exemplo:
char nome1[] = Fulano char nome2[] = Beltrano; if (strcmp (nome1, nome2) == 0) { printf (Nomes so iguais); } else { printf (Nomes so diferentes); }

8.3.4. gets Prottipo:


void gets (char *string1)

Descrio: Recebe uma string via teclado e armazena em string1. Os caracteres so armazenados at que o enter seja pressionado. Exemplo:
char nome[10]; gets (nome);

Observaes:

a funo gets() permite que o usurio fornea mais caracteres do que os que podem ser armazenados no vetor, o que pode causar um erro. Para evitar este problema, pode-se utilizar a funo fgets:

char nome[10]; fgets(nome, 10, stdin); /* stdin um arquivo aberto por padro, relacionado aos dados digitados via teclado */

No exemplo mostrado, fgets receberia 9 caracteres (ou at que o usurio teclasse enter) e armazenaria os dados digitados na string nome, adicionando o caracter terminador de string. importante observar que, caso o usurio digitasse enter antes de 9 caracteres, o caracter de nova linha (\n) tambm seria armazenado no vetor. gets() termina quando o usurio digita um espao, impedindo a digitao de frases com mais de uma palavra. Para contornar este problema pode-se utilizar opes de recebimento de dados do scanf:
scanf (%s, str); /* Recebe uma string at que o primeiro espao seja inserido */ scanf (%[\n]s, str) /* Recebe uma string at que seja enviado o caractere ASCII \n, que corresponde a enter */

8.4 Entrada controlada de dados possvel fazer uma entrada de dados controlada (ou seja, os caracteres so checados assim que so recebidos) recebendo os mesmos um a um. No exemplo a seguir implementaremos uma entrada de senha que mostra os caracteres * na tela ao invs das letras correspondentes utilizando a funo getch (que no ecoa o caracter digitado para o monitor). Note que s sero aceitos letras e no nmeros e smbolos.

int i = 0; char str[9]; printf (Digite uma senha de oito letras); while (i < 8) { str[i] = getch(); if (((str[i] >= a) && (str[i] <= z)) || ((str[i] >= A) && (str[i] <= Z))) { printf (*); i++; } }

9 Alocao dinmica de memria


Alocao dinmica de memria consiste em reservar espao para o armazenamento de dados sob demanda, liberando este espao quando no for mais necessrio. Para fazer alocao dinmica so utilizadas funes da biblioteca alloc.h, das quais as principais sero apresentadas aqui. A funo malloc usada para tentar alocar um espao contguo de n bytes de memria. Caso consiga ela retorna o endereo de incio da rea de memria, caso contrrio retorna zero. O prottipo da funo :
void* malloc (int n);

Exemplo:
int *v; int n; printf (Quantos elementos no vetor?); scanf (%d, &n); v = (int*) malloc(n * sizeof(int)); /* Alocar n vezes o tamanho de um int */ if (v == 0) { printf (Erro); } else { /* aqui poderia vir o cdigo para manipulao do vetor . . . */ free (v); }

A funo free() chamada ao final da utilizao do espao de memria dinamicamente alocado para liberar este espao, permitindo que seja utilizado por outras operaes de alocao dinmica. O prottipo de free o seguinte:
void free(void* ptr)

onde ptr contm o endereo inicial da rea de memria a ser desalocada.

Você também pode gostar