You are on page 1of 46

Universidade de Passo Fundo Instituto de Cincias Exatas e Geocincias Curso de Cincia da Computao

Programao I

CCC011 Programao I Prof. Marcos Jos Brusso Semestre: 2002/1

Linguagem C

Prof. Marcos Jos Brusso

ndice
HISTRICO...........................................................................................................................................3 PROGRAMANDO EM C......................................................................................................................3 DIRETIVA #INCLUDE.........................................................................................................................4 VARIVEIS...........................................................................................................................................4 TIPOS DE DADOS................................................................................................................................4 MODIFICADORES DE TIPO...............................................................................................................5 LITERAIS...............................................................................................................................................6 CARACTERES DE ESCAPE................................................................................................................6 VETORES E MATRIZES.....................................................................................................................7 ESCREVENDO VALORES..................................................................................................................7 LENDO VALORES...............................................................................................................................8 OPERADORES ARITMTICOS..........................................................................................................9 OPERADORES COMBINADOS..........................................................................................................10 OPERADORES RELACIONAIS...........................................................................................................11 OPERADORES LGICOS....................................................................................................................11 OPERADOR TERNRIO.....................................................................................................................11 OPERADOR SIZEOF............................................................................................................................12 MOLDAGEM OU CAST.......................................................................................................................12 COMANDO IF.......................................................................................................................................13 COMANDO DO WHILE.......................................................................................................................13 COMANDO WHILE..............................................................................................................................14 COMANDO FOR...................................................................................................................................15 COMANDO SWITCH...........................................................................................................................15 DIRETIVA #DEFINE............................................................................................................................16 DECLARAO DE FUNES...........................................................................................................17 PONTEIROS..........................................................................................................................................18 OPERAES COM PONTEIROS........................................................................................................19 PASSAGEM DE PARMETROS POR VALOR.................................................................................20 PASSAGEM DE PARMETROS POR REFERNCIA......................................................................20 FUNES E VETORES........................................................................................................................21 ALOCAO DINMICA DE MEMRIA..........................................................................................21 FUNES DE MANIPULAO DE STRINGS.................................................................................22 FUNES DE TRATAMENTO DE CARACTERES..........................................................................23 ESTRUTURAS......................................................................................................................................24 PONTEIROS PARA ESTRUTURAS....................................................................................................26 ARGUMENTOS DE LINHA DE COMANDO.....................................................................................26 FUNES DE ENTRADA E SADA EM ARQUIVOS SEQUENCIAIS...........................................27 FUNES DE ENTRADA E SADA ALEATRIA EM ARQUIVOS...............................................29 EXERCCIOS.........................................................................................................................................33

Linguagem C

Prof. Marcos Jos Brusso

Histrico
A linguagem C foi criada por Dennis M. Ritchie. Seu desenvolvimento foi influenciado pela linguagem B implementada por Ken Tompson, que por sua vez foi influenciada pela linguagem BCPL criada por Martin Richards. O sistema operacional UNIX, boa parte do Windows e muitos de seus aplicativos, assim como muitos dos softwares bsicos e aplicativos existentes no mercado foram escritos em C. C uma linguagem estruturada, de relativo baixo nvel e que garante portabilidade do cdigo fonte e um programa objeto muito eficiente, rpido e compacto.

Programando em C
Todo programa em C composto de uma ou mais funes, que so blocos de cdigo independentes. Uma funo denominada main deve ser definida em cada programa, pois o seu ponto de entrada. Isto no quer dizer que ela deva ser a primeira no arquivo fonte, uma vez que a ordem em que as funes foram escritas no interfere na execuo do programa. Uma funo pode efetuar operaes e pode chamar outras funes, sendo que estas podem fazer parte do prprio programa ou ser alguma das diversas funes pr-definidas na biblioteca padro do C. Assim que a execuo de uma funo concluda, ao atingir o } ou o comando return, o programa retorna para o prximo comando aps a chamada a esta funo. Ao concluir a funo main o prprio programa finalizado, sendo que, pelo padro ANSI, esta funo deve retornar 0, se o programa foi finalizado com sucesso, ou um valor maior que zero, se foi finalizado por uma situao de erro. /* prog01.c Meu primeiro programa em C */ #include <stdio.h> void outrafunc(void); /* Funo main */ int main(void) { printf("Estou na funcao main\n"); getchar(); outrafunc(); printf("Voltei para a funcao main\n"); getchar(); return(0); } /* Funo outrafunc */ void outrafunc(void) { printf("Agora estou em outra funcao\n"); getchar(); }

O compilador C diferencia letras maisculas de minsculas, portanto TESTE diferente de teste, que por sua vez diferente de Teste. Todas as palavras reservadas da linguagem devem ser digitadas em letra minscula. Qualquer comentrio pode ser colocado entre os smbolos /* e */. Um comentrio pode aparecer em qualquer lugar

Linguagem C

Prof. Marcos Jos Brusso

no programa onde possa aparecer um espao em branco e pode se estender por mais de uma linha.

Diretiva #include
Inclui (copia) o contedo do arquivo especificado para dentro programa atual. #include <nome do arquivo> Usado para arquivos prprios da linguagem com extenso .h (header) que contm declarao das funes da biblioteca padro, definio de tipos compostos e de macros. O arquivo procurado no diretrio padro de includes do compilador. Deve-se incluir o arquivo apropriado sempre que for utilizada alguma funo prpria da linguagem. Alguns dos principais .h do C: Arquivo stdio.h string.h math.h ctype.h stdlib.h #include "nome do arquivo" Usado para incluir arquivos criados pelo prprio programador. Geralmente arquivos .c com declarao de funes. O arquivo procurado no diretrio atual. Descrio Funes de entrada e sada (I/O) Funes de tratamento de strings Funes matemticas Funes de teste e tratamento de caracteres Funes de uso genrico

Variveis
Toda a varivel deve ser definida antes de ser usada como sendo de um tipo. O tipo vai definir o tamanho em bytes da varivel e o intervalo de valores que ela poder armazenar. O nome da varivel poder ter at 32 caracteres, sendo que o primeiro dever ser letra ou _ e os demais caracteres podem ser letras, nmeros ou _. Todas as variveis devem ser declaradas antes de qualquer comando executvel na funo. Um programa pode ter variveis globais, que so definidas fora de qualquer funo e podem ser referenciadas em qualquer uma delas, ou variveis locais que so declaradas internamente a uma funo, sendo visiveis apenas na funo em que foram declaradas. Funes distintas podem ter variveis locais com o mesmo nome. Se uma funo declarar uma varivel com o mesmo nome de uma varivel global, a prioridade da varivel local.

Tipos de Dados
Existem 4 tipos bsicos que podem ser utilizados para a declarao de variveis: Tipo char int float double Descrio Um nico caracter ou nmero inteiro pequeno Nmeros inteiros (sem casas decimais) Nmeros em ponto flutuante (com casas decimais) com preciso simples Nmeros em ponto flutuante (com casas decimais) com preciso dupla

Linguagem C

Prof. Marcos Jos Brusso

Modificadores de Tipo
Os modificadores de tipo servem para definir as caractersticas da varivel sendo declarada quanto ao seu tamanho em bytes e forma de representao dos valores (inteiros sem sinal ou com sinal em complemento de 2). Quanto ao sinal (podem ser usados com char ou int): Modificador Descrio signed A varivel pode receber valores negativos ou positivos. Padro unsigned A varivel somente pode receber valores positivos.

Quanto ao tamanho (podem ser usados com int.): Modificador short long Descrio Formato curto (2 bytes). Formato longo (4 bytes). Padro

Tipo unsigned char signed char unsigned short int signed short int unsigned long int signed long int float double long double void

Bytes 1 1 2 2 4 4 4 8 10 -

Intervalo 0 a 255 -128 a 127 0 a 65535 -32768 a 32767 0 a 4294967295 -2147483648 a +2147483647 3.4E-38 a 3.4E+38 1.7E-308 a 1.7E+308 3.4E-4932 a 1.1E+4932 Nenhum valor

Casas Decimais 0 0 0 0 0 0 7 15 17 -

O tipo padro (default) em C int, por isso sempre que a declarao tiver apenas modificadores assumido o tipo int. Por exemplo, long equivalente a signed long int. A inicializao de uma varivel pode ser feita com uma constante, expresso ou funo. int var1=10, var2=var1*5, var3=abs(var2); Na falta de inicializao explcita, variveis globais so inicializadas automaticamente com zero. Variveis locais tem valor indefinido (lixo) quando no inicializadas na declarao.

Linguagem C

Prof. Marcos Jos Brusso

Literais
Os literais so usados para especificar valores constantes dentro de programas. A linguagem C possibilita uma grande variedade na codificao destes valores, seja quanto a base numrica utilizada ou quanto ao tamanho e formato utilizado para seu armazenamento. Formato Decimal Octal Hexadecimal Ponto Flutuante Notao Cientfica Caracter String Prefixo 0 Prefixo 0x mantissaEexpoente (Sempre base 10) Um caractere entre ' ' ou seu cdigo ASCII Sequncia de caracteres entre " " Codificao Nmeros sem 0 inicial 10 010 0xFF 1.02E23 'A' , 65 "Computao" Exemplo

