programação c (apoio)

41
#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

Upload: mari-chagas

Post on 25-Jul-2015

98 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 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 

Page 2: Programação C (Apoio)

 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 

 

Page 3: Programação C (Apoio)

 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; 

Page 4: Programação C (Apoio)

 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.

 

Page 5: Programação C (Apoio)

 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;

Page 6: Programação C (Apoio)

 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; )

Page 7: Programação C (Apoio)

 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;

Page 8: Programação C (Apoio)

 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

Page 9: Programação C (Apoio)

 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. 

Page 10: Programação C (Apoio)

 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

Page 11: Programação C (Apoio)

 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;

Page 12: Programação C (Apoio)

 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

Page 13: Programação C (Apoio)

 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 

Page 14: Programação C (Apoio)

 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. 

 

Page 15: Programação C (Apoio)

 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

Page 16: Programação C (Apoio)

 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 −=ΔΔ±−

=

Page 17: Programação C (Apoio)

 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”

Page 18: Programação C (Apoio)

 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: 

Page 19: Programação C (Apoio)

 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;

}

Page 20: Programação C (Apoio)

 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; }

Page 21: Programação C (Apoio)

 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 

Page 22: Programação C (Apoio)

 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  

Page 23: Programação C (Apoio)

 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. 

Page 24: Programação C (Apoio)

 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");

Page 25: Programação C (Apoio)

 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. 

Page 26: Programação C (Apoio)

 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;

Page 27: Programação C (Apoio)

 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(){

Page 28: Programação C (Apoio)

 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. 

 

Page 29: Programação C (Apoio)

 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”, &notas[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.  

Page 30: Programação C (Apoio)

 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'

Page 31: Programação C (Apoio)

 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: 

Page 32: Programação C (Apoio)

 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

 

Page 33: Programação C (Apoio)

 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.

 

Page 34: Programação C (Apoio)

 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 

Page 35: Programação C (Apoio)

 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);

Page 36: Programação C (Apoio)

 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". 

Page 37: Programação C (Apoio)

 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";

Page 38: Programação C (Apoio)

 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() 

Page 39: Programação C (Apoio)

 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 

Page 40: Programação C (Apoio)

 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

Page 41: Programação C (Apoio)

 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.