Programação C (Apoio)
-
Upload
mari-chagas -
Category
Documents
-
view
98 -
download
2
Transcript of Programação C (Apoio)
#include<math.h> #include<stdio.h> #include<stdlib.h> float max(float x, float y){ if (x > y) return x; return y; } float mediaHarmPond(float amostra1, float peso1, float amostra2, float peso2, float amostra3, float peso3) { return (peso1 + peso2 +peso3)/(peso1/max(amostra1,0.0001)+peso2/max(amostra2,0.0001)+peso3/max(amostra3,0.0001)); } void main(){ unsigned long int cod; int i, n=0; float p1, p2, p3, mh[60], mh_media=0, somatorio=0, s; FILE *saida; if ((saida = fopen("l:medias.DAT", "w"))== NULL){ // Cria um arquivo para escrita printf("Nao conseguiu criar arquivo de saida.\n"); exit(0); // Aborta execucao }
while(1){ printf("Forneca o codigo do aluno\n"); scanf("%ld",&cod); if (cod==0) break; // Sai do laco printf("Forneca as notas das provas do aluno\n"); scanf("%f %f %f",&p1, &p2, &p3); if (p1>=0 && p1<=10 && p2>=0 && p2<=10 && p3>=0 && p3<=10){ mh[n] = mediaHarmPond(p1,1,p2,2,p3,3); mh_media += mh[n]; fprintf(saida,"Codigo: %8ld Prova 1: %2.2f Prova 2: %2.2f Prova 3: %2.2f Media harmonica ponderada: %2.2f\n", cod, p1, p2, p3, mh[n]); n++; } else printf("Intervalo de notas invalido\n"); } mh_media = mh_media/n; for(i=0;i<n;i++) somatorio+=(mh[i]-mh_media)*(mh[i]-mh_media);
s = sqrt(somatorio/(n-1));
\
2 Linguagem de Programação C
SUMÁRIO 1 INTRODUÇÃO ............................................................................................................................. 5
1.1 VISÃO GERAL DE UM PROGRAMA C ........................................................................................................ 5
2 ESTRUTURA BÁSICA DE UM PROGRAMA EM C ............................................................................ 6
2.1 BIBLIOTECAS ..................................................................................................................................... 7 2.2 AS BIBLIOTECAS DISPONÍVEIS E ALGUMAS FUNÇÕES INTERESSANTES ............................................................. 7
3 COMANDO DE ESCRITA ............................................................................................................... 9
3.1 MODIFICADORES DE SAÍDA ................................................................................................................ 11 3.2 EXERCÍCIOS..................................................................................................................................... 11
4 TIPOS DE DADOS ........................................................................................................................13
4.1 CONSTANTES .................................................................................................................................. 15 4.2 CONSTANTES PRÉ‐DEFINIDAS .............................................................................................................. 16
5 VARIÁVEIS .................................................................................................................................17
5.1 NOME DE VARIÁVEIS ........................................................................................................................ 17 5.2 DECLARAÇÃO DE VARIÁVEIS ............................................................................................................... 17 5.2.1 Escopo de Variáveis ............................................................................................................ 18
5.3 PALAVRAS RESERVADAS ..................................................................................................................... 20
6 OPERADORES .............................................................................................................................21
6.1 ATRIBUIÇÃO ................................................................................................................................... 21 6.1.1 Conversão de Tipos em Atribuições .................................................................................... 21
6.2 OPERADORES ARITMÉTICOS ............................................................................................................... 22 6.2.1 Operadores Aritméticos de Atribuição ............................................................................... 23
6.3 OPERADORES RELACIONAIS E LÓGICOS ................................................................................................. 24 6.4 PRECEDÊNCIA DOS OPERADORES ARITMÉTICO, RELACIONAIS E LÓGICOS ...................................................... 25 6.5 OPERADORES DE PONTEIROS & E * ..................................................................................................... 25 6.6 OPERADOR VÍRGULA ........................................................................................................................ 26 6.7 EXPRESSÕES ................................................................................................................................... 26 6.7.1 Conversão de Tipos em Expressões .................................................................................... 26 6.7.2 Casts ................................................................................................................................... 27 6.7.3 Espaçamento e Parênteses ................................................................................................. 28
7 ALGUMAS FUNÇÕES DE E/S .......................................................................................................29
7.1 SCANF() ......................................................................................................................................... 29 7.2 LENDO E ESCREVENDO CARACTERES ..................................................................................................... 31 7.2.1 getche() e getch() ................................................................................................................ 31
7.3 EXERCÍCIOS..................................................................................................................................... 32
8 COMANDOS CONDICIONAIS .......................................................................................................34
8.1 COMANDO IF .................................................................................................................................. 34 8.2 COMANDO SWITCH .......................................................................................................................... 35
3 Linguagem de Programação C
8.3 EXERCÍCIOS..................................................................................................................................... 36
9 ESTRUTURA DE REPETIÇÃO (LAÇOS) ...........................................................................................40
9.1 LAÇO FOR ....................................................................................................................................... 40 9.2 LAÇO WHILE ................................................................................................................................... 41 9.3 LAÇO DO‐WHILE .............................................................................................................................. 42 9.4 BREAK ........................................................................................................................................... 43 9.5 EXIT() ............................................................................................................................................ 44 9.6 EXERCÍCIOS..................................................................................................................................... 44
10 FUNÇÕES ...............................................................................................................................50
10.1 LOCALIZAÇÃO DAS FUNÇÕES ............................................................................................................... 51 10.1.1 Corpo da função antes do programa principal (no mesmo arquivo) .................................. 51 10.1.2 Corpo da função depois do programa principal (no mesmo arquivo) ................................ 51 10.1.3 Corpo da função escrito em arquivo separado ................................................................... 52
10.2 PROTÓTIPO DE FUNÇÕES ................................................................................................................... 53 10.3 DIRETIVA #DEFINE ........................................................................................................................... 53 10.4 EXERCÍCIOS..................................................................................................................................... 54
11 VETORES E MATRIZES .............................................................................................................57
11.1 INICIALIZAÇÃO DE VETORES E MATRIZES ............................................................................................... 57 11.2 MATRIZES E VETORES COMO ARGUMENTO DE FUNÇÕES .......................................................................... 58 11.3 LIMITES ......................................................................................................................................... 58 11.4 EXERCÍCIOS..................................................................................................................................... 59
12 STRINGS (CADEIA DE CARACTERES) ........................................................................................65
12.1 LEITURA DE STRINGS ........................................................................................................................ 65 12.1.1 scanf() ................................................................................................................................. 65 12.1.2 gets() ................................................................................................................................... 67
12.2 ESCRITA DE STRINGS ......................................................................................................................... 67 12.2.1 printf() ................................................................................................................................. 67 12.2.2 puts() ................................................................................................................................... 67
12.3 FUNÇÕES DE MANIPULAÇÃO DE STRINGS ............................................................................................. 68 12.3.1 strlen() ................................................................................................................................ 68 12.3.2 strcat() ................................................................................................................................ 68 12.3.3 strcmp() .............................................................................................................................. 68 12.3.4 strcpy() ................................................................................................................................ 69
12.4 EXEMPLO GERAL ............................................................................................................................. 69 12.5 EXERCÍCIOS..................................................................................................................................... 69
13 E/S COM ARQUIVO ................................................................................................................76
13.1 STREAMS ....................................................................................................................................... 76 13.2 ARQUIVOS ...................................................................................................................................... 76 13.3 SISTEMA DE ARQUIVOS ..................................................................................................................... 76 13.4 ESTRUTURA FILE ............................................................................................................................. 77 13.5 ABERTURA DE ARQUIVOS .................................................................................................................. 77 13.6 FECHAMENTO DE ARQUIVO ............................................................................................................... 78 13.7 VERIFICANDO FIM DE ARQUIVO ........................................................................................................... 78 13.8 COMANDO DE GRAVAÇÃO EM MODO TEXTO FORMATADO ........................................................................ 78 13.9 STREAMS PADRÃO ........................................................................................................................... 79
4 Linguagem de Programação C
13.10 EXERCÍCIOS ................................................................................................................................. 79
A. TABELA ASCII .............................................................................................................................81
14 BIBLIOGRAFIA ........................................................................................................................82
5 Linguagem de Programação C
1 INTRODUÇÃO
A linguagem C foi criada por Dennis M. Ritchie e Ken Thompson no Laboratório Bell em 1972, baseada na linguagem B de Thompson que era uma evolução da antiga BCPL. Ela foi implementada pela primeira vez num computador DEC PDP‐11 que usava o sistema operacional UNIX.
A linguagem C tornou‐se muito popular devido a características como:
• C é uma linguagem de alto nível com uma sintaxe bastante estruturada e flexível tornando sua programação bastante simplificada.
• Programas em C são compilados, gerando programas executáveis.
• C compartilha recursos tanto de alto quanto de baixo nível, pois permite acesso e programação direta do microprocessador. Com isto, rotinas cuja dependência do tempo é crítica, podem ser facilmente implementadas usando instruções em Assembly. Por esta razão, C é a linguagem preferida dos programadores de aplicativos.
• C é uma linguagem estruturalmente simples e de grande portabilidade. O compilador C gera códigos mais enxutos e velozes do que muitas outras linguagens.
• Embora estruturalmente simples (poucas funções intrínsecas), C não perde funcionalidade pois permite a inclusão de uma farta quantidade de rotinas do usuário. Os fabricantes de compiladores fornecem uma ampla variedade de rotinas pré‐compiladas em biblioteca.
Como uma ferramenta poderosa a linguagem C é usada na construção de vários aplicativos como sistemas operacionais, planilhas eletrônicas, processadores de texto, sistemas de transmissão de dados, entre outros. Um exemplo clássico é o sistema operacional UNIX, o qual foi implementado em C.
No início da década de 80, a linguagem C é padronizada pelo American National Standard Institute: surge o ANSI C. Atualmente, a linguagem C vem sendo usada para desenvolver novas linguagens, entre elas a linguagem C++ e Java.
1.1 VISÃO GERAL DE UM PROGRAMA C
A geração do programa executável a partir do programa fonte obedece a uma seqüência de operações ante de tornar‐se um executável. Depois de escrever o código‐fonte (ou programa) em um editor de textos (ou um ambiente de programação integrado), o programador executa o compilador. Essa ação desencadeia uma seqüência de etapas, cada qual traduzindo a codificação do usuário para uma forma de linguagem de nível inferior, que termina com o executável criado pelo linkador.
Figura 1.1 ‐ Codificação de um programa C
Editor Pré‐processador
Compilador Linkador
6 Linguagem de Programação C
2 ESTRUTURA BÁSICA DE UM PROGRAMA EM C
Um programa C consiste em uma ou várias funções. A seguir é mostrada a estrutura global de um programa em C. Detalhes sobre cada parte do programa serão vistos ao longo do texto.
Sintaxe: <Bibliotecas> <Declarações_globais> <Tipo_de_dado> <nome_função1>( <lista_de_parâmetros>) { <Declarações_locais> <Seqüência de comandos> } <Tipo_de_dado> <nome_função2>( <lista_de_parâmetros>) { <Declarações_locais> <Seqüência de comandos> } <Tipo_de_dado> <nome_funçãoN>( <lista_de_parâmetros>) { <Declarações_locais> <Seqüência de comandos> }
Como um programa pode ter mais de uma função, deve existir um mecanismo que garanta que todos os programas inicializem da mesma forma. Este mecanismo pode ser entendido como a padronização da função que será chamada primeiramente. Tal função chama‐se main().
Sintaxe: int main() primeira função a ser executada { inicia o corpo da função return 0; } termina a função
Conforme a sintaxe, int seria um tipo de dado do valor que é retornado para o sistema operacional (normalmente um inteiro, já que este valor é utilizado pelo sistema operacional para saber como o programa foi finalizado). A função main()não possui parâmetro neste caso (mas existe a possibilidade de receber dados na chamada do programa). O comando return devolve 0 (isto é, o código para dizer que o programa foi executado com sucesso) para quem chamou a função , neste caso o sistema operacional
Um programa em C deve possuir somente uma única função main()
Abaixo relacionam‐se algumas regras para a programação em C:
• Toda função C deve ser iniciada e encerrada por um abre chaves e um fecha chaves respectivamente;
• O nome da função, os parênteses e as chaves são os únicos elementos obrigatórios de uma função;
• Todas as instruções devem estar dentro das chaves;
7 Linguagem de Programação C
• As instruções C são sempre encerradas por um ponto‐e‐vírgula;
2.1 BIBLIOTECAS
A linguagem C organiza os diferentes conjuntos de funções comuns em bibliotecas padrões de funções. Então, para fazer uso de certa função de uma determinada biblioteca, o programador tem que informar que biblioteca está utilizando. Apesar de parecer complicado de ter que saber em qual biblioteca cada comando está definido, normalmente, um programa não utiliza muitas bibliotecas padrões definidas (cada biblioteca possui diversas funções). Além disso, a cada função nova, define‐se da biblioteca onde a mesma está definida.
Para fazer isto, usa‐se uma diretiva de compilação a qual é colocada fora de qualquer função do programa. A diretiva é #include instrui o compilador a ler outro arquivo‐fonte.
Sintaxe: #include nome_arq
onde nome_arq tem que estar entre aspas ou símbolos de maior ou menor. Em algumas plataformas, somente uma forma (<>). Para outras, aspas significam para o compilador que a biblioteca em questão deve ser buscada primeiramente no diretório atual e depois no diretório padrão do compilador ou pelas variáveis de ambiente. Também, os caracteres “<>“ significam ao compilador que deve procurar somente no diretório padrão ou nos diretórios definidos pelas variáveis de ambiente.
Exemplo 2.1 #include <stdio.h>
Não se usa o ponto‐e‐vírgula após diretivas de compilação. Este tipo de declaração é muito usado nos programas profissionais. Cada comando pré‐definido em C está prototipado em alguma biblioteca (isto é informado conjuntamente ao comando).
2.2 AS BIBLIOTECAS DISPONÍVEIS E ALGUMAS FUNÇÕES INTERESSANTES
A seguir segue uma lista de algumas as bibliotecas disponíveis no compilador Turbo C++ Borland: Ao longo do texto veremos o uso de muitas funções cobrindo uma boa parte destas bibliotecas, porém o leitor que desejar tornar‐se "fluente" na linguagem C pode (e deve) estudá‐las com profundidade.
alloc.h assert.h bcd.h bios.h complex.h
conio.h ctype.h dir.h dirent.h dos.h
errno.h fcntl.h float.h fstream.h generic.h
graphics.h io.h iomanip.h iostream.h limits.h
locale.h malloc.h math.h mem.h process.h
setjmp.h share.h signal.h stdarg.h stddef.h
stdio.h stdiostr.h stdlib.h stream.h string.h
strstrea.h sys\stat.h sys\timeb.h sys\types.h time.h
values.h
A seguir, algumas funções disponíveis pelas bibliotecas da linguagem C:
Biblioteca math.h
8 Linguagem de Programação C
int abs(int i);
double fabs(double d);
Calcula o valor absoluto do inteiro i e do real d, respectivamente.
double sin(double arco);
double cos(double arco);
double tan(double arco);
double asin(double arco);
double acos(double arco);
double atan(double arco);
Funções trigonométricas do ângulo arco, em radianos.
double ceil(double num);
double floor(double num);
Funções de arredondamento para inteiro.
ceil()
Arredonda para cima. Ex. ceil(3.2) → 3.0;
floor()
Arredonda para baixo. Ex. floor(3.2) → 4.0;
double log(double num);
double log10(double num);
Funções logarítmicas: log() é logaritmo natural (base e), log10() é logaritmo
decimal (base 10).
double pow(double base, double exp);
Potenciação: pow(3.2,5.6) = 3.25.6.
double sqrt(double num);
Raiz quadrada: sqrt(9.0) = 3.0.
Biblioteca stdlib.h
int random(int num);
Gera um número inteiro aleatório entre 0 e num - 1.
9 Linguagem de Programação C
3 COMANDO DE ESCRITA
A função printf() é uma das funções de E/S (entrada e saída) que mostra na tela os parâmetros que são passados como argumento. Seu protótipo está na biblioteca stdio.h.
Sintaxe: printf(“<expressao_de_controle>”, lista_de_argumentos)
onde: expressão_de_controle = contém caracteres que serão exibidos na tela e códigos de
formatação que indicam o formato em que os argumentos (da lista_de_argumentos) devem ser impressos.
lista_de_argumentos = lista de argumentos que serão apresentadas na expressão_de_controle. Tal lista não tem tamanho máximo e cada argumento deve ser separado por uma vírgula.
A Tabela 3.1 mostra os códigos na linguagem para caracteres que não podem ser inseridos diretamente do teclado.
Tabela 3.1 ‐ Código para os caracteres especiais
CÓDIGO SIGNIFICADO
\n Nova Linha (LF)
\t Tabulação (HT)
\b Retrocesso (BS)
\” ”
\\ Barra invertida
\f Salta Página de Formulário (FF)
\r Retorno de Carro (CR)
\’ ’
\v Tabulação Vertical
\a Alerta (beep)
\N Constante octal (onde N é uma constante octal)
\xN Constante Hexadecimal (onde N é uma constante hexadecimal)
\0 Nulo
Além destes, existem os códigos para formatação de impressão dos argumentos passados para a função, os quais estã relacionados na Tabela 3.2.
Tabela 3.2 ‐ Códigos para formatação de impressão
Código Significado
%c Caractere Simples
%d ou %i Inteiro decimal com sinal
%e ou %E Notação Científica (com e minúsculo ou maiúsculo, respectivamente)
%f Ponto Flutuante
%g ou %G %e ou %f (o mais curto, respectivamente)
10 Linguagem de Programação C
%o Octal
%s Cadeia de Caracteres
%u Inteiro decimal sem Sinal
%x ou %X Hexadecimal (caracteres em mínúsculo e maiúsculo, respectivamente)
%p Ponteiro (endereço)
%n Ponteiro inteiro.
%% Escreve o símbolo %
O uso incorreto do código de formatação produz, em geral, uma saída incorreta. Por exemplo, o comando printf(“%f”,x), onde a variável x é declarada como int x=4, produz a saída 0 e não 4 como esperava‐se, pois o printf procura por uma variável real e não inteira.
Exemplo 3.1 #include <stdio.h> int main() { printf(“A %s C foi criada em %d \nOk?”, “Linguagem”, 1972); return 0; }
Execução: A Linguagem C foi criada em 1972 Ok?
No Exemplo 3.1 percebe‐se o uso de dois tipos de códigos: primeiro de formatação com %s (para um literal ‐ string) representando a constante “Linguagem” e %d (inteiro decimal) representando a constante ano 1972; segundo um código especial para representar caractere de nova linha \n.
Exemplo 3.2 #include <stdio.h> int main() { printf(“A %s %c foi”, “Linguagem”, ‘C’); printf(“ criada em %d ”, 1972); return 0; }
Execução: A Linguagem C foi criada em 1972
No Exemplo 3.2, nota‐se que ‘C’ é delimitado por aspas simples enquanto que “Linguagem” é delimitado por aspas duplas. Isto indica ao compilador como diferenciar um caractere de uma cadeia de caracteres.
O especificador de formato %n faz com que o printf() armazene na variável apontada por seu argumento correspondente com um valor igual ao número de caracteres que já foram escritos.
Exemplo 3.3 #include <stdio.h> int main() { int cont; printf(“caracteres%n escritos\n”, &cont); printf(“%d\n”, cont); return 0;
11 Linguagem de Programação C
}
Execução: Caracteres escritos 10
Este tipo de formato é comumente utilizado para formatação dinâmica de saída de dados.
O especificador de formato %p é utilizado para mostrar um endereço de memória de acordo com o formato de endereçamento da máquina.
Exemplo 3.4 #include <stdio.h> int main() { int cont; printf("A variável cont está armazenada no endereço: %p\n", &cont); return 0; }
Execução: A variável cont está armazenada no endereço: 0012FF5C
3.1 MODIFICADORES DE SAÍDA
Para complementar os códigos de formatação a linguagem C oferece alguns códigos especiais para melhorar a apresentação dos dados. Para isto relacionam‐se:
• ‘‐’ : alinhamento pela esquerda.
• ‘+’: coloca o sinal de menos ou mais se o valor for numérico.
• n (número) : indica o tamanho mínimo do campo. O preenchimento é feito com espaços em branco. Se o tamanho iniciar com 0 (ex. 05), o preenchimento passa a ser feito com zeros.
• .m : tamanho máximo do campo, menos para os reais onde é usado para indicar o número de casas decimais.
• * : substitui um dos n, mas o seu valor é o próximo parâmetro.
• ‘l’ : indica que segue um dado longo.
Exemplo 3.3 COMANDO TELA printf(“%s %d”, “Numero”,10); Numero 10 printf(“%8s %4d”, “Numero”,10); ##Numero ##10 printf(“%-8s %4d”, “Numero”,10); Numero## ##10 printf(“%-3.5s %2.2f”,“Numero”,10.99); Numer 10.99 printf(“Long %ld”, 57485784); Long 57485784
onde: # ‐ representa 1 espaço em branco.
3.2 EXERCÍCIOS
1. Escreva os comandos de saída formatada que gerem as seguintes saídas:
01234567890123456789012
a) Camisa estampada 40,00
12 Linguagem de Programação C
Camisa lisa 35,00
b) Camisa estampada 40,00 Camisa lisa 35,00
c) Camisa estampada 00040,00 Camisa lisa 00035,00
d) Camisa e 40 Camisa l 35
2. Corrija o seguinte programa:
#include <stdio.h> int main{ }( printf(A Linguagem C foi criada em %d\n, 1972) return1; )
13 Linguagem de Programação C
4 TIPOS DE DADOS
Em C existem 5 tipos de variáveis básicas. Nos computadores da linha IBM‐PC (plataforma 32 bits), a Tabela 4.1 é válida. Este tipos de dados definem a quantidade de memória que ocupa e o intervalor de valores que consegue representar.
Tabela 4.1 ‐ Tipos de dados básicos para plataformas 32 bits
Tipo Bits Faixa Mínima
char 8 ‐128 a 127
int 32 ‐2,147,483,648 a 2,147,483,647
float 32 3.4E‐38 a 3.4E+38
double 64 1.7E‐308 a 1.7E+308
void 0 sem valor
Os tipos char e int armazenam números inteiros, enquanto que os tipos float e Double armazenam números de ponto flutuante (é um formato de representação digital de números reais).
Com exceção de void, os tipos de dados básicos podem estar acompanhados por modificadores na declaração de variáveis. Os modificadores de tipos da linguagem C são:
• signed;
• long;
• unsigned;
• short.
Os modificadores signed, short, long e unsigned podem ser aplicados aos tipos básicos char e int. Contudo, long também pode ser aplicado a double.
A função printf() possui especificadores de formato que permitem mostrar inteiros short e long. O %ld, %li, %lo, %lu, %lx especificam que o tipo de dado é long. O %hd, %hi, %ho, %hu, %hx especificam que o tipo de dado é short.
O especificador de formato long pode ser ainda utilizado para tipo ponto flutuante (indicando que segue um double): %le, %l E, %lf, %lg, e %lG. Outro especificado de formato é o L, o qual é utilizado para associar um long double: %Le, %LE, %Lf, %Lg, e %LG.
A Tabela 4.2 mostra todas a combinações de tipos de dados e as informações sobre tamanho, formatação e intervalo.
Tabela 4.2 ‐ Utilização dos tipos de dados (plataforma 32 bits)
Tipo Bits Formatação printf()
Intervalo
Inicio Fim
Inteiros char 8 %c ‐128 127
unsigned char 8 %c 0 255
signed char 8 %c ‐128 127
14 Linguagem de Programação C
short int 16 %hi ‐32.768 32.767
signed short int 16 %hi ‐32.768 32.767
unsigned short int 16 %hu 0 65.535
int 32 %i ‐2.147.483.648 2.147.483.647
signed int 32 %i ‐2.147.483.648 2.147.483.647
unsigned int 32 %u 0 4.294.967.295
long int 32 %li ‐2.147.483.648 2.147.483.647
signed long int 32 %li ‐2.147.483.648 2.147.483.647
unsigned long int 32 %lu 0 4.294.967.295
Ponto
Flutuante float 32 %f 3,4E‐38 3.4E+38
double 64 %lf 1,7E‐308 1,7E+308
long double 80 %Lf 3,4E‐4932 3,4E+4932
O uso de signed com inteiros é redundante. No entanto, ele é permitido porque a declaração default de inteiros assume um número com sinal. O uso mais importante de signed é modificar char em implementações em que esse tipo, por padrão, não tem sinal. Algumas implementações podem permitir que unsigned seja aplicado aos tipos de ponto flutuante (como em unsigned double). Porém, isso reduz a portabilidade de seu código e geralmente não é recomendado. O modificador unsigned altera o valor da faixa mínima do tipo através do uso do bit mais significativo (indicador de sinal).
O tamanho, e conseqüentemente o intervalo de valores, pode variar de plataforma para plataforma. Por exemplo, o long double em algumas plataformas possui 10 bytes de tamanho. O char já é um tipo que não varia de plataforma.
Exemplo 4.1 #include <stdio.h> int main() { int qtde; char tam; float total; qtde = 2; tam = ‘G’; total = 20.70; printf(“Comprei %d camisas de tamanho %c.”, qtde, tam); printf(“\nNo total, paguei R$ %f.”, custo); return 0; }
Execução: Comprei 2 camisas de tamanho G. No total, paguei R$ 20.70.
As variáveis podem ser inicializadas no momento em que se faz a declaração das mesmas. Pode‐se ver isto usando o programa anterior, que a execução será a mesma da versão anterior.
Exemplo 4.2 #include <stdio.h> int main() { int qtde=2; char tam=‘G’; float total=20.70;
15 Linguagem de Programação C
printf(“Comprei %d camisas de tamanho %c.”, qtde, tam); printf(“\nNo total, paguei R$ %f.”, custo); return 0; }
Devido às diferenças de tipos em diferentes máquinas e plataformas, pode‐se utilizar a função sizeof() para descobrir o tamanho real da variável ou tipo.
Exemplo 4.3 #include <stdio.h> int main() { printf("Tipo\t\tTamanho\n"); printf("char\t\t%d\n",sizeof(char)); printf("int\t\t%d\n",sizeof(int)); printf("float\t\t%d\n",sizeof(float)); printf("double\t\t%d\n",sizeof(double)); printf("long int\t%d\n",sizeof(long int)); return 0; }
Execução: Tipo Tamanho char 1 int 4 float 4 double 8 long int 4
4.1 CONSTANTES
Uma constante tem valor fixo e inalterável durante a execução do programa. Isto pode ser exemplificado pelo Exemplo 3.1 e Exemplo 3.2 da função printf() e pelo Exemplo 4.4.
Exemplo 4.4 ‘C’ “programa” 8 465.67
Uma constante caractere é escrita entre aspas simples (‘’) enquanto que uma constante literal entre aspas duplas (“”) e constantes numéricas como o número propriamente dito.
As constantes ‘A’ e “A” são diferentes pois a primeira é um caractere e a segunda é um literal. Apesar do conteúdo ser o mesmo a linguagem C representa as duas constantes de maneira diferente.
Constantes em C podem ser de qualquer um dos cinco tipos de dados básicos. A maneira como cada constante é representada depende do seu tipo. Pode‐se especificar precisamente o tipo da constante numérica através da utilização de um sufixo. Para tipos em ponto flutuante coloca‐se um F após o número, ele será tratado como float. Se for colocado um L, ele tornar‐se‐á um long double. Para
16 Linguagem de Programação C
tipos inteiros, o sufixo U representa unsigned e o L representa long. A tabela 5.3 mostra alguns exemplos de constantes.
Tabela 4.3 ‐ Exemplo de constantes
Tipo de Dado Exemplo de Constantes
int 1 123 21000 ‐234
long int 35000L ‐34L
short int 10 ‐12 90
unsigned int 10000U 987U 40000“
float 123.23F 2.34e‐3F
double 123.23 12312333 ‐0.9876324
long double 1001.2L
Além destas existem as constantes Hexadecimais e Octais. Usam‐se tais sistemas numéricos para facilitar a programação. Uma constante hexadecimal deve consistir em um 0x seguido por uma constante na forma hexadecimal. Uma constante octal começa com 0.
Exemplo 4.5 int hex = 0x80; /* 128 em decimal */ int oct = 012; /* 10 em decimal */
4.2 CONSTANTES PRÉ‐DEFINIDAS
Em alguns compiladores C, algumas constantes simbólicas já estão pré‐definidas. Estas
constantes em geral definam alguns valores matemáticos (π, π/2, e, etc.), limites de tipos etc. A seguir segue uma tabela contendo algumas (existem muitas outras) constantes simbólicas pré‐definidas no compilador Turbo C++ da Borland.
Biblioteca Constante Valor Significado
math.h M_PI 3.14159... π
math.h M_PI_2 1.57079... π/2
math.h M_PI_4 0,78539... π/4
math.h M_1_PI 0,31830... 1/π
math.h M_SQRT2 1,41421... √2
conio.h BLACK 0 valor da cor (preto)
conio.h BLUE 1 valor da cor (azul)
conio.h GREEN 2 valor da cor (verde)
conio.h CYAN 3 valor da cor (cyan)
conio.h RED 4 valor da cor (vermelho)
conio.h MAGENTA 5 valor da cor (magenta)
limits.h INT_MAX 2.147.483.647 limite superior do tipo int
limits.h INT_MIN -2.147.483.648 limite inferior do tipo int
17 Linguagem de Programação C
5 VARIÁVEIS
Variável em C é um espaço de memória reservado para armazenar um certo tipo de dado e tendo um nome para referenciar o seu conteúdo. O conteúdo da mesma pode variar segundo os comandos de alteração do programa.
Exemplo 5.1 #include <stdio.h> int main() { int ano; ano = 1972; printf(“A Linguagem C foi criada em %d ”, ano); return 0; }
A primeira instrução,
int ano;
é um exemplo de declaração de variável, isto é, apresenta um tipo, int, e um nome, ano.
A segunda instrução,
ano = 1972;
atribui um valor à variável e este valor será acessado através de seu nome. Para realizar isto foi usado o operador de atribuição (=).
5.1 NOME DE VARIÁVEIS
A seguir listamos algumas regras para nomes de variáveis:
• Uma variável não pode ter o mesmo nome de uma palavra‐chave de C.
• Letras maiúsculas diferem das letras minúsculas.
• O número de caracteres válidos é definido de ambiente para ambiente.
Todo identificador deve iniciar com letra (maiúscula ou minúscula) e ser composto exclusivamente por letras, dígitos e underscore (isto é, _).
Exemplo 5.2 char x; /* Válida */ int x2r; /* Válida */ float #ertt; /* Inválida */ float main; /* Inválida */ float total da venda; /* Inválida */ float total_da_venda; /* Válida */
5.2 DECLARAÇÃO DE VARIÁVEIS
A declaração de variáveis serve para reservar uma quantidade de memória apropriada para armazenar o tipo especificado. Tal declaração consiste no nome de um tipo, seguido do nome da variável. Em C todas as variáveis devem ser declaradas.
18 Linguagem de Programação C
Se existir mais de uma variável do mesmo tipo, pode‐se declará‐la de uma vez separando seus nomes por vírgulas.
int ano, mes, dia;
5.2.1 ESCOPO DE VARIÁVEIS
O escopo de uma variável define onde a mesma pode ser referenciada. O escopo de uma variável está relacionado à posição onde ela é declarada. Existem três lugares básicos: dentro de funções, na definição dos parâmetros das funções e fora de todas as funções. Estas são variáveis locais, parâmetros formais e variáveis globais, respectivamente.
5.2.1.1 VARIÁVEIS GLOBAIS
Variáveis que são declaradas fora de qualquer função. Tais variáveis são reconhecidas (isto é, podem ser alteradas ou referenciadas) pelo programa inteiro e podem ser usadas por qualquer pedaço de código.
Exemplo 5.3 #include <stdio.h> int num=10; int main() {
printf(“%d”, num * num); return 0;
}
O Exemplo 5.4 mostra que qualquer função do programa pode manipular uma variável global.
Exemplo 5.4 #include <stdio.h> int num=2;
int media(int y, int x) { return ((x+z)/num); }
int main() { int x1 = 15;
int x2 = 4; printf(“%d %d ”, num * num, media(x1,x2));
return 0; }
Deve‐se ressalvar que um mesmo programa em C pode conter n variáveis com o mesmo identificador, desde que apenas uma delas seja global e as demais n‐1 sejam declaradas localmente em n‐1 funções. Se houver duas variáveis com o mesmo identificador x, uma global e outra local à função X, as referências à variável x dentro de X correspondem a referências à variável local e as referências fora de X correspondem à variável global.
Em algumas situações, variáveis globais são úteis para passar informações entre funções ou entre o algoritmo principal e as funções, mas sua utilização deve ser feita com parcimônia, pois seu uso indiscriminado pode ser fonte de erros difíceis de serem identificados. O Exemplo 5.5 ilustra um erro típico decorrente do uso incorreto de variáveis globais.
19 Linguagem de Programação C
Exemplo 5.5 #include<stdio.h> int i; // Função que escreve seqüências decrescentes de números: void escNa1(int n) { for (i=n; i>0; i--) printf("%i ",i); } int main() { for (i=1; i<=5; i++) { escNa1(i); printf("\n"); } }
Nesse exemplo, a função escNa1() recebe um valor n e escreve os números de n a 1. A função main(), por sua vez, utiliza escNa1() para escrever, em ordem decrescente, o número 1, seguido das seqüências de 2 a 1, 3 a 1, 4 a 1 e, finalmente, 5 a 1. A função está aparentemente correta. A variável i é uma variável global modificada tanto no laço da função escNa1() quanto da função main(). Esperar‐se‐ia que a execução do programa gerasse as seguintes seqüências:
1 2 1 3 2 1 4 3 2 1 5 4 3 2 1
Ao executar‐se o programa, entretanto, é obtido o seguinte resultado:
1 1 1 1 1 1 1 1 ...
A explicação para esse comportamento é que a variável i recebe 1 na função main() e substitui o argumento n da chamada escNa1(). Em escNa1(), ela é decrementada, passando a ser 0. Na próxima iteração do for de main(), ela é incrementada (voltando a ser 1) e substitui o argumento n da chamada escNa1(). Esse processo repete‐se indefinidamente.
Na medida do possível, deve‐se evitar o uso de variáveis globais, priorizando o uso de argumentos quando for necessário passar ou receber valores de funções. Outra razão para o não uso de variáveis globais é facilitar a reutilização de funções entre diferentes programas. Se uma função utiliza uma variável global, ao portar essa função para outro programa será necessário portar, também, as variáveis globais que ela referencia, tornando mais difícil a reutilização dessa função em outros algoritmos.
5.2.1.2 VARIÁVEIS LOCAIS
20 Linguagem de Programação C
Variáveis que são declaradas dentro de uma função. Tais variáveis só podem ser referenciadas por comandos que estão dentro do bloco no qual as variáveis foram declaradas, isto é, não são reconhecidas fora de seu próprio bloco de código (nem mesmo na função main()).
Exemplo 5.6 #include <stdio.h> int main() {
int num; num = 10;
return 0; } Como a linguagem C permite somente a declaração de variáveis logo após a abertura de abre-chaves, alguns programadores abrem chaves no meio do programa apenas para declara uma nova variável.
Exemplo 5.7 #include <stdio.h> int main() {
int num; num = 10; /* Até este ponto somente a variável num existe */ { int x= 10; /* A partir deste ponto as variáveis x e num existem */ num = x + 2; } /* A partir deste ponto somente a variável num existe */
return 0; }
5.2.1.3 PARÂMETROS FORMAIS
Variáveis que são declaradas para passagem de parâmetros em funções.
Exemplo 5.8 int soma(int x, int y) { return (x+y); }
5.3 PALAVRAS RESERVADAS
Existem certos nomes que não podem ser usados como identificadores. São chamadas as palavras reservadas e são de uso restrito da linguagem C (comandos, estruturas, declarações, etc.). Algumas palavras reservadas em C são:
asm auto break case cdecl char
class const continue _cs default delete
do double _ds else enum _es
extern _export far _fastcall float for
friend goto huge if inline int
interrupt _loadds long near new operator
pascal private protected public register return
_saveregs _seg short signed sizeof _ss
static struct switch template this typedef
union unsigned virtual void volatile while
21 Linguagem de Programação C
6 OPERADORES
A linguagem C é muito rica em operadores internos. C define quatro classes de operadores: aritméticos, relacionais, lógicos e bit a bit. Além disso, C tem alguns operadores especiais para tarefas particulares.
6.1 ATRIBUIÇÃO
Para o operador de atribuição é utilizado o símbolo =. Lembre‐se que as atribuições são executadas da direita para esquerda.
Exemplo 6.1 x = 10; y = x;
Além disto, a linguagem oferece um tipo de atribuição múltipla, isto é, em um comando só pode‐se atribuir o mesmo valor a muitas variáveis.
Exemplo 6.2 a = b = c = 10; /* a, b, c terão o valor 10
6.1.1 CONVERSÃO DE TIPOS EM ATRIBUIÇÕES
A linguagem C permite a conversão automática de tipos, o que não acontece em Pascal, por exemplo. Conversão de tipos refere‐se à situação em que variáveis de um tipo são misturadas com varáveis de outro tipo. Em um comando de atribuição, a regra de conversão de tipos é muito simples: o valor do lado direito (lado da expressão) de uma atribuição é convertido no tipo do lado esquerdo (variável destino), como no Exemplo 6.3:
Exemplo 6.3 #include <stdio.h> int main() {
int x; char ch; float f; ch = x; // Linha 1 x = f; // Linha 2 f = ch; // Linha 3 f = x; // Linha 4
return 0; }
Na linha 1, os bits mais significativos da variável inteira x são ignorados, deixando ch com os 8 bits menos significativos. Se x está entre 255 e 0, então ch e x têm valores idênticos. De outra forma, o valor de ch reflete apenas os bits menos significativos de x. Na linha 2, x recebe a parte inteira de f. Na linha 3, f converte o valor inteiro de 8 bits armazenado em ch no mesmo valor em formato de ponto flutuante. Isso também acontece na linha 4, exceto por f converter um valor inteiro de 16 bits no formato de ponto flutuante.
A Tabela 6.1 mostra algumas conversões de tipos e seus efeitos. Para essas conversões foi assumido uma palavra de 32 bits.
22 Linguagem de Programação C
Tabela 6.1 ‐ Conversões de tipos e seus efeitos
Tipo Destino Tipo da Expressão Possível Informação Perdida
signed char char Se valor > 127, o destino é negativo
char short int Os 8 bits mais significativos
char int Os 24 bits mais significativos
char long int Os 24 bits mais significativos
int float A parte fracionária e possivelmente mais
float double Precisão, o resultado é arredondado
Para utilizar a Tabela 6.1 a fim de fazer uma conversão não mostrada, simplesmente converta um tipo por vez até acabar. Por exemplo, para converter double em int, primeiro converta double em float e, então, float em int.
6.2 OPERADORES ARITMÉTICOS
A Tabela 6.2 mostra os operadores aritméticos suportados pela linguagem.
Tabela 6.2 ‐ Operadores aritméticos
Operador Ação
‐ Subtração, também menos unário
+ Adição
* Multiplicação
/ Divisão
% Módulo da Divisão (resto)
‐‐ Decremento
++ Incremento
O menos unário multiplica seu único operando por ‐1. Isso é, qualquer número precedido por um sinal
O operador / executa uma divisão inteira quando ambos os operandos são do tipo inteiro.
Exemplo 6.4 int op1=20, op2=3; float op3=20, op4=3; printf("%i\n",op1/op2); /* Imprime 6 */ printf("%f\n",op1/op4); /* Imprime 6.666667 */ printf("%f\n",op3/op2); /* Imprime 6.666667 */ printf("%f\n",op3/op4); /* Imprime 6.666667 */
O operador % devolve o resto de uma divisão inteira. Por isso, os dois operandos envolvidos devem ser do tipo inteiro e o segundo operando não pode ser 0 (zero).
Exemplo 6.5 int op1=20, op2=3;
23 Linguagem de Programação C
float op3=20, op4=3; printf("%i\n",op1%op2); /* Imprime 2 */ printf("%i\n",op2%op1); /* Imprime 3 */ printf("%i\n",op1%op4); /* Erro de compilação */ printf("%i\n",op2%0); /* Erro de execução: divisão por zero */ printf("%i\n",op3%0); /* Erro de compilação */
A linguagem C inclui dois operadores que geralmente não encontramos em outras linguagens. São os operadores de incremento (++) e decremento (‐‐), os quais somam 1 ao seu operando, e subtraem 1 de seu operando, respectivamente.
x++; ou ++x; ou x = x + 1; x‐‐; ou ‐‐x; ou x = x ‐ 1;
Quando usados em uma expressão tem seus efeitos alterados pela posição do sinal de decremento e incremento. Se o operador de incremento ou decremento preceder seu operando, C executa a operação de incremento ou decremento antes de usar o valor do operando. Se o operador estiver após seu operando, C usa o valor do operando antes de incrementá‐lo ou decrementá‐lo.
Exemplo 6.6 x = 10; y = ++x; /*y recebe 11*/
x = 10; y = x++; /* y recebe 10 */
A precedência dos operadores aritméticos (qual operador deverá ser executado primeiro) é a seguinte:
++ ‐‐ Mais alta ‐ (menos unário) * / % + ‐ Mais baixa
Os operadores do mesmo nível de precedência são avaliados pelo compilador da esquerda para a direita.
6.2.1 OPERADORES ARITMÉTICOS DE ATRIBUIÇÃO
A Tabela 6.3 mostra os operadores aritméticos de atribuição suportados pela linguagem.
Tabela 6.3 ‐ Operadores aritméticos de atribuição
Operador Ação
x ‐= y x = x ‐ y
x += y x = x + y
x *= y x = x * y
x /= y x = x / y
x %= y x = x % y
As expressões com este operadores são mais compactas e normalmente produzem um código de máquina mais eficiente.
A execução da operação aritmética ocorre por último após a avaliação da expressão à direita do sinal igual.
24 Linguagem de Programação C
Exemplo 6.7 x *= 2 equivale a x = x * 2 x /= y + 5 equivale a x = x / (y + 5) x %= 2 + y equivale a x = x % (2 + y) x -= y equivale a x = x - y
6.3 OPERADORES RELACIONAIS E LÓGICOS
A Tabela 6.4 mostra os operadores relacionais e lógicos suportados pela linguagem C.
Tabela 6.4 ‐ Operadores relacionais e lógicos
Operador Ação Operador Ação
> Maior que && E (AND)
>= Maior ou igual que || OU (OR)
< Menor que ! NÃO (NOT)
<= Menor ou igual que
== Igual
!= Diferente
Em C, verdadeiro é qualquer valor diferente de zero, e falso é zero. As expressões que usam operadores relacionais ou lógicos devolvem zero para falso e 1 para verdadeiro.
Toda expressão relacional e lógica produz como resultado 0 ou 1.
Exemplo 6.8 #include <stdio.h>
int main() {
char varLogica; varLogica = 10 == 20; printf("A expressão anterior é %i\n",varLogica); varLogica = 10 < 20; printf("A expressão anterior é %i\n",varLogica); varLogica = 10 != 20; printf("A expressão anterior é %i\n",varLogica); varLogica = 10 != 20 && 3 == 3; printf("A expressão anterior é %i\n",varLogica); varLogica = 10 == 20 || 3 == 3; printf("A expressão anterior é %i\n",varLogica); varLogica = 10 == 20 && 3 == 3; printf("A expressão anterior é %i\n",varLogica); varLogica = !(10 == 20) && 3 == 3; printf("A expressão anterior é %i\n",varLogica);
return 0; }
Execução: A expressão anterior é 0 A expressão anterior é 1 A expressão anterior é 1 A expressão anterior é 1 A expressão anterior é 1 A expressão anterior é 0 A expressão anterior é 1
25 Linguagem de Programação C
A precedência dos operadores relacionais e lógicos é a seguinte:
! Mais alta > >= < <= == != && || Mais baixa
6.4 PRECEDÊNCIA DOS OPERADORES ARITMÉTICO, RELACIONAIS E LÓGICOS
A Tabela 6.5 mostra a precedência dos operadores aritméticos, relacionais e lógicos da linguagem C.
Tabela 6.5: Precedência dos operadores aritméticos, relacionais e lógicos
Precedência Operador
1º () 2º ‐ (menos unário) ++ ‐‐ ! (NÃO) 3º * / % 4º + ‐ 5º < <= > >= 6º == != 7º && 8º || 9º = *= /= %= += ‐=
Todo operador aritmético com operandos numéricos produz um resultado numérico.
Todo operador relacional com operandos numéricos produz um resultado lógico.
Todo operador lógico com operandos lógico produz um resultado lógico.
6.5 OPERADORES DE PONTEIROS & E *
Um ponteiro é um endereço na memória de uma variável. Uma variável de ponteiro é uma variável especialmente declarada para guardar um ponteiro para seu tipo especificado.
O primeiro operador de ponteiro é &. Ele é um operador unário que devolve o endereço na memória de seu operando. Por exemplo,
m = &cont;
atribui o endereço de memória da variável cont em m. Este operador é muito utilizado na leitura de variáveis.
Este tipo de operando não pode ser utilizado em três casos:
1. &(cont + 4) ‐ sempre associa‐se a uma variável e não expressão;
26 Linguagem de Programação C
2. &3 ‐ constantes não são válidas;
3. variáveis declaradas com classe de armazenamento register (não existe endereço para registrador).
O segundo operador é *. Ele é um operador unário que devolve o valor da variável localizada no endereço que o segue. Por exemplo, se m contém o endereço da variável cont,
q = *m;
coloca o valor de cont em q. Este operador é muito utilizado em manipulação de posições de memória e durante a passagem de parâmetros em funções.
Os seguintes operadores * e & colocam o valor 10 na variável chamada target. O resultado (o valor 10) deste programa é mostrado na tela.
Exemplo 6.9
#include <stdio.h> int main() { int target, source; int *m; source = 10; m = &source; target = *m; printf(“%d”,target); return 0; }
6.6 OPERADOR VÍRGULA
O operador vírgula é usado para encadear diversas expressões. O lado esquerdo de um operador vírgula é sempre avaliado como void. Isso significa que a expressão do lado direito se torna o valor de toda a expressão separada por vírgulas.
Exemplo 6.10 x = (y = 3, y + 1);
No Exemplo 6.10, primeiro y recebe 3 e, em seguida, atribui o valor 4 a x.
6.7 EXPRESSÕES
Operadores, constantes e variáveis são os elementos que constituem as expressões. Uma expressão em é qualquer combinação válida desses elementos.
6.7.1 CONVERSÃO DE TIPOS EM EXPRESSÕES
Quando constantes e variáveis de tipos diferentes são misturadas em uma expressão, elas são convertidas a um mesmo tipo. O compilador C converte todos os operandos no tipo do maior operando, o que é denominado promoção de tipo. Isso é feito operação por operação, como descrito nas regras de conversão de tipos abaixo.
SE um operando é long double
27 Linguagem de Programação C
ENTÃO o segundo é convertido para long double. SENÃO, SE um operando é double ENTÃO o segundo é convertido para double. SENÃO, SE um operando é float ENTÃO o segundo é convertido para float. SENÃO, SE um operando é unsigned long ENTÃO o segundo é convertido para unsigned long. SENÃO, SE um operando é long ENTÃO o segundo é convertido para long. SENÃO, SE um operando é unsigned ENTÃO o segundo é convertido para unsigned.
Há ainda um caso adicional especial: se um operando é long e o outro é unsigned, e se o valor do unsigned não pode ser representado por um long, os dois operandos são convertidos para unsigned long.
Considere as conversões de tipo que ocorrem no Exemplo 6.11.
Exemplo 6.11 char ch; int i; float f; double d; result= ( ch / i ) + ( f * d ) - ( f + i );
int double float
double
double
Primeiro, o caractere ch é convertido para um inteiro e float f é convertido para double. Em seguida, o resultado de ch/i é convertido para double porque f*d é double. O resultado final é double porque, nesse momento, os dois operandos são double.
6.7.2 CASTS
A linguagem permite que uma expressão pode ser forçada a ser de um tipo especificado usando uma construção chamada cast. A forma geral de um cast é
(tipo) expressão
onde um tipo é um tipo de dado padrão de C. Por exemplo, para ter certeza de que a expressão x /2 será do tipo float, escreve‐se
(float) x/2;
Neste caso se a variável x fosse um inteiro ímpar sem o cast seu valor reria um inteiro (o que não seria verdadeiro). Entretanto, com o uso do Cast oa variável x é definida como um float o que tornará o seu resultado um float.
Exemplo 6.12
28 Linguagem de Programação C
int op1=20, op2=3; float op3=20; printf("%f\n",(float)op1/op2); /* Imprime 6.666667 */ printf("%i\n",(int)op3/op2); /* Imprime 6 */ printf("%i\n",(int)op3%op2); /* Imprime 2 */ printf("%f=%f\n",20.0/3, (float)20/3); /* Imprime 6.666667 */
Como um operador, um cast é unário e tem a mesma precedência de qualquer outro operador unário.
6.7.3 ESPAÇAMENTO E PARÊNTESES
A linguagem C não limita o espaçamento ou tabulações em uma expressão. Ajudam a aumentar a legibilidade do programa. O excesso de parênteses não causa erros, isto é, colocar parênteses onde não necessita, não provoca erros, mas dificulta a leitura do programa.
29 Linguagem de Programação C
7 ALGUMAS FUNÇÕES DE E/S
Neste capítulo será visto algumas funções como scanf (), getchar() e putchar(). Tais funções encontram‐se no arquivo stdio.h.
7.1 SCANF()
Esta função serve para ler dados formatados da entrada padrão (teclado). Sua sintaxe é similar à de printf(), isto é, uma expressão de controles seguida por uma lista de argumentos separados por vírgulas. A principal diferença é que os argumentos de scanf() devem ser endereços de variáveis. Para enviar o endereço de cada argumento utiliza‐se o operador &.
Sintaxe: scanf(“expressão_de_controle”, lista_de_argumentos)
A expressão de controle pode conter códigos de formatação (mostrados na Tabela 7.1), precedidos por um sinal %, caracteres de espaço em branco e caracteres de espaço não branco.
Tabela 7.1 ‐ Códigos de formatação do comando scanf()
Código Significado
%c Lê um único caractere simples
%d ou %i Lê um inteiro decimal
%e Lê um número em notação científica
%f Lê um número em ponto flutuante
%g Lê um número em ponto flutuante
%o Lê um número em octal
%s Lê um a cadeia de caracteres
%u Lê um inteiro decimal sem sinal
%x Lê um hexadecimal
%ld Lê um inteiro longo
%lf Lê um ponto flutuante longo
%Lf Lê um ponto flutuante longo (Double)
%% Busca por um conjunto de caracteres
Exemplo 7.1 #include <stdio.h> int main() { char a; printf(“Digite um caractere e veja-o em decimal, ”); printf (“ octal e hexadecimal. \n”); scanf(“%c”,&a); printf(“\n%c=%d dec., %o oct. e %x hex. \n”,a,a,a,a); return 0; }
Execução (faça você mesmo):
30 Linguagem de Programação C
Quando a função scanf() for utilizada para ler caracteres (isto é, utilizar o %c), deve‐se adicionar a linha de comando “flush(stdin);” após a linha da função scanf(). Esta funçÃo limpa o bufer do teclado já que o %c considera o ENTER como um novo caracter.
O caractere * colocado após o % avisa à função que deve ser lido um valor do tipo indicado pela especificação, mas não deve ser atribuído a nenhuma variável (não deve ter parâmetros na lista de argumentos para estas especificações).
Exemplo 7.2 #include <stdio.h> int main() { char hora, minuto, segundo; printf("Digite a hora no formato hh:mm:ss: "); scanf("%i%*c%i%*c%i",&hora,&minuto,&segundo); printf("Você digitou %02i:%02i:%02i\n",hora,minuto,segundo); return 0; }
Note que o caractere ‘:’ foi ignorado pela função scanf() no Exemplo 7.2, como definido pelo formato %*c (ignorar um caracter).
Execução: Digite a hora no formato hh:mm:ss: 12:34:4 Você digitou 12:34:04
Um caractere de espaço branco (isto é, um espaço, uma tabulação ou uma nova linha ‐ enter) na expressão de controle faz com que a função scanf() ignore um ou mais caracteres de espaço em branco durante a leitura. Um caractere de espaço não branco na expressão de controle faz com que a função scanf() leia e ignore caracteres iguais durante a leitura. O Exemplo 7.3 mostra um programa que exemplifica o uso de caracteres de espaço em branco e não branco.
Exemplo 7.3 #include <stdio.h> int main() { int x,y; scanf("%d%d",&x,&y); printf("x=%d y=%d\n",x,y); scanf("%d,%d",&x,&y); printf("x=%d y=%d\n",x,y); scanf("%dt%d",&x,&y); printf("x=%d y=%d\n",x,y); return 0; }
Execução: 1 2 x=1 y=2 3,4 x=3 y=4 5t6 x=5 y=6
31 Linguagem de Programação C
No primeiro scanf(), as variáveis estão separadas por um espaço em branco, o que permite que o usuário utilize uma tabulação, um enter ou espaço em branco (escolhido durante a execução) para separar os dois valores a serem lidos. No segundo scanf(), uma vírgula é colocada entre os dois especificadores fazendo com que a função leia um inteiro, uma vírgula e descarte a mesma, e leia outro inteiro. Note que a leitura foi realizada com sucesso de acordo com o resultado da função printf() que segue a leitura. No terceiro scanf(), um caractere ‘t’ é colocado entre os dois especificadores fazendo com que a função leia um inteiro, um caractere ‘t’ e descarte o mesmo, e leia outro inteiro, como o caso do segundo scanf(). Por isso, tem que ter muito cuidado para não confundir o scanf() com o printf() e colocar texto na expressão de controle. O Exemplo 7.2 pode ser reescrito da seguinte forma utilizando um espaço de caractere não branco. A diferença entre o Exemplo 7.4 e o Exemplo 7.2 é que o primeiro obriga o usuário a digitar o caractere ‘:’ entre os números, enquanto que o segundo aceita qualquer tipo de caractere.
Exemplo 7.4 #include <stdio.h> int main() { char hora, minuto, segundo; printf("Digite a hora no formato hh:mm:ss: "); scanf("%i:%i:%i",&hora,&minuto,&segundo); printf("Você digitou %02i:%02i:%02i\n",hora,minuto,segundo); return 0; }
7.2 LENDO E ESCREVENDO CARACTERES
A função getchar() lê um caractere do teclado (este comando necessita o pressionamento da tecla <ENTER> após o caractere), e putchar() escreve um caractere na tela. A função getchar() espera até que uma tecla seja pressionada (a qual é mostrada na tela) e devolve o seu valor. A função putchar() escreve seu argumento caractere na tela a partir da posição atual do cursor. Os protótipos para getchar() e putchar() são mostrados aqui:
int getchar(void); int putchar(int c);
A função getchar() devolve um inteiro, mas o byte de baixa ordem contém o caractere. Além disso, pode‐se chamar putchar() com um argumento caractere. A função putchar() devolve o caractere escrito, ou EOF (definida em stdio.h e geralmente é igual a ‐1), se ocorreu algum erro. A função putchar() não acrescenta um ‘\n’ a saída.
Exemplo 7.5 #include <stdio.h> int main() { char ch; printf(“Digite algum caractere:”); ch=getchar(); printf(“\n A tecla pressionada eh ”); putchar(ch); return 0; }
7.2.1 GETCHE() E GETCH()
A função getche() lê um caractere do teclado sem pressionar <ENTER> e mostra o que foi digitado. Esta função não aceita argumentos e devolve o caractere lido para a função que a chamou.
32 Linguagem de Programação C
Exemplo 7.6 #include <stdio.h> int main() { char ch; printf(“Digite algum caractere:”); ch=getche(); printf(“\n A tecla pressionada eh %c.”, ch); return 0; }
Execução: Digite algum caractere: a A tecla pressionada eh a.
A função getch() lê um caractere do teclado sem pressionar <ENTER> e não mostra o que foi digitado. Esta função não aceita argumentos e devolve o caractere lido para a função que a chamou.
As funções getch() e getche() não são implementadas em todos os compiladores. Por isso, verifique se o seu compilador oferece tais funções antes de usá‐las.
7.3 EXERCÍCIOS
1. Faça um programa que leia 3 variáveis a, b e c, coeficientes de uma equação do 2º grau e escreva as duas raízes da equação.
2. Um representante comercial realizará uma viagem de vários dias de automóvel, e, após, quer saber a quilometragem média por litro de gasolina. Para isto, ele anotará a quilometragem no velocímetro ao sair de viagem, e depois, a quilometragem na chegada; ele também vai somar toda a gasolina (em litros) usada para abastecer o carro durante a viagem. Escreva um programa em C que, a partir desses dados, informe a quilometragem média por litro de gasolina.
3. Escreva um programa em C que leia a distância percorrida em km e o tempo que um piloto levou para percorrê‐la (em minutos). O programa deve calcular a velocidade média em km/h, e exibir a seguinte frase:
A velocidade média foi <velocidade media calculada> km/h.
4. Escreva um programa em C que calcule e escreva a soma SN dos N primeiros termos de uma série:
( )2
1 naaS n
n×+
=
onde a1 é o primeiro termo da série, an é o último e n é o número de termos. Os valores de a1, an e n serão fornecidos pelo usuário.
5. Escreva um programa em C que calcule e escreva o valor de um termo an qualquer de uma progressão geométrica dada por:
11
−= nn qaa
acb,a
bx 4 onde 2
2 −=ΔΔ±−
=
33 Linguagem de Programação C
onde a1 é o primeiro termo da série, an é o último e n é o número de termos. Os valores de a1, an e n serão fornecidos pelo usuário.
6. Em uma pizzaria, cada tulipa de chope custa R$ 2,80 e uma pizza mista grande custa R$20,00 mais R$1,50 por tipo de cobertura pedida (queijo, presunto, banana, etc.). Uma turma vai à pizzaria e pede uma determinada quantidade de chopes e uma pizza grande com uma determinada quantidade de coberturas. Escreva um programa em C que calcule e conta e, sabendo quantas pessoas estão à mesa, quanto que cada um deve pagar (não esqueça os 10% do garçom).
7. Escreva um programa em C que leia, com a função getch(), seis caracteres numéricos representando os dígitos de um número. O primeiro caractere lido representa o dígito mais à esquerda do número; o último caractere lido representa o dígito mais à direita do número. O programa deve armazenar em uma variável int o número correspondente à seqüência de caracteres. O valor correspondente é obtido através do somatório do valor dos dígitos multiplicados por 10 elevado ao seu peso, onde o dígito mais à direita tem peso 0, o seguinte tem peso 1, o terceiro peso 2 e assim por diante. Por exemplo, se a seqüência de caracteres lida foi
'0' '2' '5' '3' '7' '3'
o valor colocado na variável será 105x0 + 104x2 + 103x5 + 102x3 + 101x7 +100x3 = 25373
Dica: para a conversão de um caractere numérico no número correspondente, basta subtrair o código ASCII do caractere zero do próprio caracter. assim, '0' ‐ '0' = 0; '1' ‐ '0' = 1; '2' ‐ '0' = 2; ...; '9' ‐ '0' = 9.
8. Escreva um programa em C que leia o valor total, em termos de preço, de uma compra e o valor pago. O programa deve calcular e escrever o troco, em termos da quantidade de cédulas de R$ 100,00, 50,00, 10,00, 5,00 e 1,00 e de moedas de 50, 25, 10, 5 e 1 centavos.
9. Faça um programa em C que calcule a quantidade de latas de tinta necessária e o custo para pintar tanques cilíndricos de combustível, onde são fornecidos (o programa lê) a altura (h) e o raio (r) desse cilindro. A área (a) de um cilindro é dada pela seguinte fórmula:
rra ππ 22 +=
Sabe‐se que a lata de tinta anti‐corrosiva custa R$ 40,00, cada lata contém 5 litros e cada litro de tinta pinta 3 metros quadrados em média. Para que fique bem coberto de tinta, há necessidade de duas mãos.
34 Linguagem de Programação C
8 COMANDOS CONDICIONAIS
Os comandos condicionais determinam se um pedaço de código deve ser executado de acordo com o resultado de uma expressão lógica. Três comandos são disponibilizados pela linguagem C:
• if
• if‐else
• switch
8.1 COMANDO IF
Sintaxe: if (<expressão>) <comando>; else <comando>;
onde comando pode ser um único comando, um bloco de comandos ou nada (no caso de comandos vazios). A cláusula else é opcional. Utilizando o português estruturado, este comando seria definido da seguinte maneira:
se expressão então comando senao comando fimse
No Exemplo 8.1, o comando de atribuição é executado se e somente se x for diferente de 0. Note que não existe um símbolo ou palavra para definir o começo do bloco então.
Exemplo 8.1 if (x != 0) y = 0;
Caso haja um else ele pertence ao if mais próximo.
Exemplo 8.2 if (a > 5) { if (a < 10) b = 3; } else b = 7;
No Exemplo 8.2, o comando de atribuição “b = 3;” somente é executado se o valor da variável a é maior que 5 e menor do que 10. O comando de atribuição “b = 3;” somente é executado se o valor da variável a é menor que 5. Se não fosse separado por chaves o comando if mais interno o else pertenceria ao mesmo e não ao mais externo.
Exemplo 8.3 /* Programa para adivinhar um numero */ #include “stdio.h” #include “stdlib.h”
35 Linguagem de Programação C
int main() { int num, tentativa; num = rand(); /*gera numero aleatorio entre 0 e 32767*/ scanf(“%d”, &tentativa); if (tentativa == num) printf(“* * * CERTO * * *”);
return 0; }
Para montar um bloco de comando é somente necessário usar o abre e fecha chaves para marcar início e fim de bloco de comandos respectivamente.
8.2 COMANDO SWITCH
C tem um comando interno de seleção múltipla, switch, que testa sucessivamente o valor de uma expressão contra uma lista de constantes inteiras ou de caractere.
Sintaxe: switch (<expressão>) { case <valor1> : <seqüência de comandos> break; case <valor2> : <seqüência de comandos> break; … default: <seqüência de comandos> }
O valor da expressão é testado, na ordem, contra os valores das constantes especificadas nos comandos case. Quando uma igualdade for encontrada, a seqüência de comandos associada àquele case será executada até que o comando break ou o fim do comando switch seja alcançado. O comando default (opcional) é executado no momento em que não coincidir nenhum valor.
Exemplo 8.4 #include <stdio.h> int main() { char opcao; printf(“1. Opcao 1 \n”); printf(“2. Opcao 2 \n”); printf(“3. Opcao 3 \n”); printf(“Opcao:”); opcao=getchar(); switch(opcao) { case ‘1’: printf (“\nVocê escolheu a opcao 1”); break; case ‘2’: printf (“\n Você escolheu a opcao 2”); break; case ‘3’: printf (“\n Você escolheu a opcao 3”); break; default: printf (“\n Nenhuma opcao selecionada”); break; }
return 0; }
36 Linguagem de Programação C
O caso default é opcional e, embora seja geralmente posicionado no final do bloco switch, ele pode aparecer em qualquer posição entre os case´s especificados.
Caso um break é esquecido, o programa continua a executar as próximas instruções até achar outro break ou o símbolo fecha chaves.
Exemplo 8.5 #include <stdio.h> int main() { int n; for (n = 1; n<=5; n++) { printf(“%d\t”,n); switch( n ) { case 1: printf(“A“); break; case 3: printf(“B“); case 4: printf(“C“); break; default: printf(“*“); case 5: printf(“D“); } printf(“.\n”); } }
O resultado para o Exemplo 8.5 é mostrado a seguir: 1 A. 2 *D. 3 BC. 4 C. 5 D.
Note que quando n é igual a 2, a opção default é executada e como não há um break que finaliza o caso default, o comando para o caso 5 também é executado. O mesmo ocorre quando n é igual a 3. Como este caso não foi finalizado pelo break, o próximo comando (caso 4) também é executado até achar um break.
Como toda a estrutura switch é envolvida por chaves, não é necessário usar bloco quando há mais que uma instrução associada a um determinado case.
8.3 EXERCÍCIOS
1. Escrever um programa que leia 3 pares de coordenadas (x,y), que definam 3 pontos e:
• Verificar se eles formam um triângulo (a < b + c): não podem estar alinhados e não podem haver pontos sobrepostos.
• calcular os lados do triângulo.
• classificar o tipo do triângulo:
• eqüilátero, isósceles ou escaleno.
• acutângulo, obtusângulo ou retângulo
2. Avalie (forneça o resultado) das seguintes expressões lógicas e aritméticas, mostrando todos os passos utilizados para a obtenção da solução:
37 Linguagem de Programação C
a) (((4>=3) && (3!=3.1)) || (5>=4)) && (!(5==5.0))
b) (20%6) + 7 ‐ 3.0 + 7/2.0 + (19/5) +(20+4)/4*3
3. Escreva um programa em C que leia dois números e escreva o maior deles
4. Escreva um programa que leia 3 números e os escreve em ordem crescente.
5. Faça um programa que leia um número inteiro, verifique se é positivo ou negativo e escreva uma mensagem apropriada.
6. Escreva um programa em C que leia um número n (declarado como float). Se o n for positivo, escreva uma mensagem indicando se ele é par ou ímpar.
7. Escreva um programa em C que leia dois números inteiros e escreva o módulo da diferença entre os dois (o módulo é o valor absoluto, sempre positivo).
8. Escreva um programa em C que leia três valores e escreva a média ponderada deles. No cálculo da média ponderada, é atribuído peso 5 para o maior dos 3 valores e peso 2.5 para os outros dois.
9. Um sistema de equações lineares do tipo:
a.x + b.y = c
d.x + e.y = f
pode ser resolvido da seguinte forma:
x= c.e− b.fa.e− b.d
y= a.f − c.da.e− b.d
Escrever um programa em C que lê os coeficientes a, b, c, d, e e f e calcula e escreve os valores de x e y. Lembre‐se que os denominadores das equações não podem ser zero.
10. Escreva um programa em C que leia quatro valores correspondentes aos lados de um polígono. O programa deve informar se o polígono formado por esses valores é um retângulo, um quadrado ou um trapézio.
11. Escreva um programa em C que recebe a hora de início de um jogo na forma <hora, minutos> e a hora de seu término. O programa deve escrever a duração do jogo em minutos.
12. Escreva um programa em C que leia três valores numéricos representando os lados de um triângulo. O programa deve verificar e informar se o triângulo formado é eqüilátero, isósceles ou escaleno.
13. Escreva programa em C que leia o preço do selo necessário para enviar uma carta simples, o preço do envelope e certa quantia de dinheiro. O programa deve calcular e escrever o número de cartas possíveis de serem enviadas com tal quantia, supondo um selo por carta.
14. Uma loja fornece 5% de desconto para funcionários e 10% de desconto para clientes especiais. Escreva um programa em C que calcule o valor total a ser pago por uma pessoa. O programa deverá ler o valor total da compra efetuada e um código que identifique se o comprador é um cliente comum (código 'c') , um funcionário ('f') ou um cliente especial ('e').
15. Escreva um programa em C que leia os códigos de 5 clientes de uma loja e o valor (em reais) que cada um destes clientes pagou por sua compra. O programa deverá escrever:
• valor total pago pelos 5 clientes;
38 Linguagem de Programação C
• valor da compra média efetuada;
• códigos dos clientes que efetuaram compras superiores a 20 reais; e
• códigos dos clientes que efetuaram compras inferiores a 50 reais.
16. Escreva um programa em C que lê código de um funcionário, o número de horas por ele trabalhadas e o valor que ele recebe por hora. O programa deve calcular o imposto de renda como segue:
• sobre o valor do salário bruto igual ou acima de R$ 2000,00, incide uma alíquota de 25%;
• sobre o valor do salário bruto acima de R$ 1500,00 e abaixo de 2000.00 incide uma alíquota de 15%; e
• sobre o valor do salário bruto acima de R$ 1000,00 e abaixo de 1500.00, incide uma alíquota de 10%.
O programa deve imprimir o código do funcionário, seu salário bruto e seu salário líquido.
17. Seja o seguinte programa
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void main(){
float cod, sal_bruto, aumento, adicional;
int n_filhos;
printf("entre com o código do empregado:\n");
scanf("%f", &cod);
printf("entre com o salário bruto:\n");
scanf("%f", &sal_bruto);
printf("entre com o número de filhos:\n");
scanf("%d", &n_filhos);
/* bloco 1 */
if (sal_bruto >= 3000){
aumento = sal_bruto*0.10;
}
if ((sal_bruto <3000)&& (sal_bruto >=2000)){
aumento = sal_bruto*0.15;
}
if ((sal_bruto <2000)&& (sal_bruto >=1000)){
aumento = sal_bruto*0.20;
}
if (sal_bruto <1000){
aumento = sal_bruto*0.25;
}
/* bloco 2 */
if (n_filhos == 0){
adicional = 0;
}
if (n_filhos == 1){
adicional = 100;
}
39 Linguagem de Programação C
if (n_filhos == 2){
adicional = 150;
}
if (n_filhos == 3){
adicional = 200;
}
else {
adicional = 300;
}
sal_bruto = sal_bruto + aumento + adicional;
printf("código = %f sal_bruto = %.2f\n", cod, sal_bruto);
}
Escreva as seguintes alterações no programa, sem alterar sua funcionalidade:
• todas as modificações necessárias para que a variável cod seja do tipo int;
• remova as bibliotecas que não estão sendo utilizadas;
• altere o bloco 1, de modo a simplificar as condições dos comados if.
• remova os abre ({) e fecha‐chaves (}) desnecessários;
• substitua o bloco 2 por um comando switch.
18. Seja o seguinte programa em C:
#include <conio.h>
#include <stdio.h>
void main(){
int n1, n2, n3;
clrscr();
scanf("%d %d %d",&n1, &n2, &n3);
if ((n1>=n2)&&(n1>=n3))
if (n2>=n3) printf("%d %d %d\n", n1, n2, n3);
else printf("%d %d %d\n", n1, n3, n2);
else
if ((n2>=n1)&&(n2>=n3))
if (n1>=n3) printf("%d %d %d\n", n2, n1, n3);
else printf("%d %d %d\n", n2, n3, n1);
else
if (n1>=n2) printf("%d %d %d\n", n3, n1, n2);
else printf("%d %d %d\n", n3, n2, n1);
}
O que será escrito na tela, supondo que os valores lidos foram 2, 4 e 1?
19. Implemente em C uma calculadora simples de quatro operações. O usuário deve fornecer o valor do primeiro operando (float), a operação (um char: '+', '‐', '*', '/') e o segundo operando (float). A calculadora mostra, então, o resultado da operação. Para teste do operador, use o comando switch.
40 Linguagem de Programação C
9 ESTRUTURA DE REPETIÇÃO (LAÇOS)
A ordem de execução dos programas em C até agora é de cima para baixo. Entretanto, esta ordem pode ser alterada através do uso de comandos que permitem alterar o controle do fluxo de programa fazendo com que o programa execute certo código diversas vezes. Estes comandos chamam‐se de laços e a linguagem C possui três comandos: for, while e do‐while.
Não existe restrição de número de comandos que podem ser executados repetidamente num laço e nem a utilização de um comando dentro de outro.
9.1 LAÇO FOR
O laço for é uma estrutura de controle de repetição condicional com inicialização e incremento. Um contador normalmente é utilizado para contar o número de vezes que o laço deve ser executado.
Sintaxe: for(inicialização; condição;incremento) comando;
onde comando é um comando vazio, um comando simples, ou um bloco de comandos. Como ilustrado na Figura 9.1, primeiro é executado a inicialização que consiste em atribuições iniciais (pode ser mais de uma, utilizando a vírgula entre atribuições). Depois é testada a condição (expressão relacional) de controle do laço. O incremento (ou decremento) é executado após a execução do comando ou bloco de comandos. O fim do laço é determinado pelo valor falso que a condição se apresenta.
Figura 9.1: Fluxograma do laço for.
A inicialização, condição, incremento, e até as instruções do laço for são opcionais. Além do comando, os parênteses e os dois “;” são obrigatórios.
Exemplo 9.1 #include “stdio.h” int main() { int x; for (x=1; x<=100; x++) printf(“%d”,x);
return 0; }
41 Linguagem de Programação C
No programa acima x é inicializado com 1. Uma vez que x é menor que 100, printf() é executado e x é incrementado em 1 e testado para ver se ainda é menor ou igual a 100. Esse processo se repete até que x fique maior que 100; nesse ponto, o laço termina. Então este programa imprime na tela os números de 1 a 100.
O Exemplo 9.2 mostra o uso de um for aninhado dentro de outro. O programa exibe um quadro feito do caractere ASCII ‘�’ (código 176). O laço mais externo controla o número de linhas enquanto que o interno controla as colunas.
Exemplo 9.2 #include <stdio.h> int main() { int i,j; printf(" 0123456789\n"); for (i = 0; i< 5; i++) { printf("%d",i); for (j = 0; j< 10; j++) printf("%c",176); printf("\n"); } return 0; }
Execução: 0123456789 0░░░░░░░░░░ 1░░░░░░░░░░ 2░░░░░░░░░░ 3░░░░░░░░░░ 4░░░░░░░░░░
9.2 LAÇO WHILE
O laço while é uma estrutura de controle de repetição condicional no qual a condição é avaliada por primeiro
Sintaxe: while(condição) comando;
onde comando é um comando vazio, uma comando simples, ou um bloco de comandos. Como ilustrado na Figura 9.2, primeiro é testada a condição (expressão relacional) de controle do laço. E a cada execução de comando é repetido o teste de condição. O laço pára de executar quando a condição for falsa.
Figura 9.2: Fluxograma do laço while.
42 Linguagem de Programação C
Exemplo 9.3 #include <stdio.h> int main() {
int cont=0; char ch; while((c=getchar()) != ‘0’) cont++; printf(“Foram lidos %d caracteres”,cont);
return 0; }
9.3 LAÇO DO‐WHILE
Ao contrário dos comandos for e while, que testam a condição do laço no começo, o laço do‐while verifica a condição ao final do laço.
Sintaxe: do { <comando> } while(condição);
Este laço é utilizado em casos onde o comando ou bloco de comandos deve ser executado pelo menos uma vez (por exemplo, leitura de menus ‐ Exemplo 9.4, validação de dados na leitura ‐ No Erro! Auto‐referência de indicador não válida., o programa fica lendo um valor inteiro enquanto o usuário digitar números menor que 1 ou maior que 3. Note que a própria condição de saída serve para verificar se o valor digitado está conforme o desejado.
Exemplo 9.5). A Figura 9.3 mostra o fluxograma do laço do‐while.
Figura 9.3: Fluxograma do laço do‐while.
No Exemplo 9.4, o programa mostra mensagens conforme a entrada do usuário. O prograa fica lendo dígitos enquanto o usuário digitar dígitos diferentes de ‘1’ , ‘2’, ou ‘3’ (a qual é a condição de saída do laço).
Exemplo 9.4
43 Linguagem de Programação C
#include <stdio.h> int main() { char opcao; printf(“1. Opcao 1 \n”); printf(“2. Opcao 2 \n”); printf(“3. Opcao 3 \n”); printf(“Opcao:”); do { opcao=getchar(); switch(opcao) { case ‘1’: printf (“\nVocê escolheu a opcao 1”); break; case ‘2’: printf (“\n Você escolheu a opcao 2”); break; case ‘3’: printf (“\n Você escolheu a opcao 3”); break; default: printf (“\n Nenhuma opcao selecionada”); break; } } while (opcao != ‘1’ && opcao != ‘2’ && opcao != ‘3’);
return 0; }
No Erro! Auto‐referência de indicador não válida., o programa fica lendo um valor inteiro enquanto o usuário digitar números menor que 1 ou maior que 3. Note que a própria condição de saída serve para verificar se o valor digitado está conforme o desejado.
Exemplo 9.5 #include <stdio.h> int main() { char opcao; do { printf(“Digite um valor entre 1 e 3”); scanf(“%i”,&opcao); } while (opção < 1 || opção > 3); printf(“Opcao:”, opcao);
return 0; }
Não é preciso usar chaves quando há um único comando a ser repetido, entretanto, elas são geralmente incluídas para evitar confusão entre while e do‐while.
9.4 BREAK
Além de sua utilização no comando switch, o comando break pode ser usado no corpo de qualquer estrutura de repetição C. Causa a saída imediata do laço e o controle passa para o próximo comando do programa.
Sintaxe: break;
A inserção de um break em um laço pode ser resultado de uma escolha errada do tipo de laço ou seqüência de comandos do laço.
Exemplo 9.6 #include <stdio.h>
44 Linguagem de Programação C
int main() { int n, k; printf(“\nDigite um número natural: ”); scanf(“%u”, &n); for(k=2; k<=n-1; k++) if( n%k == 0 ) break; if (k==n) printf(“\nO número é primo”); else printf(“\nO número não é primo”); return 0; }
Observe que o for pode ser interrompido tanto pela condição k ≤ n−1 quanto pela condição n%k == 0. O teste k == n, fora da repetição, é necessário para se determinar como a repetição foi interrompida. Claramente, se k chega a assumir o valor n é porque a repetição for não foi interrompida pelo break e, conseqüentemente, o número só pode ser primo.
9.5 EXIT()
Pode‐se finalizar um programa usando a função exit() da biblioteca padrão. Essa função provoca uma terminação imediata do programa inteiro, forçando um retorno ao sistema operacional.
Sintaxe: void exit(int código_de_retorno);
O valor de código_de_retorno é retornado ao processo chamador (sistema operacional). O zero é geralmente usado como um código de retorno que indica uma terminação normal do programa. No Exemplo 9.7 o programa é finalizado quando o usuário digitar a opção 4.
Exemplo 9.7 #include <stdio.h> int main() { char opcao; printf(“1. Opcao 1 \n”); printf(“2. Opcao 2 \n”); printf(“3. Opcao 3 \n”); printf(“4. Abandonar \n”); printf(“Opcao:”); do { opcao=getchar(); switch(opcao) { case ‘1’: printf (“\nVocê escolheu a opcao 1”);
break; case ‘2’: printf (“\n Você escolheu a opcao 2”); break; case ‘3’: printf (“\n Você escolheu a opcao 3”); break; case ‘4’: exit(0); /* retorna ao SO */ } } while (opcao != ‘1’ && opcao != ‘2’ && opcao != ‘3’);
return 0; }
9.6 EXERCÍCIOS
45 Linguagem de Programação C
1. Escreva um programa para calcular o fatorial de um número lido.
2. Escreva um programa para ler um caractere de comparação e vários caracteres de entrada finalizados por ‘0’ e contar o número de vezes que o caractere de comparação apareceu.
3. Escrever um programa que mostre os números primos entre 1 e 100.
4. Escreva um programa que leia um número não determinado de valores positivos, e mostre a soma e média dos respectivos números ao ser lido um valor negativo.
5. Faça um programa que leia um número (inteiro) e escreva todos os seus divisores.
6. Faça um programa que receba como entrada uma quantia em dinheiro e mostre na tela a quantidade de notas de 5, 10, 50 e 100 são necessárias para representar o valor. O programa deve contabilizar a partir das notas de 100.
7. Suponha um número N qualquer: se N é par então N agora é N / 2; se N é ímpar N agora é 3*N + 1. Assim para N = 3 calculamos a seguinte tabela :
3 10 4 2 10 5 2 1 5 16 1 4 16 8 4 2 8 4 2 1
Observe que a partir de sete iterações a seqüência 4 2 1 começa a se repetir . Faça um programa que calcule para um dado N o número de iterações até se chegar ao primeiro 1 .
8. Faça um programa que imprima os elementos de uma PA e o somatório da mesma dados : primeiro termo , número de termos e razão
9. Faça um programa que imprima um elemento da seqüência de Fibonacci, dado o numero do elemento.
10. Faça um programa onde o usuário entra com um número decimal e o mesmo calcula e imprime o número no sistema binário .
11. Faça um programa onde o usuário entra com dois números A e B o programa devolve como resultado A elevado a B .
12. Escreva um programa que solicite ao usuário três números inteiros a,b,c onde a é maior que 1 . Seu programa deve somar todos os inteiros entre b e c divisíveis por a.
13. Escrever um programa que leia os códigos e taxas de consumo, em Kw, dos consumidores de uma cidade. O programa pára de ler quando o código fornecido for zero. O programa deve escrever a média de consumo e os valores da maior e menor taxa de consumo.
14. Seja o seguinte programa: #include <stdio.h> void main(){ int t_ant = 1, t_atu = 1, aux, i = 2, n; scanf("%d", &n); printf("1 "); if (n>1)
46 Linguagem de Programação C
while (i<=n){ printf("%d ", t_atu); aux = t_atu; t_atu = t_atu+t_ant; t_ant = aux; i++; } }
O que será escrito na tela, supondo que o valor fornecido para n seja 6? Mostre o teste de mesa completo utilizado para determinar a saída.
15. Existe um algoritmo interessante para se obter a raiz quadrada de um número quando ela é exata. Para isso, basta subtrair números ímpares consecutivos do número do qual se deseja retirar a raiz quadrada. O número de vezes será a raiz do número. Por exemplo:
0975312525 =−−−−−=
No exemplo, subtraíram‐se de 25 os 5 primeiros números ímpares consecutivos até que se chegasse 0. Assim, a raiz quadrada de 25 é 5. Faça um programa que leia um inteiro n e escreva a raiz quadrada de n. Por exemplo, se o número lido foi 49, ele escreverá 7. O calculo da raiz quadrada deverá ser feito usando o algoritmo acima, sem usar qualquer função pré‐existente em alguma biblioteca C.
16. Escreva um programa que lê um número não determinado de conjuntos de valores, cada um formado pelo número de um aluno e suas 3 notas. O programa calcula, para cada aluno, a média ponderada com pesos respectivos de 4 para a maior nota e 3 para as outras duas. Ele também escreve o número do aluno, suas 3 notas, a média calculada e uma mensagem "Aprovado" se sua nota for maior ou igual a 6 ou "Exame" se sua nota menor do que 6. O programa pára de ler dados quando o número fornecido for 0.
17. O valor de PI/2 pode ser calculado pela seguinte série de produtos:
L88
78
76
56
54
34
32
12
2=
π
Faça um programa que calcule e escreva este produto com 10000 termos.
18. Um aço é classificado de acordo com o resultado de três testes, que devem verificar se ele satisfaz às seguintes especificações:
• Teste 1: conteúdo de carbono abaixo de 7%;
• Teste 2: dureza Rokwell maior que 50;
• Teste 3: resistência à tração maior do que 80.000 psi.
O aço recebe grau 10 se passa pelos três testes; 9, se passa apenas nos testes 1 e 2; 8, se passa no teste 1; e 7, se não passou nos três testes. Faça um programa em C que leia números de amostras e, para cada amostra, leia o conteúdo de carbono (em %), a dureza Rokwell e a resistência à tração (em psi), e escreva o número da amostra e grau obtido. O programa pára de ler amostras quando o número de amostra fornecido seja negativo.
19. Faça um programa em C que gere todos os números que são múltiplos de 2, 3, 5 e 7 simultaneamente, de 1 a 1000000.
47 Linguagem de Programação C
20. Faça um programa em C que gere uma tabela com os números de 1 a 100 com seus divisores. A saída deve ser na forma:
Número Divisores
1 1 2 1, 2 3 1, 3 4 1, 2, 4 ...
21. Escreva um programa em C que leia dois valores numéricos: n e teto. O programa deve ler, então, n valores numéricos e escrever o percentual de valores lidos maiores do que teto.
22. Escreva um programa em C que leia três valores numéricos: n, valor1 e valor2. O programa deve ler, então, n valores numéricos e escrever o percentual de valores lidos menores do que valor1 e o percentual de valores lidos maiores do que valor2.
23. Altere programa abaixo para que ele repita a pergunta ate que o caractere lido seja valido (independentemente de ser em maiúscula ou minúscula).
#include <stdio.h> void main(){ char ch; printf(“Deseja continuar? (s/n)\n”); ch = getche(); if (ch == 's') printf("Continua...") else if (ch == 'n') printf("Nao continua...") }
24. Faça um programa em C que leia um número n (inteiro positivo menor que 10000) e escreva todos os números de 0 a n cuja soma dos dígitos formantes é 10. Por exemplo, se n = 160, o programa escreverá
19 28 37 46 55 64 73 82 91 109 118 127 136 145 154
25. Foram entrevistados 500 alunos de uma universidade. Para cada alunos entrevistado foi registrado o código do curso que ele freqüenta (1: engenharia; 2: computação; 3: administração) e sua idade. Faça um programa em C que processe tais dados fornecendo as seguintes informações:
• número de alunos por curso;
• número de alunos com idade entre 20 e 25 anos, por curso; e
• cursos com a menor média de idade.
26. Faça um programa em C que, para cada vendedor de uma revenda de automóveis, leia seu código, seu salário fixo e o número de carros do tipo 1, do tipo 2 e do tipo 3 por ele vendido no mês. O código 0 (zero) indica que não há mais vendedores. O programa deve calcular e escrever o salário de cada vendedor. Para cada carro vendido, o vendedor recebe uma comissão de 5%. O valor de venda de um carro do tipo 1 é R$ 15.000,00; do tipo 2, R$ 20.000,00; do tipo 3 R$ 30.000,00. Além da comissão, o vendedor recebe um bônus de acordo com o total de vendas (independentemente do tipo de carro vendido) conforme segue:
• se ele vendeu mais de 5 carros, o bônus é de R$ 300,00;
• se ele vendeu mais de 8 carros, o bônus é de R$ 500,00; e
• se ele vendeu mais de 10 carros, o bônus é de R$ 1000,00.
48 Linguagem de Programação C
27. 18) Escreva um programa em C que leia um número e escreva seu fatorial. O fatorial de n é representado por n! sendo que
0! = 1 1! = 1 2! = 1.2 = 2 3! = 1.2.3 = 6 4! = 1.2.3.4 = 24 5! = 1.2.3.4.5 = 120
28. Faça um programa em C leia os resultados da eleição de 300 candidatos às cinco vagas de deputado estadual. Os dados são: número do candidato e número de votos obtidos. O programa deve escrever os números dos 5 candidatos eleitos.
29. Faça um programa em C que leia a área de uma floresta e a taxa anual de desmatamento. O programa deve informar em quantos anos a floresta estará completamente desmatada.
30. Escrever um programa em C que lê 100 conjuntos de 2 valores, representando o número de um aluno (num) e sua altura (Ai) em centímetros. O programa deve escrever a média aritmética das alturas e os números dos alunos mais alto e mais baixo.
31. Faça um programa em C que calcule o resultado final da eleição para presidência da república. Existem 4 (quatro) partidos disputando a eleição, cujos códigos são 12, 13, 14 e 15; para computar os votos, o programa lê o código do partido votado. O código 0 (zero) indica voto em branco, código 1 (um) indica voto nulo. O programa pára de ler códigos quando o código fornecido for ‐1. O programa deverá apurar e escrever o total de votos recebidos por cada partido, o total de votos brancos e o total de votos nulos. Ele também deverá informar se há necessidade de um segundo turno, i.e., O partido mais votado não obteve 50% + 1 dos votos válidos (não‐brancos, não‐nulos). No caso de não haver segundo turno, o programa deve escrever o partido vencedor; no caso de haver o segundo turno, o programa deve escrever quais partidos o disputarão.
32. Decidiu‐se, em uma linha de produção, fazer uma verificação da taxa de uso diária dos equipamentos. Faça um programa em C que leia o código do equipamento e sua taxa de uso diária (número horas/dia). O programa deve escrever:
• o código do equipamento mais usado;
• o número de equipamentos cuja taxa de uso é igual ou superior a 15 horas/dia; e
• o número de equipamentos cuja taxa de uso é igual ou inferior a 5 horas/dia.
A entrada de dados deve ser finalizada quando o código de equipamento informado for zero.
33. Um determinado tipo de aplicação financeira rende uma taxa fixa por mês. Faça um programa em C que leia o saldo da aplicação, a taxa (percentual), um determinado número de meses e informe o saldo, passado esse número de meses.
34. Para o programa em C abaixo, diga o que será escrito na tela, supondo que o valor fornecido para N foi 6? Mostre o teste de mesa completo utilizado para determinar a saída.
#include<stdio.h> void main(){ int N, i=0, divs=1; printf("Forneça um número inteiro\n");
49 Linguagem de Programação C
scanf("%d",&N); do{ if (N%i == 0) divs+= i; i++; } while(i <= N/2); if (divs == N) printf("%d é perfeito",N); else printf("%d não é perfeito",N); }
35. Uma loja cobra, por produtos vendidos no crediário, uma taxa de 1,5% ao mês. Faça um programa em C que leia o preço do produto à vista e o número de vezes em que ele será pago. O programa deve escrever o preço final do produto para o número de vezes informado.
36. O valor de π pode ser calculado pela seguinte série:
( ) ( ) ( ) ( )5,014
5,0314
5,0214
5,0114
2222 −×+++
−×++
−×++
−×+=
nwwwwLπ
onde
nw 1
=
e n é o número de termos. Faça um programa em C que leia o valor de n e calcule e escreva o valor
de π, através desse algoritmo, com n termos.
37. Mostre, para cada linha executada do programa abaixo, os valores das variáveis, considerando que o valor fornecido para n foi 18. 01 #include<stdio.h> 02 void main(){ 03 int N, i=0, divs=1; 04 scanf("%d",&N); 05 do{ 06 if (N%i == 0) divs = divs +i; 07 i++; 08 } while(i <= N/2); 09 }
50 Linguagem de Programação C
10 FUNÇÕES
A forma geral de uma função é:
Sintaxe: tipo_função nome_função (declaração_parâmetros) { ..declaração_de_variáveis; corpo_função; }
Exemplo 10.1 int soma(int x, int y) { ... }
As funções retornam um valor (do tipo indicado em tipo_função). O valor retornado pela função é dado pelo comando return (o valor retornado pode ou não ser utilizado).
Existem dois tipos de passagem de argumentos: por valor e por referência. A segunda é realizada através de apontadores.
Exemplo 10.2 int pot(int x, int n) { /* x elevado na n potência */ int p; for(p=1;n>0;n--) p *= x; return p; }
No Exemplo 10.2, os argumentos foram passados por valor e a função retorna um valor do tipo inteiro. A chamada seria:
a = pot(10,2);
No Exemplo 10.3, nenhum valor é retornado (por isso usa‐se o tipo void) mas é realizado uma troca dos valores das variáveis, necessitando de uma passagem de parâmetros por referência.
Exemplo 10.3 /* troca os valores de duas variáveis*/
void troca(int *a, *b) { int aux; aux = *a; *a = *b; *b = aux; }
A chamada para esta função seria:
int x=1,y=2; troca(&x,&y);
Na passagem de parâmetros por referência é passado explicitamente o endereço da variável com o uso do operador &. Quando o argumento for uma matriz automaticamente será passado o endereço da matriz para a função.
51 Linguagem de Programação C
A linguagem C aceita chamadas recursivas de funções.
10.1 LOCALIZAÇÃO DAS FUNÇÕES
Existem basicamente duas posições possíveis para escrevermos o corpo de uma função: ou antes ou depois do programa principal. Podemos ainda escrever uma função no mesmo arquivo do programa principal ou em arquivo separado.
10.1.1 CORPO DA FUNÇÃO ANTES DO PROGRAMA PRINCIPAL (NO MESMO ARQUIVO)
Quando escrevemos a definição de uma função antes do programa principal e no mesmo arquivo deste, nenhuma outra instrução é necessária.
Exemplo 10.4 float media2(float a, float b) { // função
float med; med = (a + b) / 2.0; return(med); }
int main() { // programa principal
float num_1, num_2, med; puts(”Digite dois números:”); scanf(”%f %f”, &num_1, &num_2); med = media2(num_1, num_2); // chamada da função printf(”\nA media destes números e´ %f”, med);
return 0; }
Para que uma função seja reconhecida durante a compilação devemos de‐clará‐la ou defini‐la antes de qualquer referência que é feita a ela no resto do programa.
10.1.2 CORPO DA FUNÇÃO DEPOIS DO PROGRAMA PRINCIPAL (NO MESMO ARQUIVO)
Quando escrevemos a definição de uma função depois do programa principal e no mesmo arquivo deste, devemos incluir um protótipo da função chamada. Um protótipo é uma instrução que define o nome da função, seu tipo de retorno e a quantidade e o tipo dos argumentos da função. O protótipo de uma função indica ao compilador quais são as funções usadas no programa principal os tipo. A sintaxe geral para isto é a seguinte:
Sintaxe: int main() { // programa principal tipo nomef(...); // protótipo da função ... var = nomef(...) // chamada a função ... }
tipo nomef(...){ // definição da função
52 Linguagem de Programação C
[corpo de função] }
Exemplo 10.5 #include <stdio.h> int main() { // programa principal
float media2(float,float); // protótipo de media2() float num_1, num_2, med; puts(”Digite dois números:”); scanf(”%f %f”, &num_1, &num_2); med = media2(num_1, num_2); // chamada a função printf(”\nA media destes números e´ %f”, med);
} float media2(float a, float b){ // função media2()
float med; med = (a + b) / 2.0; return(med); }
Protótipo de uma função nada mais é que a declaração da função sem o seu corpo. Por isso, a lista de argumentos do protótipo podem ser escritas apenas com os tipos dos argumentos.
10.1.3 CORPO DA FUNÇÃO ESCRITO EM ARQUIVO SEPARADO
Em C, como em muitas outras linguagens, é permitido que o usuário crie uma função em um arquivo e um programa que a chame em outro arquivo distinto. Esta facilidade permite a criação de bibliotecas de usuário: um conjunto de arquivos contendo funções escritas pelo usuário. Esta possibilidade é uma grande vantagem utilizada em larga escala por programadores profissionais.
Quando escrevemos a definição de uma função em arquivo separado do programa principal devemos incluir este arquivo no conjunto de arquivos de compilação do programa principal. Esta inclusão é feita com a diretiva #include. Esta diretiva, vista nas seções 2.4.2 e 3.7.1, instrui o compilador para incluir na compilação do programa outros arquivos que contem a definição das funções de usuário e de biblioteca.
Sintaxe: #include ”path” // inclusão da função int main() { // programa principal ... var = nomef(...) // chamada a função ... }
Na diretiva #include, indicamos entre aspas duplas o caminho de localização do arquivo onde está definida a função chamada.
Exemplo 10.6 #include ”c:\tc\userbib\stat.h” // inclusão da função int main() { // programa principal
float num_1, num_2, med; puts(”Digite dois números:”); scanf(”%f %f”, &num_1, &num_2); med = media2(num_1, num_2); // chamada a função printf(”\nA media destes números e´ %f”, med);
return 0;
53 Linguagem de Programação C
}
10.2 PROTÓTIPO DE FUNÇÕES
O padrão ANSI C expandiu a declaração tradicional de função, permitindo que a quantidade e os tipos dos argumentos das funções sejam declarados. A definição expandida é chamada protótipo de função. Protótipos de funções não faziam parte da linguagem C original.
Protótipos permitem que C forneça uma verificação mais forte dos tipos. Protótipos de funções ajudam a detectar erros antes que eles ocorram. É verificado número de parâmetros, compatibilidade de tipos, entre outras.
Existem três tipos de declaração de protótipos:
Sintaxe Exemplo tipo_função nome_função (); int pot(); tipo_função nome_função (lista_tipo_argumentos); int pot(int,int); tipo_função nome_função (lista_tipo_nome_argumentos); int pot(int x, int y);
10.3 DIRETIVA #DEFINE
A diretiva #define pode ser usada para definir constantes simbólicas com nomes apropriados. Por exemplo, a constante PI pode ser definida com o valor 3.14159.
#define PI 3.14159
Só pode ser escrito um comando destes por linha, e não há ponto‐e‐vírgula após qualquer diretiva do pré‐processador.
A diretiva #define é definida como uma macro, isto é, antes do código ser compilado, o pré‐processador substitui todas as instâncias iguais ao que está definido pela diretiva. O pré‐processador realmente muda o código fonte para que o compilador possa realizar a sua análise.
Esta diretiva é usada para definir macros com argumentos.
#define AREA(x) (4*PI*x*x)
A declaração acima define a função AREA() a qual calcula a área de uma esfera. A vantagem desta declaração é não tipagem do argumento x. Não deve haver espaços entre o nome da macro e seus identificadores.
Cuidado ao utilizar #define para expressões, pois como o texto é substituído pelo que foi definida, a precedência de operadores pode alterar o resultado desejado. Por isso, recomenda‐se o uso de parênteses ao redor de expressões.
O Exemplo 10.7 mostra como o resultado de uma expressão pode ser afetado por uma macro incorretamente definida.
Exemplo 10.7 #include <stdio.h>
54 Linguagem de Programação C
#define EXPRESSAO(x) x+5 #define EXPRESSAO2(x) (x+5) int main() { int i = printf("Incorreto: %2d\n",5 * EXPRESSAO(3)); printf("Correto: %2d\n",5 * EXPRESSAO2(3)); return 0; }
Execução Incorreto: 20 Correto: 40
10.4 EXERCÍCIOS
1. Escreva um programa que receba como parâmetro um índice (float). Após, ler uma sequência de números (a qual termina por 0) e exibir o seu valor multiplicado pelo índice. A função que transforma uma string em um float é atof(char *x).
2. Escreva uma função que receba um caractere como argumento e que retorne a letra maiúscula se a mesma for minúscula. funções: islower(int ch), toupper(int ch).
3. Existe um algoritmo interessante para se obter a raiz quadrada de um número quando ela é exata. Para isso, basta subtrair números ímpares consecutivos do número do qual se deseja retirar a raiz quadrada. O número de vezes será a raiz do número. Por exemplo:
0975312525 =−−−−−=
No exemplo, subtraíram‐se de 25 os 5 primeiros números ímpares consecutivos até que se chegasse 0. Assim, a raiz quadrada de 25 é 5. Escreva uma função que receba um inteiro n e retorne a raiz quadrada de n. Por exemplo, se a função receber 49, ele retornará 7. O calculo da raiz quadrada deverá ser feito usando o algoritmo acima, sem usar qualquer função pré‐existente de alguma biblioteca C.
4. Seja o seguinte programa:
#include<stdio.h> void x(int n){ int i, resto; i = n; do{ resto = i%16; i=i/16; switch(resto){ case 10: printf("A"); break; case 11: printf("B"); break; case 12: printf("C"); break; case 13: printf("D"); break; case 14: printf("E"); break; case 15: printf("F"); break; default: printf("%d", resto); } }while(i>0); printf("\n"); } void main(){
55 Linguagem de Programação C
int N; scanf("%d",&N); x(N); }
O que será escrito na tela, supondo que o valor fornecido para N seja 10846? Mostre o teste de mesa completo utilizado para determinar a saída.
5. Simule a execução do programa abaixo mostrando todas as mudanças de valores de variáveis e o resultado da impressão.
#include<stdio.h> int perf(long int N){ long int i, divs=0; for(i=1; i<= N/2; i++) if (N%i == 0) divs = divs + i; if (divs == N) return 1; else return 0; } void main(){ long int x=14; if (perf(x)==1) printf("%d ‚ perfeito",x); else printf("%d nÆo ‚ perfeito",x); }
6. Escreva uma função em C que receba como argumentos a altura (alt) e o sexo de uma pessoa e retorne o seu peso ideal. Para homens, calcular o peso ideal usando a fórmula
PI h= 72.7× alt− 58 e , para mulheres,
PI m= 62.1× alt− 44.7 .
7. Escreva uma função em C com o seguinte protótipo
long int multiplicatório(int i, int n)
A função deve retornar o multiplicatório de i a n. Por exemplo, a chamada
multiplicatório(3,10)
retorna 1814400 (3×4×5×6×7×8×9×10).
8. Escreva uma função em C com o seguinte protótipo
long int somatório(int i, int n)
A função deve retornar o somatório de i a n. Por exemplo, a chamada
somatório(3,10)
retorna 52 (3+4+5+6+7+8+9+10).
9. Escreva uma função em C que receba dois números e retorne o maior deles.
10. A aceleração é a taxa de variação da velocidade em relação ao tempo, isto é, a razão entre a variação da velocidade e o intervalo de tempo. Matematicamente,
56 Linguagem de Programação C
tva
ΔΔ
=
onde
if vvv −=Δ
é a variação da velocidade ou a velocidade final menos a velocidade inicial. Escreva uma função em C que receba como parâmetros a velocidade inicial, a velocidade final e o intervalo de tempo correspondente e retorne a aceleração. Mostre, também, uma função main() que chame essa função.
11. O valor de π/2 pode ser calculado pela seguinte série de produtos:
L88
78
76
56
54
34
32
12
2=
π
Escreva uma função em C que receba como argumento um número inteiro n e retorne o valor de π calculado através da série acima com n termos.
12. Um aço é classificado de acordo com o resultado de três testes, que devem verificar se ele satisfaz às seguintes especificações:
• Teste 1: conteúdo de carbono abaixo de 7%;
• Teste 2: dureza Rokwell maior que 50;
• Teste 3: resistência à tração maior do que 80.000 psi.
O aço recebe grau 10 se passa pelos três testes; 9, se passa apenas nos testes 1 e 2; 8, se passa no teste 1; e 7, se não passou nos três testes. Escreva uma função em C que o conteúdo de carbono (em %), a dureza Rokwell e a resistência à tração (em psi) de uma amostra de aço e retorne o grau obtido.
13. Escreva uma função em C que receba um número n e retorne 1 se a soma dos dígitos formantes de n for 10; 0 caso contrário. Por exemplo, se o valor de n recebido for 145 a função retorna 1.
14. Escreva uma função em C que receba um numero e retorne seu fatorial. O fatorial de n é representado por n! sendo que
0! = 1 1! = 1 2! = 1×2 = 2 3! = 1×2×3 = 6 4! = 1×2×3×4 = 24 5! = 1×2×3×4×5 = 120
15. Defina as macros descritas a seguir: a) eh_minuscula(c): informa se o caractere c é uma letra minúscula. b) eh_maiuscula(c): informa se o caractere c é uma letra maiúscula. c) minuscula(c): converte a letra c para minúscula. d) maiuscula(c): converte a letra c para maiúscula.
57 Linguagem de Programação C
11 VETORES E MATRIZES
Vetores e matrizes são estruturas de dados usada para representar uma certa quantidade de variáveis de valores homogêneos. Em C, estas estruturas precisam ser declaradas, como quaisquer outras variáveis, para que o compilador conheça o tipo do vetor ou da matriz e reserve espaço de memória suficiente para armazená‐lo.
O que diferencia a declaração de uma matriz ou vetor da declaração de qualquer variável é a parte que segue o nome, isto é, os pares de colchetes ([ e ]) que envolvam um número inteiro, que indica ao compilador o tamanho da matriz.
int notas[5];
A declaração acima aloca um intervalo de memória com nome notas para armazenar 5 elementos do tipo int. Por definição um vetor ou matriz é composto por elementos de um único tipo.
Para a declaração de mais de uma dimensão em C é necessário o número de par de colchetes ser igual ao número de dimensões. Isto é, se a matriz for de duas dimensões teremos uma declaração assim:
int notas[5][5];
que declara uma matriz bi‐dimensional; para três dimensões assim
int notas[5][5][5];
que declara uma matriz tridimensional e assim por diante. O limite de índices é definido pelo compilador ou pela memória.
Os elementos do vetor ou da matriz são sempre enumerados por índices iniciados por 0 (zero).
Exemplo 11.1 for (i=0;i<5;i++) { printf(“Digite a nota do aluno %d:”,i); scanf(“%d”, ¬as[i]); }
A linguagem C não realiza verificação de limites em matrizes!
11.1 INICIALIZAÇÃO DE VETORES E MATRIZES
Como o C permite a inicialização de variáveis básicas, também é permitido a inicialização de vetores e matrizes.
Exemplo 11.2 int TAB[5]={1,5,10,15,20} int MAT[5][6]={ { 1, 0, 1, 0, 1, 0 }, { 0, 1, 0, 1, 0, 1 }, { 1, 0, 1, 0, 1, 0 }, { 0, 1, 0, 1, 0, 1 }, { 1, 0, 1, 0, 1, 0 } };
58 Linguagem de Programação C
Quando houver uma inicialização de um vetor ou uma matriz na declaração, pode‐se suprimir sempre o valor do primeiro colchete, isto é, pelo número de argumentos ele assume o número do primeiro colchete.
Exemplo 11.3 int TAB[]={1,5,10,15,20} int MAT[][6]={ { 1, 0, 1, 0, 1, 0 }, { 0, 1, 0, 1, 0, 1 }, { 1, 0, 1, 0, 1, 0 }, { 0, 1, 0, 1, 0, 1 }, { 1, 0, 1, 0, 1, 0 } };
11.2 MATRIZES E VETORES COMO ARGUMENTO DE FUNÇÕES
O C permite que passe matrizes ou vetores como argumento de uma função. Mas há uma peculiaridade na passagem de parâmetros: a forma como ela é passada.
O nome de uma matriz ou vetor desacompanhado de colchetes é equivalente ao endereço da matriz ou do vetor, isto é, passagem por referência.
Quando o nome estiver acompanhado de um indexador é passado como argumento o conteúdo daquela posição da matriz ou do vetor, isto é, passagem por valor.
11.3 LIMITES
Na linguagem C, devemos ter cuidado com os limites de um vetor. Embora na sua declaração, tenhamos definido o tamanho de um vetor, o C não faz nenhum teste de verificação de acesso a um elemento dentro do vetor ou não.
Por exemplo se declaramos um vetor como int valor[5], teoricamente só tem sentido usarmos os elementos valor[0], ..., valor[4]. Porém, o C não acusa erro se usarmos valor[12] em algum lugar do programa. Estes testes de limite devem ser feitos logicamente dentro do programa.
Este fato se deve a maneira como o C trata vetores. A memória do microcomputador é um espaço (físico) particionado em porções de 1 byte. Se declaramos um vetor como int vet[3], estamos reservando 6 bytes (3 segmentos de 2 bytes) de memória para armazenar os seus elementos. O primeiro segmento será reservado para vet[0], o segundo segmento para vet[1] e o terceiro segmento para vet[2]. O segmento inicial é chamado de segmento base, de modo que vet[0] será localizado no segmento base. Quando acessamos o elemento vet[i], o processador acessa o segmento localizado em base+i. Se i for igual a 2, estamos acessando o segmento base+2 ou vet[2](o ultimo segmento reservado para o vetor). Porém, se i for igual a 7, estamos a acessando segmento base+7 que não foi reservado para os elementos do vetor e que provavelmente está sendo usado por uma outra variável ou contém informação espúria (lixo).
Acessar um segmento fora do espaço destinado a um vetor pode destruir informações reservadas de outras variáveis. Estes erros são difíceis de detectar, pois o compilador não gera nenhuma mensagem de erro. A solução mais adequada é sempre avaliar os limites de um vetor antes de manipulá‐lo.
59 Linguagem de Programação C
A princípio este fato poderia parecer um defeito da linguagem, mas na verdade trata‐se de um recurso muito poderoso do C. Poder manipular sem restrições todos os segmentos de memória é uma flexibilidade apreciada pelos programadores.
11.4 EXERCÍCIOS
1. Faça um programa que leia 10 valores inteiros e escreva‐os na ordem inversa a que foram lidos.
2. Faça um programa que leia 10 valores inteiros, calcule sua média e escreva todos os valores que estão abaixo da média.
3. Calcular os números primos entre 0 e 100 (inclusive) utilizando o crivo de Eritóstenes:
Usar um vetor de 101 inteiros; zerar o vetor; repetir de 2 a 100
para cada número: somar 1 a todos os contadores dos seus múltiplos. ao final os números que possuem 0 no vetor são primos.
4. Escreva um programa que leia um vetor de 100 posições e mostre‐o em ordem crescente e decrescente.
5. Faça um programa que leia uma matriz M[10][10] e some todos os elementos abaixo da diagonal principal.
6. Faça um programa que leia uma matriz M[4][4] e mostra a sua transposta.
7. Escreva uma função que realize a multiplicação de matrizes.
8. Escreva uma função que receba um vetor e o tamanho do mesmo e troque os elementos (1º com o último, o 2º com o penúltimo e assim por diante).
9. Faça um programa em C que leia dois vetores unidimensionais A e B, de dimensão 8, e realize a troca dos elementos destes vetores; ou seja, após a execução do programa o vetor B deverá conter os valores fornecidos para o vetor A, e vice‐versa.
10. Escreva um programa em C que realize o controle das vagas de um estacionamento, representado através de um vetor. A posição i do vetor marcada com 1 indica que a vaga i está ocupada; se a posição estiver marcada com 0, a vaga está livre. Inicialmente, todas as vagas estão livres (o estacionamento tem 20 vagas). O programa deve constantemente requisitar ao operador a operação a ser executada. São oferecidas três operações: saída de veículo ('s' ou 'S'), entrada de veículo ('e' ou 'E') e deixar o programa ('d' ou 'D'). Seja, por exemplo, o estacionamento na seguinte situação:
60 Linguagem de Programação C
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
O estado do vetor representando o estacionamento seria:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 0 1 0 1 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0
Quando um veículo sai dos estacionamento, o programa deve atualizar o vetor refletindo a nova vaga livre; quando um veículo entra no estacionamento, o programa deve informar qual a vaga livre (se existir) mais próxima da entrada e atualizar o vetor refletindo a nova vaga ocupada.
11. Seja uma floresta de 1.000.000.000 m2. Com um percentual de desmatamento corrente de 1.2% ao ano que aumenta 50% ao ano. Assim, no próximo ano ele aumentará para 1.8% (1.2 + 0.6), depois 2.7% (1.8 + 0.9), 4.05% (2.7 + 1.35) etc. Faça um programa em C que coloque em um vetor os percentuais de desmatamento dos próximos 10 anos e em outro vetor a área desmatada correspondente.
12. Faça um programa em C que armazene em um vetor os 50 primeiros números primos.
13. Faça um programa em C que leia um conjunto de 50 valores em um vetor A. Depois de lidos os 50 valores, o programa deverá colocar em vetor P os elementos pares de A e em I os elementos ímpares.
14. Faça um programa em C que leia o primeiro termo de uma progressão geométrica (a1) e a razão (q). O programa deve colocar em um vetor os 100 primeiros termos da progressão. Um termo qualquer da progressão será o resultado da multiplicação do valor do termo anterior pela razão, i.e.,
an = an-1×q
15. Faça um programa em C que leia dois vetores numéricos v1 e v2 de 100 posições e calcule o produto escalar deles. O produto escalar é dado pelo somatório da multiplicação de cada posição dos vetores, isto é,
Produto_esc = v1[0]×v2[0] + v1[1]×v2[1] + v1[2]×v2[2] + v1[3]×v2[3] + ...
16. Faça um programa em C que leia um vetor contendo os conceitos dos alunos de uma turma de 20. Os conceitos podem ser 'A', 'B', 'B', 'B' e 'E'. O programa deve desenhar um histograma horizontal correspondente à distribuição dos conceitos. Para o vetor de conceitos
0 1 2 3 4 5 6 7 8 9
'A' 'A' 'C' 'B' 'A' 'B' 'A' 'B' 'D' 'B'
61 Linguagem de Programação C
10 11 12 13 14 15 16 17 18 19
'A' 'B' 'C' 'E' 'C' 'C' 'A' 'C' 'A' 'B'
o histograma ser desenhado seria
A ▒▒▒▒▒▒▒ B ▒▒▒▒▒ C ▒▒▒▒▒▒ D ▒ E ▒
O código ASCII do caractere ▒ é 176.
17. Escreva um programa em C que leia os códigos e conceitos dos alunos de uma turma de tamanho máximo 60. O programa deverá colocar em um vetor a situação de cada aluno: 'A', se o conceito for superior a 0; 'E' caso contrário. O algoritmo pára de ler quando o código informado for 0. Por exemplo,
1 2 3 4 5 6 7 8 59
'A' 'A' 'A' 'E' 'A' 'A' 'E' 'E' ... ’A'
18. Faça um programa em C que calcule e escreva a média móvel. O programa deverá executar um laço de leitura de valores inteiros e positivos; a introdução de valores negativos servirá como indicador de término de leitura. Para cada valor fornecido, deverá ser impressa a média calculada. A média móvel é efetuada sobre um número especificado de pontos. Quando se introduz um novo dado, descarta‐se o valor mais antigo dando‐se lugar ao novo dado. Este esquema de substituição faz da média móvel um instrumento valioso na análise de tendências. Quanto menor o número de dados, mais sensível será com relação à média. Considerar para a solução deste problema 10 pontos(valores), armazenados em um vetor. Supondo, por exemplo, que em um determinado momento o vetor tem os seguintes valores
0 1 2 3 4 5 6 7 8 9
5 7 4 2 5 3 4 6 7 4
e o novo valor lido foi 3. A média móvel será
( )10
3476435247 +++++++++
Observe que no cálculo o valor mais antigo (5) foi substituído por 3 (o mais recente). O vetor agora ficará assim:
0 1 2 3 4 5 6 7 8 9
7 4 2 5 3 4 6 7 4 3
Se na próxima leitura for lido o valor 4, a média móvel será
( )10
447643524 ++++++++
O valor mais antigo (7), que foi substituído pelo 4 e o vetor agora ficará assim:
0 1 2 3 4 5 6 7 8 9
62 Linguagem de Programação C
4 2 5 3 4 6 7 4 3 4
19. Escreva um programa em C que leia um vetor de 20 posições e o escreva. A seguir, o programa deve compactar o vetor, retirando dele todos os valores nulos ou negativos e escrever o vetor compactado. Após, ele deve ser ainda mais compactado, através da retirada dos elementos em duplicados.
20. Escreva uma função em C com o seguinte protótipo:
void digitosSomam10(int i, int j, int V[10])
A função coloca no vetor V os 10 primeiros números de i a j cuja soma dos dígitos formantes é 10. Por exemplo, se i=10 e j=200, então
0 1 2 3 4 5 6 7 8 9
19 28 37 46 55 64 73 82 91 109
Se entre i e j não houverem 10 números cuja soma dos dígitos formantes, as demais posições não preenchidas deverão ser completadas com ‐1.
21. Escreva uma função em C com o seguinte protótipo:
void interseccao(char V1[10], char V2[10], char V3[10])
A função recebe os vetores V1 e V2 preenchidos e coloca em V3 o resultado da intersecção de V1 e V2, i.e., coloca em V3 apenas os caracteres que estão contidos nos dois vetores. Exemplo:
V1 0 1 2 3 4 5 6 7 8 9
'A' 'E' 'F' '6' '$' 'H' 'M' 'O' 'X' 'Z'
V2
0 1 2 3 4 5 6 7 8 9
'B' 'C' 'K' 'E' 'F' 'G' 'T' 'O' 'M' '6'
V3
0 1 2 3 4 5 6 7 8 9
'E' 'F' 'O' 'M' '6' ' ' ' ' ' ' ' ' ' '
22. Escreva uma função em C com o seguinte protótipo:
void parteInteira(double V1[10], double V2[10])
A função recebe os vetores V1 preenchido e coloca em V2 a parte inteira e sem sinal dos elementos de V1. Exemplo:
V1
0 1 2 3 4 5 6 7 8 9
15 -67 13.14 96.7 -43.04 99 -6 78.01 123 -7.07
V2
0 1 2 3 4 5 6 7 8 9
15 67 13 96 43 99 6 78 123 7
23. Escreva uma função em C com o seguinte protótipo:
63 Linguagem de Programação C
void uniao(char V1[10], char V2[10], char V3[20])
A função recebe os vetores V1 e V2 preenchidos e coloca em V3 o resultado da união de V1 e V2, i.e., coloca em V3 os caracteres que estão contidos nos dois vetores, não repetindo ocorrências. Por exemplo:
V1
0 1 2 3 4 5 6 7 8 9
'A' 'E' 'F' '6' '$' 'H' 'M' 'O' 'X' 'Z'
V2
0 1 2 3 4 5 6 7 8 9
'B' 'C' 'K' 'E' 'F' 'G' 'T' 'O' 'M' '6'
V3
0 1 2 3 4 5 6 7 8 9
'A' 'E' 'F' '6' '$' 'H' 'M' 'O' 'X' 'Z'
10 11 12 13 14 15 16 17 18 19
'B' 'C' 'K' 'G' 'T' ' ' ' ' ' ' ' ' ' '
24. Faça um programa em C que leia uma matriz 5�5. Após lido, a matriz deverá ser invertida, isto é, as linhas tornar‐se‐ão colunas e as colunas tornar‐se‐ão linhas. Na figura abaixo, é mostrado um exemplo de inversão.
0 1 2 3 4 0 1 2 3 4
0 3 9 10 10 2 0 3 13 20 7 8
1 13 4 86 20 7 1 9 4 2 3 11
2 20 2 7 7 13 2 10 86 7 60 77
3 7 3 60 33 2 3 10 20 7 33 21
4 8 11 77 21 1 4 2 7 13 2 1
25. Faça um programa em C que leia uma matriz 5x5 e escreva se ela é simétrica. Uma matriz é simétrica se ela é igual à sua transposta. A matriz M abaixo, por exemplo, é simétrica já que M = Mt.
M 0 1 2 3 4 Mt 0 1 2 3 4
0 1 3 9 0 31 0 1 3 9 0 31 1 3 5 11 10 20 1 3 5 11 10 20 2 9 11 66 7 13 2 9 11 66 7 13 3 0 10 7 33 10 3 0 10 7 33 10 4 31 20 13 10 0 4 31 20 13 10 0
26. Faça um programa em C que leia os códigos e as notas finais (entre 0 e 10) de uma turma de alunos de tamanho desconhecido (mas não maior que 60) até que o código fornecido seja negativo. O algoritmo deve escrever os códigos dos alunos que ficaram com nota final inferior à nota média da turma.
27. Escreva um programa em C que leia em dois vetores A e B, de 6 posições, números de um dígito. O programa deve colocar em um vetor C o resultado da subtração de A por B, posição por posição,
64 Linguagem de Programação C
considerando os casos em que o conteúdo da posição de A é menor do que o conteúdo da posição de B, conforme o exemplo abaixo.
0 1 2 3 4 5
A 7 8 1 0 0 9
0 1 2 3 4 5
B 3 4 2 0 3 4
0 1 2 3 4 5
C 4 3 8 9 7 5
65 Linguagem de Programação C
12 STRINGS (CADEIA DE CARACTERES)
Em C não existe um tipo de dado que represente uma cadeia de caracteres, também chamada de string. Ao contrário, as string são implementadas como um vetor de caracteres, terminados pelo caractere NULL (‘\0’). O caractere NULL serve como uma marca de fim de string para as funções que lidam com strings.
Como em qualquer vetor, os caracteres da string podem ser individualmente acessados.
A declaração:
char nome[15];
reserva um espaço de memória para uma string de tamanho 14, pois o décimo‐quinto byte é para o caractere NULL. A manipulação de strings pode ser feita através de funções ou elemento a elemento como se fosse um vetor.
Exemplo 12.1 char str[2]; str[0] = ‘U’; str[1] = ‘\0’; /* Caractere NULL para finalizar string */
Como todo vetor as strings podem ser inicializadas, como mostram o Exemplo 12.2:
Exemplo 12.2 char nome[]={‘C’,’a’,’r’,’l’,’o’,’s’,’\0’}; char nome[]=“Carlos”; char nomes[][8]={“Eduardo”, “Andre”, “Adriana”, “Carla”, “Jose”};
12.1 LEITURA DE STRINGS
Para ler uma string pode‐se utilizar a função scanf() ou a função gets() da biblioteca C para receber a string.
12.1.1 SCANF()
A função scanf() é bastante limitada para a leitura de strings. Pois não pode haver espaços em branco na string lida. O que vier após o espaço em branco é eliminado.
Exemplo 12.3 #include <stdio.h> int main() { char nome[15]; printf(“Digite seu nome:”); scanf(“%s”,&nome); printf(“Saudacoes %s”,nome);
return 0; }
66 Linguagem de Programação C
Execução Digite seu nome: Carlos Alberto Saudacoes, Carlos
O padrão ANCSI C adicionou ao scanf() um novo especificador de formato chamado scanset. O scanset representa um conjunto de caracteres que pode ser lido pela função scanf(). Para definir um scanset, utiliza‐se uma cadeia de caracteres a ser lida entre colchetes, precedidos por um %. O Exemplo 12.4 mostra alguns scansets e seu respectivo significado.
Exemplo 12.4 %[XYZ] ler apenas os caracteres X, Y, e Z %[0-9] ler apenas os caracteres de 0 a 9 %[A-Z] ler apenas os caracteres maiúsculos do alfabeto %[a-z] ler apenas os caracteres minúsculos do alfabeto
Quando o scanset é utilizado, a função scanf() continua lendo e armazenando os caracteres na string até que encontre um caractere que não pertença ao conjunto.
Para inverter a seleção, coloca‐se o caractere acento circunflexo (^) antes do conjunto de caracteres. Assim, a função scanf() não aceitará caractere algum do conjunto definido.
O Exemplo 12.5 mostra um código utilizando o scanset. No primeiro scanf(), somente os caracteres ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’ serão aceitos na leitura. No segundo scanf(), somente os caracteres maiúsculos do alfabeto serão aceitos na leitura. No terceiro scanf(), os dígitos de 0 a 9 não serão aceitos na leitura. Note que o usuário digitou caracteres fora do conjunto definido em todos os três scanf(), mas eles não foram lidos.
Exemplo 12.5 #include <stdio.h> int main() { char str[20]=””; scanf("%[abcdef]",str); fflush(stdin); printf("> %s\n",str); scanf("%[A-Z]",str); fflush(stdin); printf("> %s\n",str); scanf("%[^0-9]",str); printf("> %s\n",str); return 0; }
Execução: abcABC > abc ABCabc > ABC !@#123 > !@#
Caso a string inteira não é considerada válida, o scanf() não altera o conteúdo da string.
67 Linguagem de Programação C
12.1.2 GETS()
A função gets() é bastante conveniente para a leitura de strings. O seu propósito é unicamente ler uma string da sua entrada padrão que por default é o teclado.
Visto que uma string não tem um tamanho pré‐determinado, gets() lê caracteres até encontrar o de nova linha (‘\n’) que é gerado ao pressionar a tecla [Enter]. Todos os caracteres anteriores ao ‘\n’ são armazenados na string e é então incluído o caractere ‘\0’. Caracteres brancos como espaços e tabulações são aceitáveis como parte da string.
Exemplo 12.6 #include <stdio.h> int main() { char nome[15]; printf(“Digite seu nome:”); gets(nome); printf(“Saudações %s”,nome);
return 0; }
Execução Digite seu nome: Carlos Alberto Saudações, Carlos Alberto
12.2 ESCRITA DE STRINGS
Para escrever uma string pode‐se utilizar a função printf() ou a função puts() da biblioteca C.
12.2.1 PRINTF()
A função printf() ao imprimir a string não realiza uma nova linha, como é definido na sua implementação. Em compensação é uma função que pode ser usada para impressão de mais que uma string por linha.
12.2.2 PUTS()
A função puts() é o complementa de gets(). O seu propósito é unicamente imprimir a string apontada pelo seu argumento. O endereço desta string deve ser mandado para puts() como argumento.
O Exemplo 12.7 ilustra algumas das muitas possibilidades de seu uso.
Exemplo 12.7 /* mostra o uso de putc() */ #include <stdio.h> int main() { char nome[81]; puts(“Digite seu nome:”); gets(nome); puts(“Saudacoes, ”); puts(nome); puts(“puts() pula de linha sozinha”); puts(&nome[4]);
return 0; }
68 Linguagem de Programação C
Execução Digite seu nome: Carlos Alberto Saudacoes, Carlos Alberto puts() pula de linha sozinha los Alberto
A função puts() reconhece ‘\0’como fim de string. Cada impressão de puts(), ele acaba com um caractere de nova linha.
Utilizando a função printf() o mesmo efeito seria:
printf(“%s\n”,nome); puts(nome);
12.3 FUNÇÕES DE MANIPULAÇÃO DE STRINGS
Como strings são implementadas como vetores, os operadores usuais não podem ser aplicados sobre este tipo de dado. Por exemplo: comparação atribuição não são suportados por este tipo de dado.
As funções descritas nas próximas seções utilizam o cabeçalho padrão STRING.H.
12.3.1 STRLEN()
Devolve o comprimento da string terminada por um nulo apontada por str. O nulo não é contado.
Sintaxe: size_t strlen(char *str);
Exemplo 12.8 printf(“%d”,strlen(“ola”)); /* O resultado é 3 */
12.3.2 STRCAT()
Concatena uma cópia de str2 em str1 e termina str1 com um nulo. Como não existe verificação de limites, é de inteira responsabilidade do usuário que o tamanho de str1 seja suficientemente grande para armazenar seu conteúdo original e o de str2.
Sintaxe: char *strcat(char *str1, const char *str2);
Exemplo 12.9 printf(“%s”,strcat(“ola”, “ mundo”)); /* O resultado é ola mundo */
12.3.3 STRCMP()
Compara lexicograficamente duas strings e devolve um inteiro baseado no resultado como mostrado aqui:
Valor Significado
69 Linguagem de Programação C
Menor que zero str1 é menor que str2 Zero str1 é igual a str2 Maior que zero str1 é maior que str2
Sintaxe: int strcmp(const char *str1, const char *str2);
12.3.4 STRCPY()
Copia o conteúdo de str2 em str1. str2 deve ser um ponteiro para uma string terminada com um nulo. A função strcpy() devolve um ponteiro para str1.
Sintaxe: char *strcpy(char *str1, const char *str2);
Exemplo 12.10 char str[80]; strcpy(str, “mundo”); /* copia mundo na string str */
12.4 EXEMPLO GERAL
O programa abaixo exemplifica o uso das funções descritas anteriormente.
Exemplo 12.11 #include “stdio.h” #include “string.h” int main() { char s1[80], s2[80]; gets(s1); gets(s2); printf(“comprimento: %d %d \n”, strlen(s1), strlen(s2)); if (!strcmp(s1,s2)) printf(“As strings sao iguais\n”); strcat(s1,s2); printf(“%s\n”,s1); strcpy(s1, “Isso e um teste \n”); printf(s1); return 0; }
Ao rodar este programa e entrar com as strings “ola” e “ola”, a saída será
comprimentos: 3 3 As strings são iguais aloalo Isso e um teste
12.5 EXERCÍCIOS
1. Faça um programa que leia 3 nomes (até 30 letras) e os escreva em ordem alfabética.
2. Escreva um programa que leia um número indeterminado de caracteres e conta o número de vezes que cada letra (A‐Z) aparece:
70 Linguagem de Programação C
Desconsiderar se a letra é maiúscula ou minúscula; Termina com o caractere ´0´.
3. Escrever a função atoi() (recebe uma string como parâmetro e transforma em um inteiro).
4. Escreva uma função em C com o seguinte protótipo void itoa(long int numero, char str[])
A função recebe um número inteiro (positivo ou negativo) e coloca em str sua representação na forma de um string. Por exemplo, se o número for ‐12345, o string receberá "‐12345"; no string, não é necessário representar o sinal positivo. Observações: (1) para obter‐se o código ASCII de um caractere numérico qualquer, basta somar o número equivalente ao código ASCII do caractere ‘0’ (zero). Por exemplo, o código ASCII do caractere '5' é '0'+5; (2) o número não terá mais do que 5 dígitos; (3) pode‐se pegar dígito a dígito do número utilizando operações de divisão inteira e resto da divisão sucessivas por potências de 10. Exemplo:
72385 10000
-70000 7
2385 1000
-2000 2
385 100
-300 3
85 10
-80 8
5 1
-5 5
0
5. Simule a execução do programa abaixo mostrando todas as mudanças de valores de variáveis. #include<stdio.h> #include<conio.h> #include<string.h> void X(int n, char str[]){ int i; i = strlen(str); str[i]='\0'; do{ str[i] = n%2+'0'; n=n/2; i--; }while(i>0); } void main(){ int a=13; char strx[30]; X(a,strx); printf("%d = %s \n", a,strx);
71 Linguagem de Programação C
}
6. Escreva uma função em C com o seguinte protótipo
int palin(char str[])
A função recebe um string e retorna 1 se ele representar uma palavra palíndroma, isto é, igual de trás para frente (como "arara", "radar", "somos" etc.); se a palavra não é palíndroma, a função deve retornar 0.
7. Escreva uma função em C com o seguinte protótipo
int chrtimes(const char str1[], const char ch)
A função recebe um string e um caractere e retorna o número de ocorrências da letra correspondente ao caractere no string. Por exemplo, a chamada
chrtimes("paranapanema", 'a')
retorna 5 (observe que as letras maiúsculas e minúsculas tem códigos ASCII diferenciados).
8. Escreva uma função em C com o seguinte protótipo
int numchrtimes(const char str1[])
A função recebe um string e retorna o número de ocorrências de caracteres numéricos no string. Por exemplo, a chamada
numchrtimes("alfa1 bravo2 charlie 5")
retorna 3.
9. Escreva uma função em C com o seguinte protótipo:
int strtimes(const char str1[], const char str2[])
A função recebe dois strings, str1 e str2, e retorna o número de ocorrências de str2 em str1. Por exemplo, a chamada
strtimes("com o grêmio, onde o grêmio estiver", "grêmio")
retorna 2 (a função não distingue letras maiúsculas de minúsculas).
10. Escreva a função int strin(const char str1[],const char str2[])
A função verifica se str1 está contido em str2, a partir da posição 0. Em caso afirmativo, a função retorna 1, em caso negativo, 0. Por exemplo, a chamada
strin("ASTRO", "ASTRONAUTA");
retorna 1, mas as chamadas
strin("astro", "mastro");
strin("carro", "caravana");
retornam 0.
11. Escreva uma função em C com o seguinte protótipo:
void int2bin(int n, char str[])
72 Linguagem de Programação C
A função recebe um número inteiro sem sinal e coloca em um string a representação do número em binário. A obtenção da representação em binário de um número é feita através de divisões (inteira) sucessivas do número por 2. O resto de cada divisão fornece os dígitos binários. Exemplo:
10973 2
1 5486 2
0 2743 2
1 1371 2
1 685 2
1 342 2
0 171 2
1 85 2
1 42 2
0 21 2
1 10 2
0 5 2
1 2 2
0 1 2
Dígito mais significativo (+ à esq.) → 1 0
Assim, após a chamada
int2bin(10973, numbin)
numbin irá conter "10101011011101".
12. A função recebe um número inteiro sem sinal e coloca em uma string a representação do número em hexadecimal. A obtenção da representação em hexadecimal de um número é feita através de divisões (inteira) sucessivas do número por 16. O resto de cada divisão fornece os dígitos hexadecimais. Na base hexadecimal, o valor 10 é representado pela letra ‘a’, o valor 11 por ‘b’, o valor 12 por ‘C’, o valor 13 por ‘d’, o valor 14 por ‘e’ e o valor 15 por ‘f’.
10973 16
13 685 16
13 42 16
10 2 16
Dígito mais significativo (+ à esq.) → 2 0
Assim, após a chamada
int2hexa(10973, numhexa)
numhexa irá conter "2ADD".
73 Linguagem de Programação C
13. Escreva uma função em C com o seguinte protótipo:
void int2hexa(int n, char str[])
14. Sejam as duas funções abaixo:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define preco_max 1000000
void codifica(unsigned long int numero, unsigned long int div, char chave[], char str[]){
unsigned long int resto;
int i = 0;
do{
resto = numero%div;
numero = numero/div;
div = div/10;
str[i] = chave[numero];
numero = resto;
i++;
}while(div!=0);
str[i] = ‘\0’;
}
void cripto(float preco, char codigo[]){
char chave[] = "nevralgico";
unsigned long int parte_int;
int parte_frac;
parte_int = (unsigned long int) floor(preco);
parte_frac = (unsigned long int) (preco/parte_frac)*100;
codifica(parte_int, preco_max, chave, codigo);
codigo[strlen(codigo)]=’.’;
codifica(parte_int, 100, chave, codigo);
}
15. A função codifica recebe um número inteiro, o valor máximo que ele pode assumir, um string representando uma chave de codificação e uma variável string que receberá o numero codificado, através da substituição dos dígitos pelos caracteres correspondentes da chave. A função cripto recebe um número fracionário e coloca em um string as partes inteira e fracionária do número codificadas. Ela pode ser utilizada conforme o exemplo abaixo:
void main(){
char codigo[20];
float preco;
do{
printf("entre com preco:\n");
scanf("%f",&preco);
cripto(preco,codigo);
printf("codigo do preco: %s\n", codigo);
} while(1);
74 Linguagem de Programação C
}
A partir das definições acima, escreva uma função em C com o protótipo
float descripto(char codigo[])
A função recebe um string e retorna o valor correspondente ao string decodificado.
16. Considerando as funções codifica e cripto da questão anterior, mostre o valor impresso pela função main() abaixo:
void main(){
char codigo[20];
float preco = 23345.98;
cripto(preco,codigo);
printf("codigo do preco: %s\n", codigo);
}
17. Escreva uma função em C com o seguinte protótipo
int strlen(char str[])
A função recebe um string e retorna seu tamanho, sem incluir o caractere nulo ('\0').
18. Escreva uma função em C com o seguinte protótipo
void strcpy(char str1[], char str2[])
A função recebe dois strings (str2[] e str1[]) e copia o conteúdo de str2[] para str1[].
19. Mostre o resultado da execução do programa (função main()) abaixo.
int kyz(const char str1[], const char str2[]){
int cont=0, j, i, achou =1;
for (i=0; str1[i]!='\0';i++){
do{
if (str1[i]!=str2[j]){
achou= 0;
j = 0;
break;
}
j++;
i++;
} while(str2[j]!='\0');
if (achou) cont++;
j = 0;
achou = 1;
}
return cont;
}
void main(){
char maior[]="ABXYZCXYZKLMNPQXYZ";
char menor[]="XYZ";
75 Linguagem de Programação C
printf( "%d\n", kyz(maior,menor)) ;
}
20. Escreva uma função em C que receba dois strings e retorne 1 se os strings são iguais; 0 se eles são diferentes.
21. Escreva um programa em C que leia valores para dois vetores de strings, conforme a definição abaixo:
char maridos[10][30], esposas[10][30];
Os valores lidos correspondem a nomes de pessoas. O primeiro vetor conterá apenas nomes de homens; o segundo conterá apenas nomes de mulheres. Por exemplo,
0 1 2 3 4 5 6 7 8 9
“joão” “elias” “adão” “vítor” “hugo” “carlos” “heitor” “olívio” “enio” “luís”
0 1 2 3 4 5 6 7 8 9
“marta” “irma” “carla” “sandra” “gilda” “paula” “ana” “isete” “iara” “sandra”
A seguir, o programa lê uma matriz 10×10 contendo apenas 0’s e 1’s, conforme o exemplo abaixo: 0 1 2 3 4 5 6 7 8 9 0 0 0 1 0 0 0 0 0 0 01 0 0 0 0 0 1 0 0 0 02 0 0 0 1 0 0 0 0 0 03 0 0 0 0 0 0 1 0 0 04 0 0 0 0 1 0 0 0 0 05 0 0 0 0 0 0 0 1 0 06 0 0 0 0 0 0 0 0 1 07 0 1 0 0 0 0 0 0 0 08 1 0 0 0 0 0 0 0 0 09 0 0 0 0 0 0 0 0 0 1
Uma posição i,j da matriz acima contendo o valor 1 indica que o elemento i do vetor maridos é casado com o elemento j do vetor esposas. O programa deve escrever tais relações na forma “<i> é casado com <j>”. Para o exemplo acima, a saída seria:
João é casado com carla
Elias é casado com paula
Adão é casado com sandra
...
76 Linguagem de Programação C
13 E/S COM ARQUIVO
São grupos de dados armazenados em meio não volátil (disco, fita, entre outros). São utilizados para armazenar dados de forma permanente.
A linguagem C não contém nenhum comando de E/S. Ao contrário, todas as operações de E/S ocorrem através de chamadas a funções da biblioteca C padrão. Essa abordagem faz o sistema de arquivos de C extremamente poderoso e flexível. O sistema de E/S de C é único, porque dados podem ser transferidos na sua representação binária interna ou em um formato de texto.
13.1 STREAMS
A linguagem C oferece uma abstração da interface para controle de E/S, independente do dispositivo real (terminais, acionadores de disco, acionadores de fita, entre outros) que é acessado. Sendo que o dispositivo real é chamado de arquivo.
Existem dois tipos de streams: texto e binária. A primeira é uma seqüência de caracteres organizados em linhas e terminadas por um caractere de nova linha (depende da implementação). A segunda é uma seqüência de bytes com uma correspondência de um para um com aqueles encontrados no dispositivo externo ‐ isto é, não ocorre nenhuma tradução de caracteres.
13.2 ARQUIVOS
Um arquivo pode ser qualquer coisa, desde um arquivo em disco até um terminal ou uma impressora. Associa‐se uma stream com um arquivo específico realizando uma operação de abertura. Todos as streams são iguais, mas não todos os arquivos. Isto é, um arquivo disco pode suportar acesso aleatório enquanto um teclado não pode.
Cada stream associada a um arquivo tem uma estrutura de controle de arquivo do tipo FILE. Essa estrutura é definida no cabeçalho STDIO.H.
Todos os arquivos são fechados automaticamente quando o programa termina, normalmente com main() retornando ao sistema operacional ou uma chamada à exit(). Os arquivos não são fechados quando um programa quebra (crash).
13.3 SISTEMA DE ARQUIVOS
O sistema de arquivos ANSI é composto de diversas funções inter‐relacionadas. As mais comuns são mostradas na Tabela 13.1. Essas funções exigem que o cabeçalho STDIO.H seja incluído em qualquer programa em que são utilizadas.
Tabela 13.1 ‐ Funções mais comuns do sistema de arquivo com buffer
Nome Função
fopen() Abre um arquivo
fclose() Fecha um arquivo
putc() Escreve um caractere em um arquivo
fputc() O mesmo que putc()
77 Linguagem de Programação C
getc() Lê um caractere de um arquivo
fgetc() O mesmo que getc()
fseek() Posiciona o arquivo em um byte específico
fprintf() É para um arquivo o que printf() é para o console
fscanf() É para um arquivo o que scanf() é para o console
feof() Devolve verdadeiro se o fim de arquivo for atingido
ferror() Devolve verdadeiro se ocorreu um erro
rewind() Repõe o indicador de posição de arquivo no início do arquivo
remove() Apaga um arquivo
fflush() Descarrega um arquivo
O arquivo cabeçalho STDIO.H fornece os protótipos para as funções de E/S e define estes três tipos: size_t, fpos_t e FILE. O tipo size_t é essencialmente o mesmo que um unsigned, assim como o fpos_t. O tipo FILE é discutido na próxima seção.
A biblioteca STDIO.H define várias macros como: EOF, SEEK_SET, SEEK_CUR e SEEK_END. A macro EOF é geralmente definida como ‐1 e é o valor quando uma função de entrada tenta ler além do final do arquivo. As outras macros são usadas com fseek(), que é uma função que executa acesso aleatório em um arquivo.
13.4 ESTRUTURA FILE
Para a manipulação de arquivos é utilizado a declaração de ponteiro (ponteiro de arquivo). Isto é, um ponteiro para informações que definem vários dados sobre o arquivo, como o seu nome, status, e a posição atual do arquivo. Um ponteiro de arquivo é uma variável ponteiro do tipo FILE . Todas as funções são realizadas utilizando o ponteiro. Para a declaração de um ponteiro de arquivo utiliza‐se a seguinte sintaxe:
Sintaxe: FILE *<var>
Exemplo 13.1 FILE *fp;
13.5 ABERTURA DE ARQUIVOS
A função fopen() abre uma stream para uso e associa um arquivo a ela. Retorna o ponteiro de arquivo associado a esse arquivo.
Sintaxe: FILE *fopen(const char * <nome_arquivo>, const char * <modo_abertura>);
O modo de abertura define a forma como é feito o acesso aos dados (somente leitura, leitura e escrita, etc). As forma principais são apresentadas na Tabela 13.2.
Tabela 13.2 ‐ Os modos de abertura válidos
Modo Significado
r Abre um arquivo texto para leitura
78 Linguagem de Programação C
w Cria um arquivo texto para escrita
a Anexa a um arquivo texto
rb Abre um arquivo binário para leitura
wb Cria um arquivo binário para escrita
ab Anexa a um arquivo binário
r+ Abre um arquivo texto para leitura/escrita
w+ Cria um arquivo texto para leitura/escrita
a+ Anexa ou cria um arquivo texto para leitura/escrita
r+b ou rb+ Abre um arquivo binário para leitura/escrita
w+b ou wb+ Cria um arquivo binário para leitura/escrita
a+b ou ab+ Anexa a um arquivo binário para leitura/escrita
Exemplo 13.2 FILE *arq; /* ponteiro de arquivo */ arq = fopen(“dados.dat”,”wb”);
Se ao abrir um arquivo para leitura o mesmo não existir a função fopen retorna um ponteiro nulo (NULL).
arq = fopen(“dados.dat”,”rb”); if (arq == NULL) arq=fopen(“dados.dat”,”wb”);
13.6 FECHAMENTO DE ARQUIVO
A função fclose() fecha uma stream que foi aberta através de uma chamada à fopen(). Esta função tem a seguinte sintaxe:
Sintaxe: int fclose(FILE *fp);
onde fp é o ponteiro de arquivo devolvido pela chamada à fopen(). O valor de retorno 0 significa uma operação de fechamento bem‐sucedida.
13.7 VERIFICANDO FIM DE ARQUIVO
A função feof()devolve verdadeiro quando for encontrado o fim de arquivo. O protótipo desta função está declarado abaixo:
Sintaxe: int feof(FILE *fp);
Esta função pode ser aplicada tanto para arquivo texto como para arquivos binários.
13.8 COMANDO DE GRAVAÇÃO EM MODO TEXTO FORMATADO
Como extensão das funções básicas de E/S já discutidas, o sistema de E/S com buffer inclui fprintf() e fscanf(). Essas funções se comportam exatamente como printf() e scanf() exceto por operarem em arquivos. Os protótipos de fprintf() e fscanf() são
79 Linguagem de Programação C
Sintaxe: int fprintf(FILE *fp, const char *control_string, ...); int fscanf(FILE *fp, const char *control_string, ...);
onde fp é um ponteiro de arquivo devolvido por uma chamada à fopen(). fprintf() e fscanf() direcionam suas operações de E/S para o arquivo apontado por fp.
A fscanf() devolve o número de elementos lidos, convertidos e armazenados. No caso de fim de arquivo o fscanf() devolve o valor EOF.
O Exemplo 13.3 mostra um programa que lê uma string e um inteiro do teclado, escreve‐os em um arquivo em disco e em seguida lê e mostra a informação na tela.
Exemplo 13.3 #include <stdio.h> #include <stdlib.h> #include <io.h> int main() { FILE *fp; char s[80]; int t; if((fp=fopen(“teste”,”w”))==NULL) { printf(“Arquivo nao pode ser aberto\n”); exit(1); } printf(“entre com uma string e um número: “ ); fscanf(stdin, “%s%d”, s, &t); /* le do teclado */ fprintf(fp, “%s %d”, s, t); /* escreve no arquivo */ fclose(fp); if((fp=fopen(“teste”,”w”))==NULL) { printf(“Arquivo nao pode ser aberto\n”); exit(1); } fscanf(fp, “%s%d”, s, &t); /* le do arquivo */ fprintf(stdout, “%s %d”, s, t); /* imprime na tela */ return 0; }
A formatação realizada para leitura e escrita de dados pode comprometer a velocidade de processamento do programa.
13.9 STREAMS PADRÃO
Sempre que um programa é iniciado, três streams padrões são abertas automaticamente:
• stdin (entrada padrão ‐ teclado);
• stdout (saída padrão ‐ tela);
• stderr (saída de erro padrão ‐ tela);
• stdaux (saída auxiliar padrão ‐ porta serial);
• stdprn (impressora padrão ‐ impressora paralela).
Essas streams podem ser utilizadas normalmente para executar operações de E/S bufferizada.
13.10 EXERCÍCIOS
1. Faça um programa que escreva os números de 0 a 10 em um arquivo.
80 Linguagem de Programação C
2. Faça um programa que leia 11 números de um arquivo.
3. Escrever um programa em C que leia um número indeterminado de códigos (inteiro) e taxas de consumo (real), em Kw, dos consumidores de uma cidade e grave os dados em um arquivo chamado medidas.txt. O programa pára de ler quando o código fornecido for zero.
4. Escrever um programa em C que leia o arquivo gerado no exercício 1 e mostre quantas taxas existem e o maior consumo.
5. Escrever um programa em C que leia um arquivo texto (temp.txt) e grave em outro arquivo (tempMax.txt). O arquivo origem possuiu um número indeterminado de linhas, onde cada linha possui 5 colunas: dia, mês, ano, temperatura mínima (real), temperatura máxima (real). O programa deve escrever no arquivo tempMax.txt o dia, mês, ano, e a temperatura máxima somente quando ela for maior que a temperatura máxima do dia anterior. Por exemplo, assuma que o arquivo temp.txt possua o seguinte conteúdo:
10 10 2007 16.5 32.2 11 10 2007 15.4 31.0 12 10 2007 17.5 32.7 13 10 2007 18.6 32.4 14 10 2007 17.5 30.3 15 10 2007 18.3 31.2 16 10 2007 16.8 30.2 17 10 2007 17.6 31.3
O programa deve gerar o arquivo tempMax.txt com o seguinte conteúdo:
12 10 2007 32.7
15 10 2007 31.2
17 10 2007 31.3
81 Linguagem de Programação C
A. TABELA ASCII
Cód Car Cód Car Cód Car Cód Car Cód Car Cód Car Cód Car Cód Car
0 32 64 @ 96 ‘ 128 Ç 160 á 192 └ 224 Ó
1 ☺ 33 ! 65 A 97 a 129 ű 161 í 193 ┴ 225 ß
2 ☻ 34 ” 66 B 98 b 130 é 162 ó 194 ┬ 226 Ô
3 ♥ 35 # 67 C 99 c 131 â 163 ú 195 ├ 227 Ò
4 ♦ 36 $ 68 D 100 d 132 ä 164 ñ 196 ─ 228 õ
5 ♣ 37 % 69 E 101 e 133 à 165 Ñ 197 ┼ 229 Õ
6 ♠ 38 & 70 F 102 f 134 å 166 ª 198 ã 230 µ
7 • 39 ’ 71 G 103 g 135 ç 167 º 199 Ã 231 þ
8 40 ( 72 H 104 h 136 ê 168 ¿ 200 ╚ 232 Þ
9 41 ) 73 I 105 i 137 ë 169 ® 201 ╔ 233 Ú
10 42 * 74 J 106 j 138 è 170 ¬ 202 ╩ 234 Û
11 ♂ 43 + 75 K 107 k 139 ï 171 ½ 203 ╦ 235 Ù
12 ♀ 44 , 76 L 108 l 140 î 172 ¼ 204 ╠ 236 ý
13 45 - 77 M 109 m 141 ì 173 ¡ 205 ═ 237 Ý
14 ♫ 46 . 78 N 110 n 142 Ä 174 « 206 ╬ 238 ¯
15 ☼ 47 / 79 O 111 o 143 Å 175 » 207 ¤ 239 ´
16 4 48 0 80 P 112 p 144 É 176 ░ 208 ð 240
17 3 49 1 81 Q 113 q 145 æ 177 ▒ 209 Ð 241 ±
18 ↕ 50 2 82 R 114 r 146 Æ 178 ▓ 210 Ê 242 _
19 !! 51 3 83 S 115 s 147 ô 179 │ 211 Ë 243 ¾
20 ¶ 52 4 84 T 116 t 148 ö 180 ┤ 212 È 244 ¶
21 § 53 5 85 U 117 u 149 ò 181 Á 213 245 §
22 ▬ 54 6 86 V 118 v 150 û 182 Â 214 Í 246 ÷
23 ↕ 55 7 87 W 119 w 151 ù 183 À 215 Î 247 ¸
24 ↑ 56 8 88 X 120 x 152 ÿ 184 © 216 Ï 248 °
25 ↓ 57 9 89 Y 121 y 153 ö 185 ╣ 217 ┘ 249 ¨
26 → 58 : 90 Z 122 z 154 Ü 186 ║ 218 ┌ 250 ·
27 ← 59 ; 91 [ 123 { 155 ø 187 ╗ 219 █ 251 ¹
28 ¬ 60 < 92 \ 124 | 156 £ 188 ╝ 220 ▄ 252 ³
29 ↔ 61 = 93 ] 125 } 157 Ø 189 ¢ 221 ¦ 253 ²
30 t 62 > 94 ^ 126 ~ 158 × 190 ¥ 222 Ì 254
31 u 63 ? 95 _ 127 Δ 159 ƒ 191 ┐ 223 ▀ 255
82 Linguagem de Programação C
14 BIBLIOGRAFIA
KERNIGHAN, Brian W.; RITCHIE, Dennis M.. C: A Linguagem de Programação. 11ª Edição. Porto Alegre: EDISA, 1998. 208 p.
MIZRAHI, V. V. Treinamento em Linguagem C. São Paulo: Pearson Prentice Hall, 2008.
SCHILDT, H. C Completo e total. 3a Edição. São Paulo: McGraw‐Hill, 1996.