Dgitos decimais separados por ponto: nnn.dd 3.14159265

Caracteres de Escape
Os caracteres de escape so usados para representar alguns caracteres que, ou no esto disponveis diretamente no teclado do computador ou em determinadas situao no podem ser inseridos diretamente dentro de um programa fonte C. Outra vantagem do uso desta forma codificada que a portabilidade do programa garantida. Estes caracteres podem aparecer tanto dentro de literais do tipo caracter como string. Caracter Descrio \a Campainha ou Bell \b Retrocesso ou Backspace \n \r \t \' \" \\ \0 Alimentao de linha Retorno do carro Tabulao horizontal (TAB) Aspa simples Aspa dupla Contrabarra Caracter nulo (ASCII 0)

Linguagem C

Prof. Marcos Jos Brusso

Vetores e Matrizes
Todos os vetores em C comeam com o ndice 0 e no verificado limite para um vetor. Vetores em C so freqentemente chamados de arranjo. int ivetor[10]; /* declara um vetor de 10 elementos do tipo int */ float fmatriz[2][5]; /* matriz de 2 linhas com 5 colunas tipo float */

Strings em C so simplesmente vetores de caracteres. Toda string deve ser finalizada pelo caracter '\0'. String entre aspas duplas ("") o C coloca automaticamente \0 no final. Vetores podem ser inicializados na declarao. Neste caso a declarao do tamanho opcional, pois o compilador pode calcular. Para a inicializao de vetores, se coloca os valores entre {}. Para strings usa-se um literal entre "". int vetor[5] = {2,4,6,8,10}; int matriz[3][3] = {{2,15,0},{33,4,900},{-1,12,50}}; char nome[]= {'C','O','M','P','U','T','A','C','A','O','\0'}; char texto[10]="exemplo";

Escrevendo Valores
A funo printf()
A funo printf uma funo da biblioteca padro C que escreve valores. Ela pode receber diversos parmetros, sendo que o primeiro dever ser uma string. Cada especificador de formato encontrado nesta string substitudo pelo parmetro seguinte na lista de argumentos. Tudo o que aparecer nesta string que no for um especificador de formato ser impresso literalmente. A funo printf est definida em stdio.h.

Especificadores de Formato
Formato Descrio %d Nmero inteiro decimal %o Nmero inteiro octal %x %u %c %s %f %% Nmero inteiro hexadecimal Nmero inteiro decimal sem sinal Um nico caracter String Nmero em ponto flutuante Exibe um %

Pode-se especificar o tamanho do campo a ser impresso, colocando um nmero entre o % e o caracter de formato. Por exemplo %5d indica que o valor a ser impresso vai ocupa 5 posies na tela. As posies em excesso so preenchidas com brancos. Por padro o valor alinhado a direita do campo. Se o tamanho do campo for precedido por - (menos), ento alinhado esquerda. Se for colocado um 0 em frente ao tamanho o campo preenchido com zeros. Sempre que o tamanho do campo for insuficiente para exibir o valor solicitado, o tamanho ignorado. Assim um valor nunca truncado. Pode-se usar dois nmeros separados por ponto. Para valores numricos a primeira parte indica o tamanho do campo, e a segunda parte o nmero de casas decimais. O tamanho do campo inclui as casas decimais e o ponto. Para strings a primeira parte indica o tamanho do campo e a segunda o nmero mximo de caracteres da string a imprimir.

Linguagem C

Prof. Marcos Jos Brusso

/* prog02.c */ #include <stdio.h> int main(void) { char val_c = 'A'; int val_i = 100; double val_d = 50.5; char frase[]="COMPUTACAO"; printf("[%c] [%c] [%d]\n",val_c, val_c+1 ,val_c); printf("[%d] [%5d] [%-5d] [%05d]\n",val_i, val_i, val_i, val_i); printf("[%5.2f]\n",val_d); printf("[%15s]\n", frase); printf("[%-15s]\n", frase); printf("[%3.4s]\n", frase); printf("[%15.3s]\n", frase); printf("[%-15.3s]\n", frase); getchar(); return(0); }

Lendo Valores
Para a entrada de dados (leitura de valores) em C, dependendo do tipo da varivel que vai ser lida, deve-se usar a funo apropriada. Estas funes esto definidas em stdio.h Funo getchar() L um caracter e retorna o caracter digitado. Deve-se teclar Enter aps o caracter lido. letra = getchar(); Pode ser utilizada sem aproveitar o valor de retorno, simplesmente para dar uma pausa no programa at ser teclado Enter. getchar(); Funo scanf() Deve ser utilizada para a entrada de variveis numricas (int, float e double). O mode de utilizar semelhante funo printf, porm colocar obrigatoriamente o smbolo & em frente ao nome da varivel sendo lida. Est definida em stdio.h Formato %d int %u unsigned int %f %lf %c %s scanf("%d", &varint); float double Um caracter Uma string (espao em branco finaliza) Tipo

Linguagem C

Prof. Marcos Jos Brusso

Funo gets()
Usada para a entrada de string. gets(nome);

Devido a forma como a funo scanf trata o buffer de entrada, quando ela for utilizada em conjunto com as demais funes de leitura deve-se limpar este buffer com fflush(stdin);
/* prog03.c */ #include <stdio.h> int main(void) { int vari; float varf; char nome[80]; printf("Digite seu nome: "); gets(nome); printf("Digite um numero inteiro: "); scanf("%d", &vari); printf("Digite um numero em ponto flutuante: "); scanf("%f", &varf); printf("\n%s, voce digitou %d e %f ", nome, vari, varf); fflush(stdin); getchar(); return(0); }

Operadores Aritmticos
Realizam as operaes aritmticas normais sobre os seus operandos. Podem ser utilizados com qualquer tipo de dados, exceto o resto da diviso, o qual no pode ter operandos em ponto flutuante. Operador = + * / % ++ -Funo Atribuio Soma Subtrao Multiplicao Diviso (se os dois valores forem int, o resultado no ter casas decimais) Resto da diviso inteira Incremento pr ou ps-fixado Decremento pr ou ps-fixado

Linguagem C

10

Prof. Marcos Jos Brusso

/* prog04.c */ #include <stdio.h> int main(void) { int a=5, b=2; float resultado=0.0; resultado = a/b; printf("%d/%d = %.2f\n", a, b, resultado); getchar(); return(0); }

No exemplo anterior, o resultado 2.0, e no 2.5 como seria esperado. Isto porque na diviso entre operandos inteiros o resultado resulta em um valor inteiro. Dentro de uma operao complexa, cada operao tratada em separado, podendo afetar o resultado final. /* prog05.c */ #include <stdio.h> int main(void) { int n1,n2,n3; n1=n2=n3=1; n2= ++n1; n3= n2++; printf("%d\n%d\n%d", n1, n2, --n3); getchar(); return(0); }

Operadores Combinados
Sempre que em um programa C aparece uma expresso como a seguinte: operando1 = operando1 op operando2; onde o resultado da operao est sendo atribuda para o seu primeiro operando, esta expresso pode ser simplificada para a seguinte forma: operando1 op= operando2; Expresso Normal a = a + b; a = a - b; a = a * b; a = a / b; Expresso Simplificada a+=b; a-=b; a*=b; a/=b;

Linguagem C

11

Prof. Marcos Jos Brusso

Operadores Relacionais
Os operadores relacionais so utilizados em expresses condicionais para comparar o valor de duas expresses. Operador > >= < >= == != Funo Maior que Maior ou igual Menor que Menor ou igual Igual Diferente de

Operadores Lgicos
Os operadores lgicos so utilizados para conectar expresses lgicas sendo geralmente utilizados em expresses condicionais. Operador Funo && AND lgico || OR lgico ! NOT lgico

Operador Ternrio
Sintaxe: (exp1)?exp2:exp3 A expresso exp1 avaliada, se for verdadeira o conjunto assume o valor da expresso exp2 seno assume o valor da expresso exp3. /* prog06.c */ #include <stdio.h> int main(void) { int n1, n2, maior; printf("Digite dois valores:\n"); scanf("%d %d", &n1, &n2); maior = (n1>n2)?n1:n2; printf("O maior e' %d\n", maior); fflush(stdin); getchar(); return(0); }

Linguagem C

12

Prof. Marcos Jos Brusso

Operador sizeof
Sintaxe: sizeof(expresso) ou sizeof(tipo) Este operador retorna o tamanho em bytes ocupados pela expresso ou tipo. O tamanho de uma varivel no depende do seu contedo, mas apenas do tipo que ela foi declarada. O tamanho de um vetor igual a soma do tamanho de seus elementos.

int s = n = s =

n, s, vet[3]; sizeof(n); sizeof(float); sizeof(vet);

Moldagem ou Cast
Sintaxe: (tipo) expresso Fora a expresso a assumir um determinado tipo. No altera o tipo da varivel, apenas converte o valor naquele ponto do programa. /* prog07.c */ #include <stdio.h> int main(void) { int a=5, b=2; float resultado=0.0; resultado = (float)a/b; printf("%d/%d = %.2f\n", a, b, resultado); getchar(); return(0); }

Linguagem C

13

Prof. Marcos Jos Brusso

Comando if
Sintaxe: if(condio) comando1; else comando2; Se condio for verdadeira (diferente de 0) executado comando1, seno executado comando2. Quando mais de um comando for utilizado, devem estar agrupados entre { e }.O else, que opcional, eqivale sempre ao ltimo if pendente (sem else). /* prog08.c */ #include <stdio.h> int main(void) { int num; printf("Digite um numero: "); scanf("%d", &num); if(num%2==0){ printf("%d e' par\n", num); printf("A metade e' %d\n", num/2); } else printf("%d e' impar\n", num); fflush(stdin); getchar(); return(0); }

Comando do while
Sintaxe: do comando; while(condio); Executa o comando enquanto a condio for verdadeira. Como a condio avaliada no final de cada passagem, o comando executado pelo menos uma vez. /* prog09.c */ #include <stdio.h> int main(void) { int soma = 0, i=10, final=15; do{ printf("%d\n", i); soma += i; i++; }while(i<=final); printf("Soma dos numeros entre [10 e 15] = %d\n", soma); getchar(); return(0); }

Linguagem C

14

Prof. Marcos Jos Brusso

Comando while
Sintaxe: while(condio) comando; Executa o comando enquanto a condio for verdadeira. Como a condio avaliada no incio de cada passagem, o comando no ser executado nenhuma vez se, ao entrar neste lao, a condio for falsa. /* prog10.c */ #include <stdio.h> int main(void) { int n1=5, n2=3, produto=0; /* Multiplica dois inteiros positivos por somas sucessivas */ while(n2>0){ produto+=n1; n2--; } printf("5 x 3 = %d\n", produto); getchar(); return(0); }

Pode-se utilizar os seguintes comandos dentro de um lao para controlar a sua execuo: continue; break; Salta o restante do lao e testa novamente a condio. Finaliza o lao atual, pulando para o primeiro comando aps o final deste.

/* prog11.c */ #include <stdio.h> int main(void) { int num, i=0, vet[5]; printf("Digite 5 numeros entre 1 e 100 (0 para parar)\n"); while(i<5){ printf("%d> ", i+1); scanf("%d", &num); if(num==0) break; if(num<0 || num > 100){ printf("Redigite...\n"); continue; } vet[i] = num; i++; } fflush(stdin); getchar(); return(0); }

Linguagem C

15

Prof. Marcos Jos Brusso

Comando for
Sintaxe: for(exp1; exp2; exp3) comandos; Define um lao onde exp1 a expresso executada antes de entrar no lao. Usado geralmente para atribuir um valor inicial para a varivel de controle do lao. A expresso exp2 avaliada no incio de cada iterao, sendo que o lao ser executado enquanto exp2 for verdadeira. Ao final de cada passagem, exp3 executada. Normalmente usa-se para incrementar (ou decrementar a varivel de controle). Para exp1 e exp3 pode-se usar mais de uma expresso separadas por vrgula. Qualquer uma das partes do comando opcional. Se exp2 for omitida o lao executado indefinidamente (lao infinito). /* prog12.c Exibe o conteudo de um vetor, a soma e a media seus elementos */ #include <stdio.h> int main(void) { int i, vetor[6]={12,3,1,2,10,9}, soma; float media; for(soma=0,i=0; i<6; i++){ printf("vetor[%d]: %d\n", i , vetor[i]); soma += vetor[i]; } media = soma/6.0; printf("Soma: %d\nMedia: %f\n", soma, media); getchar(); return(0); }

Comando switch
Sintaxe: switch(expresso){ case constante1: comando; break; case constante2: comando; break; default: comando; } Avalia a expresso e executa os comandos seguintes ao case que coincidir com o valor da expresso. Ao encontrar um break, o restante do switch pulado. Se nenhum valor de case coincidir com a expresso, ento so executados os comandos aps default (opcional).

Linguagem C

16

Prof. Marcos Jos Brusso

/* prog13.c */ #include <stdio.h> int main(void) { int escolha; float total=0.0; printf("1 - Pizza\n"); printf("2 - Hamburger\n"); printf("3 - Cachorro Quente\n"); printf("0 - FIM\n"); do{ printf("\nFaca sua escolha: "); scanf("%d", &escolha); switch(escolha){ case 1: printf("Voce escolheu pizza.\n"); total+=9.5; break; case 2: printf("Voce escolheu hamburger.\n"); total+=4.0; break; case 3: printf("Voce escolheu cachorro-quente.\n"); total+=1.5; break; case 0 : break; default : printf("OPCAO INVALIDA!\a\n"); } }while(escolha!=0); printf("Total a pagar : %10.2f\n", total); fflush(stdin); getchar(); return(0); }

Diretiva #define
Sintaxe: #define nome valor Substitui toda a ocorrncia de nome no programa-fonte por valor. a chamada substituio de macro. Por conveno todo o nome de macro escrito em letras maisculas. #define PI 3.14159265358979323846 Uma macro pode conter argumentos, que so substituidos na ordem em que aparecem, independente de seu nome. Por exemplo: #define dobro(a) (a*2) #define maior(x,y) ((x>y)?x:y)

Linguagem C

17

Prof. Marcos Jos Brusso

Se for necessrio mais de uma linha para um define deve-se colocar uma contrabarra \ no final da linha. /* prog14.c */ #include <stdio.h> #define #define #define #define TAMANHO 10 odd(n) (n%2!=0) quadrado(n) (n*n) cubo(n) (n*n*n)

int main(void) { int vetor[TAMANHO],i; for(i=0;i<TAMANHO;i++){ if(odd(i)) vetor[i]=quadrado(i); else vetor[i]=cubo(i); printf("%02d\n",vetor[i]); } getchar(); return(0); }

Declarao de Funes
A declarao completa de uma funo em C segue a seguinte sintaxe: tipo nome_da_funcao(lista de argumentos) { declarao das variveis locais; corpo da funo; return(valor); /* Somente se a funo no for void */ } Se a funo no retornar valor ela deve ser declarada com sendo do tipo void. O valor retornado deve ser sempre do mesmo tipo da funo, e passado para a funo chamadora. Os parmetros da funo so variveis locais inicializadas com os valores passados na posio correspondente no momento da sua chamada.

Linguagem C

18

Prof. Marcos Jos Brusso

/* prog15.c */ #include <stdio.h> int fatorial(int x); int main(void) { int num, resultado; printf("Digite um Numero: "); scanf("%d", &num); resultado = fatorial(num); printf("O Fatorial de %d e' %d\n",num, resultado); fflush(stdin); getchar(); return(0); } int fatorial(int x) { int temp=1; while(x>1){ temp*=x; x--; } return(temp); }

Ponteiros
Por padro, toda varivel C declarada para armazenar um valor: variveis int servem para armazenar valores inteiros, float para armazenar valores numricos com preciso simples, etc. Toda a vez que o nome de uma varivel inserido em um programa, est se fazendo referncia ao seu valor, ou seja, o contedo daquela varivel. Existe um tipo especial de varivel em C que ao invs de conter valores, armazena endereos de memria: So os ponteiros (tambm conhecidos por apontadores). Declaraes de ponteiros so precedidas do smbolo * (astersco), como no exemplo: int *var; onde declarada uma varivel var, que pode conter qualquer endereo de memria onde esta armazenado um inteiro. Variveis ponteiro no podem ser usadas antes de serem inicializadas, isto , enquanto no apontarem para um endereo de memria vlido. Para inicializar uma varivel ponteiro podemos atribuir o endereo de outra varivel ou ento alocar memria dinamicamente para ela. Para trabalhar com ponteiros utilizamos 2 operadores unrios especiais: Operador Funo & (Endereo de) Fornece o endereo de memria onde est armazenada uma varivel. * (Valor apontado por) Valor armazenado na varivel referenciada por um ponteiro.

Linguagem C

19

Prof. Marcos Jos Brusso

/* prog16.c */ #include <stdio.h> int main(void) { int variavel, *ponteiro; variavel = 20; ponteiro = &variavel; printf("%d %d\n", variavel, *ponteiro); *ponteiro = 100; printf("%d %d\n", variavel, *ponteiro); getchar(); return(0); }

Operaes com Ponteiros


Pode-se fazer somas e subtraes com um ponteiro. Incrementar um ponteiro que aponta para um elemento de um vetor far com que ele passe a apontar para o prximo elemento, e decrement-lo far com que ele aponte para o elemento anterior. Ponteiros void podem apontar para qualquer tipo de dado, mas no se pode fazer operaes com ponteiros este tipo de ponteiro, nem mesmo referncia indireta. void *p; Um ponteiro, aps inicializado, pode ser usado como se fosse um vetor do tipo de dados que foi declarado. Sempre que um vetor aparece em um programa sem um subscrito (ndice), apenas o nome, assumido o endereo do primeiro elemento deste vetor. /* prog17.c */ #include <stdio.h> int main(void) { char frase[]="teste", *p; int i; printf("%s\n",frase); p=frase; /* Mesmo que ponteiro=&nome[0]; */ printf("\nUsando o indice\n"); for(i=0; p[i]!='\0'; i++) printf("%c\n",p[i]); printf("\nIncrementando o ponteiro\n"); while(*p!='\0'){ printf("%c\n", *p); p++; } getchar(); return(0); }

Linguagem C

20

Prof. Marcos Jos Brusso

Passagem de Parmetros por Valor


Por padro, os parmetros so passados para as funes por valor, isto , apenas uma cpia do valor do argumento passado para a funo chamada e se esta funo alterar o valor recebido, esta modificao no afetar a varivel usada por quem chamou. /* prog18.c */ # include <stdio.h> void dobro(int valor); int main(void) { int num=3; printf("%d\n",num); dobro(num); printf("%d\n",num); getchar(); return(0); } void dobro(int valor) { valor = valor*2; printf("%d\n",valor); }

Passagem de Parmetros por Referncia


Se no lugar de passar o valor de uma varivel, for passado o seu endereo de memria como argumento de uma funo, qualquer alterao feita usando referncia indireta ir modificar o valor da varivel na funo chamadora. Isto passagem de parmetro por referncia. Para passarmos o endereo de uma varivel, o parmetro deve ser declarado como um ponteiro. /* prog19.c */ # include <stdio.h> void dobro(int *ref); int main(void) { int num=3; printf("%d\n",num); dobro(&num); printf("%d\n",num); getchar(); return(0); } void dobro(int *ref) { *ref= *ref * 2; printf("%d\n", *ref); }

Linguagem C

21

Prof. Marcos Jos Brusso

Funes e Vetores
Vetores obrigatoriamente devem ser passados como parmetro por referncia. ento passado o endereo do primeiro elemento do vetor. Uma funo no pode retornar um vetor, mas pode retornar um ponteiro para este. /* prog20.c */ # include <stdio.h> void troca(char *str, int atual, int novo); int main(void) { char nome[80]="teste"; printf("%s\n", nome); troca(nome,'e','a'); printf("%s\n", nome); getchar(); return(0); } void troca(char *str, int atual, int novo) { int i; for(i=0;str[i]!='\0';i++){ if(str[i]==atual) str[i]=novo; } }

Alocao Dinmica de Memria


Pode-se alocar, isto , reservar reas de memria dinamicamente durante a execuo de um programa e atribuir o endereo alocado para um ponteiro. Isto til quando no se conhece o tamanho necessrio para um vetor em tempo de compilao ou quando se quer criar ou destruir variveis em qualquer parte do programa. As funes para alocao de memria esto definidas em stdlib.h. void *malloc(unsigned tamanho) Aloca memria (tamanho em bytes) e retorna um ponteiro para a memria alocada. Retorna NULL se no existir memria disponvel suficiente. void *realloc(void *prt, unsigned tamanho) Altera o tamanho da rea alocada por malloc(). Se o bloco no puder ser realocado retorna NULL. void free(void *ptr) Libera a memria alocada por malloc().

Linguagem C

22

Prof. Marcos Jos Brusso

/* prog21.c */ #include <stdlib.h> #include <stdio.h> int main(void) { int *vetor, num, i, soma=0; printf("Numero de elementos do vetor:"); scanf("%d", &num); vetor = malloc(num*sizeof(int)); if(vetor==NULL){ printf("Sem Memoria!\a\n"); return(1); } for(i=0;i<num;i++){ printf("Informe vetor[%d]:", i); scanf("%d", &vetor[i]); soma += vetor[i]; } printf("Total: %d", soma); free(vetor); fflush(stdin); getchar(); return(0); }

Funes de Manipulao de Strings


Alguns cuidados devem ser tomados ao se lidar com strings em C. Por serem vetores char, as strings esto sujeitas a todas as regras pertinentes aos vetores normais. Todas as strings devem ser passadas por referncia para funes, uma funo no pode retornar uma strings, mas pode retornar o endereo de uma string (char *) e o C no faz verificao de limite para vetores. Outras limitaes decorrentes e muito importantes so as seguintes: 1. Strings no podem ser atribudas com o operador de atribuio = (embora possam ser inicializadas) 2. Strings no podem ser comparadas com o operador de comparao == Para contornar estes problemas pode-se usar algumas funes da biblioteca padro C, definidas em string.h char *strcpy(char *destino, char *origem) Copia uma string em outra (origem para destino). Retorna destino. Ex: strcpy(nome,"computao"); char *strncpy(char *destino, char *origem, unsigned n) Copia no mximo n caracteres de origem para destino. No coloca \0 no final de destino. Retorna destino. Ex: strcpy(nome,"computao",3); /* copia "com" */ int strcmp(char *s1, char *s2) Compara s1 com s2. Retorna < 0 se s1 < s2, 0 se s1==s2 ou >0 se s1>s2. Ex: if(strcmp(opcao,"FIM")==0) return;

Linguagem C

23

Prof. Marcos Jos Brusso

int strncmp(char *s1, char *s2, unsigned num) Compara no mximo num caracteres de s1 com s2. Retorna < 0 se s1 < s2, 0 se s1==s2 ou >0 se s1>s2. Ex: if(strncmp(endereco,"http",4)==0) flag = 1; char *strcat(char *destino, char *origem) Concatena origem a destino. Retorna destino. Destino deve ter tamanho suficiente para receber a string concatenada. Ex: strcat(cidade," - RS"); unsigned strlen(char *string) Retorna o nmero de caracteres da string, sem contar o '\0'. Ex: strcpy(nome,"COMPUTACAO"); printf("%d",strlen(nome)); /* 10 */

Funes de Tratamento de Caracteres


A biblioteca padro da linguagem C provm um conjunto de funes para teste e converso de caracteres. Estas funes esto definidas em ctype.h. int isalnum(int caracter) Retorna verdadeiro se caracter letra ou nmero. int isalpha(int caracter) Retorna verdadeiro se caracter uma letra. int isdigit(int caracter) Retorna verdadeiro se caracter um nmero ('0'..'9'). int islower(int caracter) Retorna verdadeiro se caracter letra minscula. int isupper(int caracter) Retorna verdadeiro se caracter letra maiscula. int isspace(int caracter) Retorna verdadeiro se caracter um espao em branco. int tolower(int caracter) Se caracter for letra, retorna-o convertido para minsculo, seno retorna o prprio caracter. int toupper(int caracter) Se caracter for letra, retorna-o convertido para maisculo, seno retorna o prprio caracter.

Linguagem C

24

Prof. Marcos Jos Brusso

/* prog22.c */ #include <ctype.h> #include <stdio.h> void nomeproprio(char *destino, char *origem); int main(void) { char nome[80], temp[80]; printf("Digite um Nome:"); gets(nome); nomeproprio(temp, nome); printf("Original:[%s] \nAlterado:[%s]\n", nome, temp); getchar(); return(0); } void nomeproprio(char *destino, char *origem) { int i; char ant=' '; for(i=0; origem[i]!='\0'; i++){ destino[i] = (ant==' ')?toupper(origem[i]):tolower(origem[i]); ant = origem[i]; } destino[i] = '\0'; }

Estruturas
Sintaxe: struct etiqueta_da_estrutura { tipo membro_1; tipo membro_2; tipo membro_n; }; Estrutura o conjunto de uma ou mais variveis colocadas sob um nome nico. Estrutura implementa em C a idia de registro. struct int int int }; data{ dia; mes; ano;

Para acessar um membro da estrutura deve-se usar o operador . (ponto), unindo o nome da varivel de estrutura com o nome do campo (ou membro). struct data nascimento; nascimento.dia = 10;

Linguagem C

25

Prof. Marcos Jos Brusso

O tamanho total de uma estrutura igual a soma do tamanho de seus itens. Estruturas podem ser aninhadas, isto , estruturas podem fazer parte de outras estruturas.Pode-se criar vetores de estruturas e estruturas podem ser inicializadas na declarao. /* prog23.c */ #include <stdio.h> #include <string.h> #include <ctype.h> #define TAMANHO 4 struct data{ int dia, mes, ano; }; struct aluno{ int matricula; char nome[30]; struct data nascimento; }; int main(void) { struct aluno turma[TAMANHO] = { {9991, "Fulano", {10,5,1965}}, {9992, "Cicrano", {23,8,1977}}, {9993, "Beltrano", {14,1,1970}}, {9994, "Individuo", {2,10,1969}}, }; int i, achou, quem; char escolha; do{ printf("Matricula: "); scanf("%d", &quem); achou = 0; for(i=0; i<TAMANHO; i++) if(quem==turma[i].matricula){ printf("Nome: %s\n", turma[i].nome); printf("Nascimento: %02d/%02d/%04d\n", turma[i].nascimento.dia, turma[i].nascimento.mes, turma[i].nascimento.ano); achou = 1; break; } if(!achou) printf("Nao Encontrado\n"); printf("\nContinuar? [S/N]: "); fflush(stdin); escolha=getchar(); }while(toupper(escolha)=='S'); return(0); }

Linguagem C

26

Prof. Marcos Jos Brusso

Ponteiros para estruturas


Podem ser criados ponteiros para estruturas, como no exemplo: struct data *ptr_data; Para acessar o membro de uma estrutura atravs de um ponteiro usa-se o operador -> (seta). Neste caso, o ponteiro deve estar, obrigatoriamente, apontando para uma varivel de estrutura do mesmo tipo do ponteiro. ptr_data->dia = 10; Estruturas no podem ser passadas por valor para funes, deve-se passar um ponteiro para a estrutura. Tambm no podemos retornar uma struct em uma funo mas pode-se retornar o endereo da estrutura. /* prog24.c */ #include<stdio.h> struct data{ int dia, mes, ano; }; void exibedata(struct data *pd) { char *meses[12]={"Janeiro","Fevereiro","Marco","Abril","Maio", "Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"}; printf("%02d de %s de %04d\n", pd->dia, } int main(void) { struct data dt1; printf("Informe uma data: "); scanf("%d/%d/%d", &dt1.dia, &dt1.mes, &dt1.ano); exibedata(&dt1); fflush(stdin); getchar(); return(0); } meses[pd->mes-1], pd->ano);

Argumentos de Linha de Comando


Os programas escritos em C podem receber parmetros a partir da linha de comando. Este argumentos so utilizados com muita freqencia no sistema operacional Unix e suas variantes, como Linux, onde praticamente todos os programas aceitam argumentos, que servem para informar ao programa o que o usurio deseja que ele faa. ls ls *.C ls -l *.c Para acessar os parmetros passados a partir do sistema operacional deve-se definir 2 argumentos para a funo main().O primeiro um inteiro (argc), que ir conter o nmero de parmetros passados. O segundo parmetro (argv), um vetor de strings (ponteiro para ponteiros para char) que contm cada um dos argumentos passados.Como argv[0] contm o nome do programa, ento argc sempre maior ou igual a 1.

Linguagem C

27

Prof. Marcos Jos Brusso

/* prog25.c */ #include <stdio.h> #include <string.h> #define TAMANHO 10 int main(int argc, char **argv) { int vetor[TAMANHO]={5, 2, 8, 10, 1, 12, 9, 5, 4, 6}; int mostra_soma=0, mostra_media=0, i, soma=0; float media=0.0; for(i=1;i<argc;i++){ if(strcmp(argv[i], "-s")==0 || strcmp(argv[i], "-S")==0) mostra_soma=1; else if(strcmp(argv[i], "-m")==0 || strcmp(argv[i], "-M")==0) mostra_media=1; else{ printf("Argumento %s invalido\a", argv[i]); return(1); } } for(i=0; i<TAMANHO; i++){ printf("vetor[%d]=%d\n", i, vetor[i]); soma += vetor[i]; } if(mostra_soma) printf("Soma: %d\n", soma); if(mostra_media){ media = (float)soma/TAMANHO; printf("Media: %f\n", media); } getchar(); return(0); }

Funes de Entrada e Sada em Arquivos Sequenciais


O tipo FILE, definido em <stdio.h> uma definio de estrutura usado pelas funes de acesso a arquivos com buffer em C. FILE *fopen(char *nome_do_arquivo,char *modo_de_abertura) Abre o arquivo e retorna um ponteiro para a estrutura do arquivo aberto, ou NULL em caso de erro. A string modo_de_abertura pode conter alguns dos seguintes caracteres: Caracter "r" "w" "a" "+" "b" "t" Finalidade Abre para leitura Cria um novo arquivo para escrita. Se j existe eliminado e recriado. Abre para escrita no final do arquivo (append). Em conjunto com "r" permite acesso de leitura e escrita (I/O). O arquivo um arquivo binrio. Arquivo texto. (Linha finalizadas com '\n' e arquivo com EOF)

Alguns arquivos so associados dispositivos e definidos automaticamente pelo C, e podem ser usados por

Linguagem C

28

Prof. Marcos Jos Brusso

qualquer programa: Arquivo Descrio stdin Dispositivo de entrada padro. stdout Dispositivo de sada padro. stderr Dispositivo de sada de erros.

int fprintf(FILE *arquivo,char *formato,...) Semelhante a printf(), mas pode-se especificar o arquivo de sada. int fclose(FILE *arquivo) Fecha o arquivo. Retorna 0 se OK ou EOF se algum erro ocorreu. int fgetc(FILE *arquivo) L um caracter do arquivo. Retorna o caracter lido ou EOF no final do arquivo ou em caso de erro. int fputc(int caracter, FILE *arquivo) Escreve um caracter no arquivo. Retorna o caracter gravado ou EOF em caso de erro. /* copia.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { FILE *origem,*destino; int temp; if(argc!=3){ fprintf(stderr, "Numero de parametros incorreto\a"); exit(1); } if((origem=fopen(argv[1],"rb"))==NULL){ fprintf(stderr, "Nao consegui abrir %s\n",argv[1]); exit(1); } if((destino=fopen(argv[2],"wb"))==NULL){ fprintf(stderr, "Nao consegui abrir %s\n",argv[2]); exit(1); } do{ temp=fgetc(origem); if(temp==EOF) break; fputc(temp,destino); }while(1); fclose(origem); fclose(destino); return(0); } char *fgets(char *linha, int tamanho, FILE *arquivo) L uma linha de texto de um arquivo. retorna um ponteiro para a string lida ou NULL em caso de erro ou final de arquivo. O parmetro tamanho limita o numero mximo de bytes que se quer ler por linha(tamanho-1). Se a linha no arquivo for maior que tamanho, l apenas a parte inicial. O restante ser lido na prxima chamada fgets(). int fputs(char *linha,FILE *arquivo) Escreve uma string em um arquivo. Retorna o ltimo caracter gravado ou EOF em caso de erro.

Linguagem C

29

Prof. Marcos Jos Brusso

/* exibe.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { FILE *arq; char linha[255]; if(argc!=2){ fprintf(stderr, "Numero de parametros incorreto\a\n"); exit(1); } if((arq=fopen(argv[1],"rt"))==NULL){ fprintf(stderr, "Nao consegui abrir %s\n",argv[1]); exit(1); } while(fgets(linha,sizeof(linha),arq)!=NULL) printf("%s",linha); fclose(arq); return(0); }

Funes de Entrada e Sada Aleatria em Arquivos


Para acesso randmico a arquivos, mantido um cursor que indica a posio do arquivo a partir do qual ser feita a prxima leitura/escrita no arquivo. Cada vez que se l/escreve n bytes no arquivo este cursor incrementado em n. int fread(void *buffer, int tamanho, int num, FILE *arquivo) L bytes de um arquivo e armazena-os na posio de memria apontada por buffer. A funo retorna o nmero de itens realmente lidos e avana o cursor de arquivo tamanho*num bytes. Parmetro Descrio buffer Ponteiro para uma rea de memria onde sero armazenados os dados lidos do arquivo. tamanho num arquivo Numero de bytes a ler. Geralmente sizeof(buffer). Numero de itens a ler. Geralmente 1. Ponteiro FILE para um arquivo aberto anteriormente por fopen().

int fwrite(void *buffer, int tamanho, int num, FILE *arquivo) Escreve bytes em um arquivo. A funo retorna o nmero de itens realmente gravados e avana o cursor tamanho*num bytes. Se o cursor estiver apontando a uma rea j gravada do arquivo, ento os novos dados iro sobrescrever os anteriores. Se estiver apontando para o final do arquivo ento os os novos dados sero anexados. Parmetro buffer tamanho num arquivo Descrio Ponteiro para uma rea de memria onde esto armazenados os dados a serem gravados no arquivo. Numero de bytes a gravar. Geralmente sizeof(buffer). Numero de itens a gravar. Geralmente 1. Ponteiro FILE para um arquivo aberto anteriormente por fopen().

int fseek(FILE *arquivo,int deslocamento, int apartir) Altera a posio do cursor de um arquivo. Retorna 0 se OK.

Linguagem C

30

Prof. Marcos Jos Brusso

Parmetro arquivo deslocamento apartir

Descrio Ponteiro FILE para um arquivo aberto anteriormente por fopen(). Nmero de bytes a deslocar, relativos a apartir. Deve ser um inteiro positivo. Define o ponto inicial do deslocamento.

Para o parmetro apartir, pode ser uma das seguintes macros definidas em stdio.h: Valor SEEK_SET SEEK_CUR SEEK_END Descrio Posiciona a partir do inicio do arquivo. Relativo a posio atual. Retrocede do final do arquivo.

void rewind(FILE *arquivo) Posiciona o cursor no inicio do arquivo. identico a fseek(arquivo,0L,SEEK_SET). int ftell(FILE *arquivo) Retorna o valor atual do cursor de arquivo, isto a posio da prxima escrita ou leitura. int feof(FILE *arquivo) Retorna diferente de zero se foi tentado ultrapassar o final do arquivo.

Linguagem C

31

Prof. Marcos Jos Brusso

/* cadastra.c */ #include <stdio.h> #include <stdlib.h> struct cidades{ int codigo; char nome[50]; char uf[3]; }; int main(void) { FILE *arquivo; struct cidades cidade; int achou, cod_temp; /*TENTA ABRIR PARA LEITURA/GRAVACAO*/ arquivo=fopen("cidades.dat","r+b"); if(arquivo==NULL){ /* SE NAO CONSEGUIR CRIA O ARQUIVO */ arquivo = fopen("cidades.dat","w+b"); if(arquivo==NULL){ fprintf(stderr,"Nao consegui criar o arquivo\n"); exit(1); } } do{ printf("\nCodigo : "); scanf("%d", &cod_temp); fflush(stdin); if(cod_temp==0) break; /* POSICIONA NO INICIO DO ARQUIVO */ rewind(arquivo); achou = 0; while(fread(&cidade,sizeof(cidade),1,arquivo)==1 && !feof(arquivo)) /* LE ATE O FINAL PROCURANDO CODIGO */ if(cidade.codigo==cod_temp){ printf("Codigo ja cadastrado. Tecle Algo..."); getchar(); achou = 1; break; } if(!achou){ cidade.codigo = cod_temp; printf("Nome.. : "); gets(cidade.nome); printf("Estado.: "); gets(cidade.uf); /* POSICIONA NO FINAL PARA INCLUSAO E GRAVA NOVO REGISTRO */ fseek(arquivo,0,SEEK_END); fwrite(&cidade,sizeof(cidade),1,arquivo); } }while(1); fclose(arquivo); return(0); }

Linguagem C

32

Prof. Marcos Jos Brusso

/* lista.c */ #include <stdio.h> #include <stdlib.h> struct cidades{ int codigo; char nome[50]; char uf[3]; }; int main(void) { FILE *arquivo; struct cidades cidade; /*TENTA ABRIR PARA LEITURA/GRAVACAO*/ arquivo=fopen("cidades.dat","r+b"); if(arquivo==NULL){ fprintf(stderr,"Nao consegui abrir o arquivo\n"); exit(1); } /*EXIBE TODOS OS REGISTROS CADASTRADOS */ while(fread(&cidade,sizeof(cidade),1,arquivo)==1 && !feof(arquivo)) printf("%04d %-50s %2s\n",cidade.codigo,cidade.nome,cidade.uf); fclose(arquivo); getchar(); return(0); }

Linguagem C

33

Prof. Marcos Jos Brusso

Exerccios
1) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado. #include <stdio.h> void main(void) { int n1=15, n2=4; char txt[]="ASDFGHJKL"; float vf=9.5; printf("[%4d]", n1); printf("[%03d]", n2); printf("[%12s]", txt); printf("[%c]", txt[1]); printf("[%c]", txt[n2]); printf("[%-6.4s]", txt); printf("[%10.2f]", vf); printf("%-8.1f", vf); }

2) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado. #include <stdio.h> void main(void) { int m[2][2] = {{10, 32}, {500,41}}; int v1 = 0, v2 = 1; char str[] = "TCLITE"; printf("[%05d]", m[++v1][v2++]); printf("[%-4d]", v2); v1 += v2; printf("[%04d]", v1); printf("[%4.3s]", str); v1 = (m[0][1]>m[1][0])? 4: 1; printf("[%c]", str[v1]); }

3) Escrever um programa que declara um vetor de 20 elementos inteiros, l um valor qualquer para cada posio do vetor e aps exibe cada valor do vetor em decimal, octal e hexadecimal, um elemento do vetor por linha, em colunas de 5 caracteres alinhadas a esquerda. 4) Escrever um programa que l uma matriz float de 20 linhas e 20 colunas e a seguir exibe toda a coluna onde est o menor valor da matriz. O programa deve ter pelo menos um lao do tipo do while

5) Escrever um programa que declara uma matriz float com 4 linhas e 5 colunas, l um valor para cada posio da matriz e no final exibe a mdia dos valores para cada coluna da matriz. Estes valores devem ser exibidos com 3 casas decimais.

Linguagem C

34

Prof. Marcos Jos Brusso

6) O seguinte programa deveria ler os valores para um vetor int de 10 elementos e no final mostrar a soma dos valores informados. Encontre os erros no programa, corrija-os e justifique cada correo feita.

#include <stdio.h> #include <conio.h> void main(void); { int vet[10], i, soma=0; clrscr; for(i=0; i==10; i++){ printf("Digite o ", i+1, " numero: "); scanf("%d", vet[i]); soma+=vet[i]; } printf("Soma dos valores digitados: %d", soma); }
7) Escrever um programa que declara uma matriz de 4 linhas e 3 colunas de nmeros inteiros, l uma valor para cada posio da matriz e mostra os valores da matriz que so iguais ao seu ndice de linha ou o seu ndice de coluna. Mostrar com seguinte formato:

Linha 0, Coluna 1 : Valor 1 Linha 2, Coluna 2 : Valor 2


8) Escrever um programa que declara trs variveis int (n1, n2 e n3), l um valor maior que zero para cada varivel e exibe o menor valor lido multiplicado pelo maior e o maior valor dividido pelo menor. 9) Escrever um programa que declara um vetor de 20 inteiros, l um valor para cada posio e no final mostra quantos elementos possuem valor maior, menor e igual ao primeiro elemento do vetor. 10) Escrever uma funo int calcula(int n1, int n2, int n3), que recebe trs nmeros inteiros como parmetro e retorna o maior valor passado multiplicado pelo menor.

var = calcula(10, 5, 8); var = calcula(0, -1, 20); var = calcula(5, 6, 7);

/* var recebe 50 (10 * 5) */ /* var recebe -20 (20 * -1) */ /* var recebe 35 (7 * 5) */

11) Escrever uma funo int somaintervalo(int n1, int n2) que retorna a soma dos nmero inteiros que existem entre n1 e n2 (inclusive ambos). A funo deve funcionar inclusive se o valor de n2 for menor que n1.

n=somaintervalo(3, 6); n=somaintervalo(5,5); n=somaintervalo(-2,3); n=somaintervalo(4, 0);

/* /* /* /*

n n n n

recebe recebe recebe recebe

18 10 3 10

(3 + 4 + 5 + 6) */ (5 + 5) */ (-2 + -1 + 0 + 1 + 2 + 3) */ (4 + 3 + 2 + 1 + 0) */

12) Escrever um programa que l quatro nmeros inteiros (4 variveis separadas) e exibe a mdia dos valores digitados. A leitura deve ser feita na funo main() e a exibio em uma funo chamada calcula(). O programa no pode ter variveis globais. 13) Escrever um programa que l quatro valores float e exibe o maior e o menor valor digitado. A leitura deve ser feita em uma funo chamada ler() e o resultado deve ser exibido em uma funo chamada exibe(), sendo que no pode ser declarada nenhuma varivel global.

14) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir

Linguagem C

35

Prof. Marcos Jos Brusso

espaos em branco por sublinhado (_):

#include <stdio.h> #define macro(n) (n)?n*2:n*n void main(void) { int a=2, b=9, vt[3]={6,2,4}; float fv=5.0; char txt[]="ASDFGHJKL"; printf("[%-4d]", sizeof(txt)); b=macro(vt[1]); printf("[%04d]", b); fv/=a; printf("[%8.5f]", fv); txt[--b]='X'; printf("[%8.5s]", txt); printf("[%4d]", b); printf("[%c]", txt[a]); }
15) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado (_):

#include <stdio.h> void main(void) { int vet[5]={9,4,6,2,5}; char str[]="boa sorte"; int num=1,i=0; int *ptr; ptr=&num; *ptr = vet[3]; printf("[%-5d]", num); ptr = vet; vet[0] = --num; printf("[%4d]", ptr[0]); printf("[%c]", str[num]); num=0; while(i<3){ num+=vet[i]; i++; } printf("[%03d]", num); printf("[%5.2s]", str); }

Linguagem C

36

Prof. Marcos Jos Brusso

16) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado (_):

#include <stdio.h> void main(void) { float vetor[]={3.5, 2.0, 4.5, 9.0}; float var=0.0; float *p; int x, y; y=sizeof(vetor); printf("[%d]", y++); p = vetor; x = (int) *p; printf("[%04d]", x); p++; *p += y; printf("[%8.3f]", vetor[1]); x=0; while(var < 15.0){ var+= vetor[x]; x++; } printf("[%10.1f]", var); printf("[%-5d]", x); }
17) Mostrar o que seria exibido aps cada chamada funo printf. Substituir brancos por sublinhado.

#include <stdio.h> void main(void) { char c0; int num=5, teste=55, *ptr; char linha[]="final"; ptr = &num; c0 = (num/2)?'3':'9'; *ptr += sizeof(c0); printf("[%-5d]", num); printf("[%c]", c0); ptr = &teste; *ptr = -1; printf("[%3d]", ++teste); for(num=0, teste=1; linha[num] !='\0';num++) teste += num; printf("[%d]", teste); printf("[%c]", linha[--num]); }

Linguagem C

37

Prof. Marcos Jos Brusso

18) Mostrar o que seria exibido aps cada chamada funo printf. Substituir brancos por sublinhado.

#include<stdio.h> void main(void) { int t1=1,i=0,vet[3]={3,2,4}; int *p; char str[]="outubro"; do{ t1 *= vet[i++]; }while(i<3); p=&t1; printf("[%-5d]",*p); t1 = sizeof(str) + i; printf("[%4d]",t1); printf("[%c]",str[i]); *p = 0; printf("[%d]",vet[t1]); printf("[%5.2s]",str); }
19) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado (_):

#include <stdio.h> void main(void) { char texto[]="THINK!"; int a=10, b=2, c=0; int *pin; float vf=0.0; pin = &a; a = ++b; printf("[%-3d]", *pin); c = (b>2)?15:25; printf("[%04d]", c); pin = &b; printf("[%-10.4s]", texto); *pin = 1; printf("[%c]", texto[b]); a-=1; vf = c/a; printf("[%6.2f]", vf); }

Linguagem C

38

Prof. Marcos Jos Brusso

20) Escrever ao lado de cada funo printf deste programa o que ser exibido na sua execuo.

#include <stdio.h> void main(void) { int i, n, x, vet[]={3, 5, 9, 0, 4}; int *ptr; ptr = vet; printf("[%3d]", *ptr); *ptr = 2; for(i=n=x=0; i<4; i++){ n+=vet[i]; x = (i%2)?x+1:x+2; } printf("[%-4d]", n); printf("[%d]", i*sizeof(vet)); printf("[%d]", x); ptr++; printf("[%03d]", *ptr); }
21) Mostrar ao lado de cada chamada a funo printf o que ser exibido na execuo deste programa. Substituir espaos em branco por um trao.

#include <stdio.h> #include <string.h> #include <ctype.h> void main(void) { int a=1, b=0, vet[4] = {6, 9, 2, 5}, *ptr; char txt[10]="1prova"; ptr = &a; b = *ptr; printf("[%04d]", vet[b]); ptr = vet; a = ++b; printf("[%d]", a); ptr++; printf("[%-5d]", *ptr); printf("[%3d]", sizeof(txt) - strlen(txt)); for(a=1, b=0; txt[b]!='\0'; b++) if(isalpha(txt[b])) a*=2; printf("[%d]", a); }

Linguagem C

39

Prof. Marcos Jos Brusso

22) Escrever uma funo int divisao(int dividendo, int divisor, int *resto), que retorna a diviso inteira (sem casas decimais) de dividendo por divisor e armazena no parmetro resto, passado por referncia, o resto da diviso.

int r, d, d = divisao(5, 2, &r); printf("Resultado:%d Resto:%d", d, r); /* Resultado:2 Resto:1 */


23) Escrever um programa que declara um vetor int com 30 elementos na funo main e atribui 0 (zero) para todos os elementos com um lao for. Em seguida, em uma funo chamada leitura, deve ler um valor maior que 0 e menor que 1000 para cada posio do vetor. Finalmente, em uma funo chamada calculo, deve ser exibido o maior e o menor valor armazenado no vetor. No pode ser declarada nenhuma varivel global. 24) Escrever um programa que declara um vetor int com 20 elementos na funo main e l um valor para cada posio do vetor na mesma funo. Em seguida exibir o contedo do vetor em uma funo chamada exibe, seguindo a seguinte lgica: Se a soma dos valores armazenados no vetor for um nmero par, mostrar o vetor a partir do primeiro elemento at o ltimo. Se a soma dos valores armazenados no vetor for um nmero impar, mostrar o vetor a partir do ltimo elemento at o primeiro. O programa no pode utilizar nenhuma varivel global. 25) Escrever uma funo int ultima(char *string, char c) que retorna qual a ltima posio na string em que aparece o caracter c. Se o caracter no estiver na string, retornar 1.

char str[]=teste; int q; q=ultima(str, t); q=ultima(str, x);

/* q recebe 3 */ /* q recebe 1 */

26) Escrever uma funo int substitui(char *string, char c1, char c2), que troca, na string recebida como parmetro, toda a ocorrncia do caracter c1 pelo caracter c2. A funo deve retornar o nmero de substituies que foram feitas.

char txt[] = "recupera"; int num; num = substitui(txt, 'e', 'X'); printf("%d - %s", num, txt); /* 2 - rXcupXra */
27) Escrever a funo char *right(char *destino, char *origem, int num) que copia para a string destino os ltimos num caracteres da string origem. Retornar destino.

char str[80]; right(str, "testando", 2); right(str, "abcdefgh", 4);

/* str recebe "do" */ /* str recebe "efgh" */

28) Escrever uma funo int totalpos(char *string, char c), que retorna a soma das posies (ndices) da string onde aparece o caracter c. Se o caracter no aparece na string, retornar -1.

num = totalpos(internet, e); num = totalpos(internet, i); num = totalpos(internet, a);

/*retorna 9 (3+6) */ /*retorna 0 (0) */ /*retorna -1 */

29) Escrever uma funo int contadepois(char *string, char c) que retorna quantos caracteres a string possui aps a primeira posio onde aparece o caracter c. Se a string no possuir o caracter c a funco deve retornar -1.

var var var var

= = = =

contadepois(avaliando, contadepois(avaliando, contadepois(avaliando, contadepois(avaliando,

n); a); o); x);

/* /* /* /*

var var var var

recebe recebe recebe recebe

2 8 0 -1

*/ */ */ */

Linguagem C

40

Prof. Marcos Jos Brusso

30) Escrever uma funo int primeira(char *string, char c) que retorna qual a primeira posio na string em que aparece o caracter c. Se o caracter no estiver na string, retornar 1.

char str[]=teste; int q; q=primeira(str, e); q=primeira(str, x);

/* q recebe 1 */ /* q recebe 1 */

31) Escrever um programa que declara uma string de 80 caracteres na funo main, l a string, e depois exibe a string informada, um caracter em cada linha em uma outra funo chamada mostra. No pode ser declarada nenhuma varivel global. 32) Escrever um programa que inicialmente pede ao usurio qual o tamanho do vetor que ele quer usar. Ento cria dinamicamente um vetor float do tamanho informado, l um valor para cada posio do vetor e no final exibe a soma e a mdia do vetor, ambas com 3 casas decimais e todos os valores do vetor que forem maior que a mdia calculada. O programa deve ter no mnimo 2 funes e no pode declarar variveis globais. 33) Escrever um programa que aloca dinamicamente um vetor double com tamanho informado pelo usurio na funo main. A seguir, l um valor para cada posio na funo leitura. Finalmente mostra a soma dos valores que esto armazenados em posio pares do vetor na funo exibe. No pode ser declarada nenhuma varivel global. 34) Escrever um programa que declara dois vetores int com 20 elementos, vet1 e vet2. L um valor para cada posio de vet1, copia vet1 invertido (de trs para frente) em vet2 e exibe os dois vetores. A leitura deve ser feita em uma funo chamada leitura, a inverso em funo chamada inverte e a exibio em uma funo chamada exibe. No pode ser declarada nenhuma varivel global. 35) Escrever ao lado de cada chamada funo printf o que ser exibido na execuo deste programa. Substituir espaos em branco por _

#include <stdio.h> #include <string.h> #include <ctype.h> #define dif(y, z) (y>z)?y-z:z-y void main(void) { int a=6, i=1, *ptr; char frase[]="a*b23*z", outra[20]="0123456789ABCDEF"; ptr = &i; for(i=0; frase[i]!='\0'; i++) if(isdigit(frase[i])) a+=i; printf("[%-4d]", a++); printf("[%03d]", *ptr); *ptr = strlen(frase)-2; printf("[%c]", outra[--i]); printf("[%3d]", dif(a, i)); outra[1] = '&'; printf("[%-6.3s]", outra); }
36) Escrever uma funo void copialn(char *destino, char *origem), que copia apenas os caracteres da string origem que so letra ou nmero para a string destino.

char s1[20]=Por $17,00, char s2[20]; copialn(s2, s1); /* s2 recebe Por1700 */

Linguagem C

41

Prof. Marcos Jos Brusso

37) Escrever um programa que declara uma string palavra com 80 caracteres. A seguir o programa deve ler repetidamente esta string (usar gets) e mostrar a string e o seu tamanho (nmero de caracteres ocupados) at que o valor digitado seja FIM. No final mostrar quantas leituras foram feitas e o nmero total de caracteres.

Digite uma string: AULA String: [AULA] Caracteres: 4 Digite uma string: TESTANDO String: [TESTANDO] Caracteres: 8 Digite uma string: FIM String: [FIM] Caracteres: 3 Strings Lidas: 3 Total de Caracteres: 15
38) Mostrar ao lado de cada chamada a funo printf o que ser exibido na execuo do programa abaixo. Substituir espaos em branco por _

#include <stdio.h> #include <ctype.h> #include <string.h> void main(void) { int a=0, b=2, c=10; char txt1[80]="A*E*I*O*U", txt2[80]="X:Y:Z"; char *ptr; ptr=txt1; ptr++; a=(isalpha(*ptr))?b:c; printf("[%03d]", --a); strcpy(txt2, txt1); *ptr = '$'; printf("[%-12s]", txt1); b = a-strlen(txt2); printf("[%-5d]", b++); printf("[%c]", txt2[1]); if(strcmp(txt1, txt2)==0) c = b + sizeof(txt1); printf("[%6d]", c); }

Linguagem C

42

Prof. Marcos Jos Brusso

39) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado (_):

#include <stdio.h> #include <string.h> void main(void) { char frase[]="computacao"; char *p; float var=0.0; int i, k; p = frase; k=strlen(frase); printf("[%04d]", ++k); while(*p != '\0'){ p++; var += 1.5; } printf("[%7.2f]", var); i = (int) var - k; printf("[%-5d]", i); k = sizeof(var); printf("[%c]", frase[k]); printf("[%-7.5s]", frase); }
40) Escrever uma funo void stringup(char *destino, char *origem), que copia todos os caracteres da string origem para destino, convertendo-os para maiscula.

char s1[20], s2[20]=aula de c; stringup(s1, s2); printf(%s, s1); /* AULA DE C */


41) Escrever uma funo void removeb(char *str1, char *str2) , que recebe duas strings como parmetro e copia para a primeira string (str1) todos os caracteres da segunda (str2) que no so brancos.

char txt1[80]=" a b c d, txt2[80]; removeb(txt2, txt1); printf("[%s]", txt2); /* Exibe [a b c d] */


42) Escrever um programa que l repetidamente uma string em um lao. Se o valor digitado for igual a exit, deve parar, seno exibe-a um caracter por linha.

Digite uma string: aula a u l a Digite uma string: abc a b c Digite uma string: exit

Linguagem C

43

Prof. Marcos Jos Brusso

43) Mostrar ao lado de cada chamada a funo printf o que ser exibido na execuo do programa abaixo. Substituir espaos em branco por _

#include <stdio.h> #include <ctype.h> #include <string.h> void main(void) { char sa[20]="A1B2C3D4", sb[10]="Z9"; char *p; int i=1, j; p=sa; j=(isdigit(sa[--i]))?sizeof(sa):sizeof(sb); printf("[%-5d]", j); strcat(sa, sb); p++; *p = 'H'; printf("[%12s]", sa); i+=strlen(sb); printf("[%06d]", i++); if(strcmp(sa, sb) < 0) i*=2; printf("[%c]", sa[i]); printf("[%-5.1s]", sb); }
44) Escrever ao lado de cada chamada funo printf o que ser exibido na execuo deste programa. Substituir espaos em branco por _

#include <stdio.h> #include <string.h> #include <ctype.h> #define dif(y, z) (y>z)?y-z:z-y void main(void) { int a=2, i=1, *ptr; char frase[]="PROGRAMA.C", outra[20]="abcdefghijklmn"; ptr = &i; for(i=0; frase[i]!='\0'; i++) if(isalnum(frase[i])) a+=i; printf("[%-4d]", --a); printf("[%03d]", *ptr); *ptr = strlen(frase); printf("[%c]", outra[i]); printf("[%3d]", dif(8, 25)); outra[1] = '#'; printf("[%-8.4s]", outra); }

Linguagem C

44

Prof. Marcos Jos Brusso

45) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado (_):

#include <stdio.h> #include <ctype.h> #include <string.h> struct produto{ int codigo; char nome[30]; float preco; }; void main(void) { struct produto reg={10,"Caneta", 2.5}; char c, teste[30]="abc"; int v=2, i; printf("[%-5d]", --v); c = reg.nome[v]; v = (islower(c)) ? strlen(teste) : sizeof(teste); printf("[%d]", v); reg.preco += v; printf("[%10.3f]", reg.preco); strcpy(teste, reg.nome); printf("[%10.3s]", teste); for(i=0,v=1; teste[i]!='\0'; i++) if(teste[i]=='a') v++; printf("[%-4d]", v); }

Linguagem C

45

Prof. Marcos Jos Brusso

46) Mostrar ao lado de cada chamada funo printf o que ser exibido na execuo do programa. Substituir espaos em branco por sublinhado (_):

#include <stdio.h> #include <string.h> struct pessoa{ char nome[40]; int idade; float peso; }; void main(void) { struct pessoa reg={"Fulano", 20, 60.5}; int var=0; int *p; char c; char linha[40]="Beltrano"; p = &var; var=strlen(reg.nome); printf("[%d]", var++); var/=2; c = reg.nome[var]; printf("[%c]", c); *p=(strcmp(linha,reg.nome)!=0)? sizeof(linha) : strlen(linha); printf("[%-6d]", --var); reg.peso += *p; printf("[%7.2f]", reg.peso); for(var=0; linha[var]!='\0'; var++) reg.idade = reg.idade - 1; printf("[%04d]", reg.idade); }
47) Escrever uma funco int ultimodomes(struct data *dt) que retorna qual o ultimo dia do mes em que se encontra a data passada por parmetro. struct data teste={15, 4, 1999}; int ult; ult = ultimodomes(&teste); /*ult recebe 30 */

48) Escrever uma funcao void datecpy(struct data *dt1, struct data dt2), que atribui o contedo de dt2 para dt1. struct data da={1,5,1999}, db={15,8,1980}; datecpy(&da, &db); /* copia db para da */

49) Escrever um programa que recebe o nome de 2 arquivos como argumento de linha de comando. O programa deve criar o segundo arquivo e gravar nele todos os caracteres do primeiro que forem letras ou nmeros e no final, mostrar na sada padro quantos caracteres foram copiados. Qualquer mensagem de advertencia ao usurio (nmero invlido de argumentos, no pode abrir o arquivo, etc...) deve ser exibida na sada de erros.

c:\> copialn aula.txt aula.ltr Foram copiados 71 caracteres

Linguagem C

46

Prof. Marcos Jos Brusso

50) Escrever um programa que recebe o nome de dois arquivos como argumento na linha de comando (origem e destino) e copia o contedo do primeiro arquivo para o segundo, eliminando os espaos em branco. O programa somente deve aceitar um nmero vlido de argumentos.

c:\> copiasem

aula.txt limpo.txt

51) Escrever um programa que recebe o nome de um arquivo como argumento na linha de comando, e conta e exibe quantos caracteres o arquivo contm, quantos so espaos, quantos so letras, quantos so nmeros e quantos so outro tipo de caracter. O programa somente deve aceitar um nmero vlido de argumentos.

c:\> conta teste.txt teste.txt possui 110 caracteres, sendo 10 espaos, 55 letras, 15 nmeros e 30 outros caracteres.
52) Escrever um programa que recebe o nome de um arquivo texto como argumento na linha de comando e conta quantas linhas o arquivo contm. O programa somente deve aceitar um nmero vlido de argumentos.

c:\> conta teste.txt teste.txt possui 15 linhas


53) Escrever um programa que recebe o nome de um arquivo como argumento na linha de comando, e exibe o contedo do arquivo convertendo todas as letras para maisculas. O programa somente deve aceitar um nmero vlido de argumentos. 54) Escrever um programa que recebe o nome de 2 arquivos texto pela linha de comando e copia o contedo do primeiro arquivo para o segundo convertendo todas as letras maisculas para minsculas e as minsculas para maisculas.

C:\> COPIAMM arq1.txt arq2.txt


55) Escrever um programa que recebe o nome de um arquivo texto como argumento de linha de comando e exibe o seu contedo no seguinte formato: o caracter e seu codigo ASCII em hexadecimal, um caracter por linha. Validar o nmero de argumentos passados. 56) Escrever um programa que receba o nome de um arquivo texto como argumento de linha de comando e, lendo o seu contedo, conta e exibe o nmero de linhas que o arquivo contm. Qualquer mensagem de advertncia ao usurio (parmetros invlidos ou no pode abrir o arquivo) deve ser exibida na sada padro de erros. C:\> contalin teste.txt

teste.txt possui 19 linhas.


57) Escrever um programa que recebe o nome de 2 arquivos como argumento de linha de comando. O programa deve criar o segundo arquivo e gravar nele todos os caracteres do primeiro que forem letras e no final, mostrar na sada padro quantos caracteres foram copiados. Qualquer mensagem de advertencia ao usurio (nmero invlido de argumentos, no pode abrir o arquivo, etc...) deve ser exibida na sada de erros.

c:\> copialetras aula.txt aula.ltr Foram copiados 71 letras