A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

LINGUAGEM C Centro Federal de Educação Tecnológica da Paraíba Coordenação de Informática Professor: Lafayette B. Melo.

Apresentações semelhantes


Apresentação em tema: "LINGUAGEM C Centro Federal de Educação Tecnológica da Paraíba Coordenação de Informática Professor: Lafayette B. Melo."— Transcrição da apresentação:

1 LINGUAGEM C Centro Federal de Educação Tecnológica da Paraíba Coordenação de Informática Professor: Lafayette B. Melo

2 Tópicos 1. Introdução à Linguagem C 2. Operadores e Expressões
3. Estruturas de Controle 4. Entrada e Saída 5. Vetores 6. Strings 7. Funções 8. Ponteiros 9. Estruturas e Uniões 10. Arquivos Texto 11. Arquivos Binários

3 “Programas em C são feitos para que outras pessoas não possam entendê-los e para que depois de muito tempo nem o próprio programador os entenda.” (?) “Programas em C posssuem liberdade, elegância e consistência.” (Herbert Schildt)

4 1. Introdução à Linguagem C
Origens de C, características e uso A linguagem C foi implementada por Dennis Ritchie em um PDP-11 que usava UNIX Martin Richards criou a BCPL. A BCPL influenciou a criação da linguagem B de Ken Thompson, o que levou a C nos anos setenta Se popularizou com os PC’s, mas houve a necessidade da criação de um Padrão (ANSI) Com o Turbo C foram estabelecidas 3 metas: padrão ANSI completo, rapidez e eficiência e ambiente integrado

5 1. Introdução à Linguagem C
C é uma linguagem de alto nível com recursos de baixo nível Alto nível: Ada, Modula2, Pascal, Cobol, Fortran, Basic Nível Médio: C Baixo Nível: Assembly Cé portátil: pode adaptar em um computador softwares utilizados em computadores diferentes Erros em tempo de execução são pouco verificados Manipula bits, bytes e endereços

6 1. Introdução à Linguagem C
C é estruturada: uma linguagem estruturada é aquela que permite declarar sub-rotinas dentro de sub-rotinas - C faz isso? Outra característica para linguagem estruturada: compartimentalização de código e dados Estruturadas: Pascal, Ada, C, Modula2 Não-estruturada: Fortran, Basic, Cobol C e Assembly: Capacidade de manipular com bits e bytes permite substituir Assembly em parte

7 1. Introdução à Linguagem C
A linguagem do programador Toda linguagem não é para programador? C foi feita para dar confiabilidade ao código ou aumentar a velocidade do código C possui poucas restrições, tem rapidez e eficiência Uso de C: para sistemas operacionais, interpretadores, SGBD’s, editores, compiladores

8 1. Introdução à Linguagem C
Compiladores X Interpretadores Interpretadores lê o código fonte uma linha de cada vez e efetua as instruções está presente sempre que você roda o programa precisa ser sempre traduzido Compiladores lê todo o programa e depois o converte em código objeto converte o programa em código objeto tem o custo de uma única transformação “Tempos de compilação longos contribuem para providências curtas”

9 1. Introdução à Linguagem C
Um programa C compilado usa 4 regiões: Pilha Heap Variáveis Globais Código O compilador compila --- liga as funções da biblioteca necessárias --- e roda o programa. No processo de compilação podem surgir erros e advertências

10 1. Introdução à Linguagem C
Visão geral de programas em C Um programa em C tem uma ou mais funções Formato: Exemplo: tipo nome_da_função(lista_de_argumentos) { código; } main() { printf(“primeiro programa!”); }

11 1. Introdução à Linguagem C
As funções printf e scanf São funções de entrada/saída Não fazem parte da definição de c Formato: Exemplo: printf(“expressão de controle”,argumentos) main() { printf(“Este e um numero par: %d”,2); }

12 1. Introdução à Linguagem C
Exemplo: main() { int dias; float anos; /* entrada de dados*/ printf(“Entre com o numero de dias: “); scanf (“%d”, &dias); anos = dias/365.25; printf (“\n\n%d dias sao %f anos. \n”,dias,anos); return(0); }

13 1. Introdução à Linguagem C
Uso de funções Exemplo: sqr(x) int x; { printf (“%d ao quadrado e %d\n”,num,num*num); } main() int num; printf (“Digite um numero: ”); scanf (“%d”,&num); sqr (num);

14 1. Introdução à Linguagem C
Tipos de variáveis Códigos de controle Tipo Bits Bytes Escala char 8 1 -128 a 127 int 16 2 a 32767 float 32 4 3.4E-38 a 3.4E+38 double 64 1.7E-308 a 1.7E+308 void sem valor Código O que é %d Inteiro %f Float %c Caractere %s String %% %

15 1. Introdução à Linguagem C
Outros exemplos: (Qual é a saída de cada um?) printf (“teste %% %%”) printf (“%f”,40.345) printf (“um caractere %d e um inteiro %d”,’D’,120) printf (“%s e um exemplo”,”Este”) printf (“%s%d%%”,”Juros de “,10)

16 1. Introdução à Linguagem C
Exemplo: (Qual é a saída?) main() { int evento=5; char corrida=‘C’; float tempo=27.25; printf (“o tempo na etapa %c”,corrida); printf (“\nda competicao %d foi %f.”,evento,tempo); }

17 1. Introdução à Linguagem C
Uso de varíáveis com ponto flutuante Os números de ponto flutuante são os reais Há várias maneiras de eles serem escritos São guardados na memória em duas partes Uso de caracteres e strings Um caractere em c pode ser representado de várias formas Exemplos: 3 bytes 1 byte + .12345 5 sinal Fração/mantissa Expoente printf (“%d %c %x %o \n”,’A’,’A’,’A’,’A’);

18 Programa multiplica mul(a,b) /* parâmetros dentro dos parênteses */
int a,b; { printf (“ %d ”,a*b); } main() mul (10,11); < > TÓPICOS SAIR

19 Condições Loop if (a < b) printf (“a e menor do que b”);
if (a == b) printf (“Ei, os dois valores são iguais!”); Loop main() { int cont; for (cont=1;cont<=100;cont++) printf (“%d “,cont); } < > TÓPICOS SAIR

20 Blocos de código if (x < 10) {
printf (“muito baixo, tente de novo”); scanf (“%d”,&x); } < > TÓPICOS SAIR

21 Programa Mostra Caracteres
main() { char ch; ch = ‘A’; printf (“%c”,ch); ch = ‘B’; ch = ‘C’; } < > TÓPICOS SAIR

22 Programa Mostra String
main() { char str[80]; printf (“digite seu nome: ”); gets (str); printf (“ola %s!”,str); } Programa Saída printf (“%s %d”,”isto e uma string”,100); printf (“isto e uma string %d”,100); printf (“numero %d e decimal, %f e float.”,10, ); printf (“%c %s %d-%x”,’um’,” numero em decimal e hex: “,10,10); printf (“%s”,”ALO\n”); < > TÓPICOS SAIR

23 Expressões “Os operadores manipulam variáveis e constantes para formar expressões.” Identificadores Nomes utilizados para se fazer referência a variáveis, funções, rótulos e outros objetos Regras de formação: Os primeiros caracteres com letras ou sublinhados Os subsequentes com letras, números, sublinhados ou $. Ex.: cont, test23, alt_balanco Os 32 primeiros caracteres são significativos

24 Letras maiúsculas e minúsculas tratadas de forma diferente
Não pode ser igual a uma palavra reservada e não deve ser igual a uma função da biblioteca Tipos: TIPO EXTENSÃO ESCALA char a 255 int a 32767 float E-38 a 3.4E+38 double E-308 a 1.7E+308 void 0 sem valor Modificadores: alteram os tipos base de forma que se adequem a uma situação específica. São eles: signed, unsigned, long e short

25 Observações quanto aos modificadores:
todos eles são aplicados a char e int, long pode ser aplicado a double signed com inteiro é redundante inteiro com sinal significa que tem um sinalizador no bit de ordem superior. Ex.: 127 é e é a maioria dos computadores representará números negativos e, complemento de 2. Ex.: -127 como o número inteiro se fosse declarado como unsigned int seria 65535

26 TIPO EXTENSÃO ESCALA char a 127 unsigned char a 255 signed char a 127 int a 32767 unsigned int a 65535 signed int a 32767 short int a 32767 unsigned short int a 65535 signed short int a 32767 long int a signed long int a unsigned long int a float E-38 a 3.4E+38 double E-308 a 1.7E+308 long double E-308 a 1.7E+308

27 Este programa mostra a diferença de um inteiro com sinal e de um inteiro sem sinal
main() { int i; /*inteiro com sinal*/ unsigned int j;/*inteiro sem sinal*/ j = 60000; i =j; printf (“%d %u”,i,j); }

28 Podem ser utilizadas variáveis char que não sirvam apenas para conter os valores do conjunto de caracteres ASCII. Ex.: main() { int i, j, k; char c, d, e; long tm; tm = time(0); for (i=0;i<100;i++) for (j=0;j<100;j++) for (k=0;k<100;k++); printf(“tempo para inteiros: %ld\n”,time(0)-tm); for (c=0;c<100;c++) for (d=0;d<100;d++) for (e=0;e<100;e++); printf(“tempo para caracteres: %ld\n”,time(0)-tm); }

29 Variáveis Constantes declaração: tipo lista_variáveis Ex.: int cont;
Regras de escopo: 1) fora de todas as funções; 2) dentro de uma função; 3) na declaração de parâmetros formais; 4) em um bloco condicional Constantes valores fixos as constantes de caracteres são entre aspas simples: ‘a’ e ‘%’ constantes numéricas: 10 e -100

30 Regras de escopo (exemplo):
int soma; /* variável global */ main() { int cont; /* variável local */ soma = 0; for (cont=0;cont<10;cont++) { total(cont); mostra(); } } mostra() total(x) { int x; int conte; /* local */ { for(cont=0;cont<10;cont++) soma = x + soma; printf(“-”); } printf(“a soma e %d\n”,soma);

31 Constantes de ponto flutuante exigem ponto decimal seguido do componente fracionário
Podem ter vários exemplos combinados Constantes hexa: int hex=0xFF /*255 decimal*/ Constantes octais: int oct=011 /*9 decimal*/ Constantes de strings: conjunto de caracteres entre aspas. Ex. “lafa”, “a” # ’a’ Constantes com barras invertidas: Ex.: ch=‘\t’ Algumas constantes: \b-retrocesso, \f-alimentação de formulário, \n-nova linha, \r-retorno, \t-tab, \”-aspas, \’-aspas, \0-zero, \\-barra, \v-tab, \a-alerta, \oN-octal, \x-hexa

32 Operadores símbolo que manda o computador executar manipulações matemáticas ou lógicas Categorias: aritméticos, de relação e lógicos e bit a bit, além dos operadores especiais O que veremos: aritméticos, de relação e lógicos e de atribuição Aritmétcos: + - * / % O menos unário também é considerado operador -- e ++ Ex.: x++ e ++x, x-- e --x Há uma diferença entre: x=10 ; x=10; y=++x; e y=x++; Precedência: */% +-

33 De relação e lógicos: de relação-mostra as relações que os valores devem ter uns com os outros. Lógicos-mostram a maneira como as relações podem ser concatenadas Relação: V- é qualquer valor não zero, F- um valor zero > >= < <= == != Lógicos: obedecem à tabela verdade && (AND) !! (OR) ! (NOT) p q p AND q p OR q NOT p 10 > 5 && !(10 > 9) || 3<= 4 é V ou F? 1 && !(0 || 1) é V ou F?

34 Programa com operadores de relação
main() { int i, j; printf (“digite dois numeros: “); scanf (“%d%d,&i,&j); printf (“%d == %d e %d\n”,i,j,i==j); printf (“%d != %d e %d\n”,i,j,i!=j); printf (“%d <= %d e %d\n”,i,j,i<=j); printf (“%d >= %d e %d\n”,i,j,i>=j); printf (“%d < %d e %d\n”,i,j,i<j); printf (“%d > %d e %d\n”,i,j,i>j); }

35 Programa com operadores lógicos
main() { int i, j; printf (“digite dois numeros, 0 ou 1: “); scanf (“%d%d,&i,&j); printf (“%d AND %d e %d\n”,i,j,i && j); printf (“%d OR %d e %d\n”,i,j,i || j); printf (“NOT %d e %d\n”,i,!i); } Outro exemplo com operadores relacionais e lógicos main() { int i; for (i=1;i<100;i++) if (!i%2) printf (“%d “,i); }

36 De atribuição: = é permitido que seja utilizado com outros operadores x+=10; é o mesmo que x=x+10 posso usar operadores múltiplos: x=y=z=0; posso usar condicional: y = x > 9 ? 100 : 200; Exemplo: main() { int x, y, produto; printf(“digite dois numeros: “); scanf (“%d%d”,&x,&y); if ((produto=x*y) < 0) printf (“produto negativo\n”); }

37 Expressões combinam operadores, constantes e variáveis
seguem as regras de álgebra quando são misturados tipos diferentes em uma expressão, C converte de acordo com as regras char e short int ficam int, float fica double, se um valor é long double o outro fica long double se um valor é double o outro fica double se um valor é long o outro fica long se um valor é unsigned o outro fica unsigned Forçando uma expressão a ser de um tipo (casts): Ex. (float) x/2; Formato: (tipo) exp Pode e devem ser usados espaçamentos e parênteses

38 Comandos de Controle O que são IF
Os comandos de Controle de Fluxo são utilizados para definir o fluxo de execução do programa Podem ser agrupados nos comandos if, switch, while, for, do-while e goto IF Sintaxe: if (condição) comando; else comando; Apenas um dos comandos, o associado ao if ou o associado ao else será executado

39 Programa com if - número mágico
main() { int magico,adivinha; randomize(); magico = random (100); printf (“Adivinhe o numero!”); scanf (“%d”,&adivinha); if (adivinha == magico) printf (“Ok, voce acertou!”); else printf (“Voce errou!!”); } If aninhado: if objeto de um else ou de outro if if (x) if (x) { if (y) printf (“ola!”); if (y) printf (“ola”); else printf (“oi!”); } else printf (“oi”!);

40 Modificação de número mágico
Escada if-else-if: if (condição) comando; else if (condição) else if (condição) ... Modificação de número mágico if (adivinha == magico) { printf (“Ok, voce acertou!\n”); printf (“%d e o numero magico\n”); } else if (adivinha > magico) printf (“valor alto!\n”); else printf (“valor baixo!\n”);

41 Divisão do primeiro pelo segundo número
Expressões Condicionais: em C o fato de não se utilizar nas condições do If apenas operadores lógicos ou de atribuiçao pode se resultar em ganho Divisão do primeiro pelo segundo número main() { int a, b; printf (“digite dois numeros: “); scanf (“%d%d”,&a,&b); if (b) printf (“%d\n”,a/b); else printf (“não divido por zero\n”); }

42 SWITCH - substitui a escada if-else-if
O computador testa uma variável sucessivamente contra uma lista de valores. Sintaxe: switch (variável) { case constante1 : sequência de comandos break; case constante2: ... default: } Switch e if: só testa igualdades e expressões condicionais, if pode ser de qualquer tipo. Não pode haver 2 constantes case com valores iguais no mesmo switch. Ex. de switch de menus:

43 char ch; printf (“1. Verificar erros \n“); printf (“2. Corrigir erros \n“); printf (“3. Exibir erros \n“); printf (“4. Outra opção \n“); ch = getchar(); switch (ch) { case ‘1’: verficar(); break; case ‘2’: corrigir(); case ‘3’: exibir(); default: printf(“nenhuma opção escolhida”); }

44 Programa de saída int t; for (t=0;t<10;t++) switch (t) { case 1:
printf (“Agora”); break; case 2: printf (“é”); case 3: case 4: printf (“hora “); printf (“ de dar tchau \n”); case 5: case 6: printf (“vamos... “); case 7: case 8: case 9: printf (“-”); };

45 Programa de switch aninhado
switch (x) { case 1: switch (y) { case 0: printf(“erro na divisão”); break; processa (x,y); } case 2: ... Loops - permitem que o computador repita um conjunto de instruções até que alcance uma certa condição FOR - faz o incremento um número determinado de vezes e de acordo com determinadas condições. Sintaxe:

46 Exemplo simples Exemplo de decremento
for (inicialização; condição; incremento) comando Exemplo simples main() { int x; for (x=1;x<=100;x++) printf (“%d “,x); } Exemplo de decremento main() { int x; for (x=100;x>0;x--) printf (“%s “,x); }

47 Cuidado com a condição falsa !!!
Exemplo de atribuição main() { int x; for (x=0;x<=100;x=x+5) printf (“%d “,x); } Cuidado com a condição falsa !!! x=10; for (y=10;y!=x;++y) printf (“%d”,y); printf (“%d”,y); Variação com duas variáveis de controle main() { int x,y; for (x=0,y=0;x+y<100;++x,y++) printf (“%d “,x+y); }

48 Variação com condições como expressões válidas em c
main() { int i, j, resposta; char feito = ‘ ‘; for (i=1;i<100 && feito != ‘N’;i++) { for (j=1;j<10;j++) { printf (“quanto e %d + %d? “,i,j); scanf (“%d”,&resposta); if (resposta != i+j) printf (“Errado\n”); else printf (“Certo \n”); } printf(“mais? “); feito = getche();

49 Variação de expressões válidas em c em qualquer lugar do for
main() { int t; for (prompt();t=readnum();prompt()) sqrnum(t); } prompt() printf (“digite um inteiro: “); readnum() scanf(“%d”,&t); return t; sqrnum(num) int num; printf(“%d\n”,num*num);

50 For sem todas as expressões
for (x=0;x!=123;) Loop infinito for (;;) printf (“este loop rodará para sempre\n); Saindo de um Loop for (;;) { ch = getche(); if (ch == ‘A’) break; } printf (“voce digitou um A”); Loop sem corpo (retardo) for (t=0;t < ALGUM_VALOR;t++)

51 WHILE - enquanto uma condição ocorre repete. Sintaxe:
Exemplo simples espera_por_char() { char ch; ch = ‘\0’; while (ch != ‘A’) ch =getche() } while (condição) comando; Condições separadas-1 variável como expressão condicional funcao1() { int trab; trab = 1; while (trab) { trab = process1(); if (trab) trab = process2(); trab = process3(); }

52 Exemplo simples main() { char str[255];
printf(“digite uma sequencia: “); gets (str); center (strlen(str)); printf(str); } center(len) int len; len = (80 - len)/2; while (len>0) { printf(“ “); len--;

53 DO-WHILE - repete algo enquanto uma condição ocorre. Sintaxe:
comando; } while (condição); Exemplo simples main() { int num; do { scanf (“%d”,&num); } while (num < 100); O do-while é muito usado para rotina seleção de menu!!!

54 Programa - número mágico outra versão
main() { int magico,adivinha, tentativas=0; randomize(); magico = random (100); do { printf(“adivinhe: “); scanf (“%d”,&adivinha); if (adivinha == magico) { printf (“** acretou **”); printf (“%d e o numero magico\n”,magico); } else if (adivinha> magico) printf (“valor alto”); else printf (“valor baixo”); tentativas++; } while (adivinha != magico); printf (“voce tentou %d vezes\n”,tentativas);

55 Loops aninhados - exemplo das 4 potências de 1 a 9
main() { int i, j, k, temp; printf (“ i i^2 i^3 i^4 i^5\n”); for (i=1;i<10;i++) { for (j=1;j<5;j++) { temp = 1; for (k=0;k<j;k++) temp=temp*i; printf (“%9d”,temp); } printf(“/n”);

56 Uso de break e continue Uso de rótulos e goto int t;
for (t=0;t<100;t++) { printf (“%d “,t); if (t==10) break; } int x; for (x=0;x<100;x++) { if (x%2) continue; printf (“%d “,x); } Uso de rótulos e goto

57 Matrizes unidimensionais
Matrizes e Strings O que são Matrizes: conjunto de variáveis de mesmo tipo, referenciadas pelo mesmo nome. Em C, matrizes são locações contíguas de memória. Podem ter uma ou mais dimensões. Strings: conjunto de caracteres. Em C, não há o tipo string, então são usadas matrizes de caracteres Matrizes unidimensionais Sintaxe: tipo nome_var [tamanho]; Em C, todas as matrizes usam zero como índice do primeiro elemento

58 Exemplo programa matriz simples
main() { int x[10]; /* reserva 10 espaços de memória */ int t; for (t=0;t<0;++t) x[t]=t; } Cálculo do tamanho de uma matriz total_em_bytes = sizeof(tipo)*comprimento Matrizes permitem lidar com muitas variáveis relacionadas

59 Exemplo trabalho com várias variáveis - média de dez
main() { int amostra[10], i, med; for (i=0;i<0;i++) { printf(“digite numero %d: “,i); scanf (“%d”,&amostra[i]); } med=0; for (i=0;i<10;i++)med=med+amostra[i]; printf (“A media e %d\n”,med/10); Verificação de limites: C não faz verificação de limites. Por que? Veja a loucura!

60 Exemplo atribuindo valores além do limite da matriz
main() { int erro[10], i; for (i=0;i<100;i++) erro[i]=1; } Matrizes são listas Exemplo matrizes são listas main() { int i; for (i=0;i<7;i++) ch[i]=‘A’ + i; } ch[0] ch[1] ch[2] ch[3] ch[4] ch[5] ch[6] A B C D E F G E daí ?

61 Lendo strings pelo teclado
Uso comum das matrizes unidimensionais Em C, uma string pode ser entendida como uma matriz de caracteres terminada em zero O zero é ‘/0’ Em uma constante de strings não é preciso se preocupar com o zero. Ex.: “Lafayette”. Como fica “Hora de dar tchau” internamente? Lendo strings pelo teclado Forma usual de ler uma string: função gets(). Sintaxe: gets (nome_matriz)

62 E se a string for maior do que a variável?
Exemplo lendo a string main() { char str[80]; printf(“Digite seu nome:/n”); gets (str); printf(“Ola, %s!”,str); } Funções de String: strcpy(), strcat(), strcmp(), strlen() Função strcpy - Sintaxe: strcpy(destino,origem) Exemplo strcpy main() { char str[80]; strcpy(str,”hora de dar tchau”) } E se a string for maior do que a variável?

63 Exemplo strcat Função strcat - Sintaxe: strcat(string1,string2) main()
{ char primeiro[20], segundo[10]; strcpy(primeiro,”hora de dar “); strccpy(segundo,”tchau”); strcat(primeiro,segundo); printf(“Agora e %s.”,primeiro); } Função strcmp - Sintaxe:strcmp(string1,string2) Retorna 0 se as strings são iguais, um número positivo se string1 for maior do que string2 e um número negativo se string1 for menor do que string2

64 Exemplo strcmp - senha senha() { char s[80];
printf (“digite a senha: “); gets(s); if (strcmp(s,”hora de dar tchau”)) { printf (“senha inválida\n”); return 0; } return 1; Se quiser que algo ocorra o que fazer? main() { char s[80]; for (;;) { printf(“: “); gets(s); if (!strcmp(“sair”,s)) break; }

65 Exemplo imprimir de trás pra frente
Função strlen - Sintaxe: strlen(string). Retorna comprimento. Exemplo strcat main() { char str[80]; printf(“digite um nome: “); gets(str); printf(“%d”,strlen(str)); } Exemplo imprimir de trás pra frente main() { char str[80]; int i; gets (str); for (i=strlen(str)-1;i>=0;i--) printf (“%c”,str[i]); }

66 Exemplo terminador zero string em maiúsculas
Exemplo todas main() { char s1[80], s2[80]; gets (s1); gets (s2); printf(“comprimentos:%d e %d\n”,strlen(s1),strlen(s2)); if (!strcmp(s1,s2)) printf(“as strings são iguais\n”); strcat(s1,s2); printf (“%s\n”,s1); } O terminador zero pode ter uso interessante!! Exemplo terminador zero string em maiúsculas main() { char str[80]; int i; strcpy(str,”hora de dar tchau”); for (i=0;str[i];i++) str[i]=toupper(str[i]); printf(“%s”,str); }

67 Exemplo outro modo dever o printf
Variações de printf() Formato básico: printf(“%s”,nome_matriz) Posso usar apenas printf(nome_matriz)? Exemplo outro modo dever o printf main() { char str[80]; strcpy(str,”Lafayette”); printf (str); } Matrizes bidimensionais Forma mais simples da matriz multidimensional Exemplo de declaração: int bidm[10][20]

68 Exemplo matrizes bidimensionais
main() { int t, i; num[3][4]; for (t=0;t<3;++t) for(i=0;i<4;++i) num[t][i]=(t*4) + i +1; } Cálculo do tamanho de uma matriz bytes = linhas*colunas*sizeof(tipo) Matrizes de strings - uso comum. Para criar uma matriz de strings, é utilizada uma matriz bidimensional de caracteres. Índice esquerdo = número de strings. Índice direito = comprimento máximo de cada string

69 Exemplo matriz de string
Acesso a uma matriz particular - Exemplo: gets (matriz_str[2]) = gets (&matriz_str[2][0]); Exemplo matriz de string main() { register int t, i, j; char texto[100][80]; for (t=0;t<100;t++){ printf (“%d: “,t); gets(texto[t]); if (!*texto[t]) break; } for (i=0;i<t;i++) printf (“%s\n”,texto[i]);

70 Ponteiros O que são Razões de uso dos ponteiros:
1) fornecem maneiras pelas quais podemos mudar argumentos de funções; 2) rotinas de alocação dinâmica; 3) substituição por matrizes Perigos: uso de ponteiros não inicializados ou perdidos e facilidade para seu uso incorretamente O que são Ponteiros são variáveis que contêm um endereço de memória - “uma variável aponta para a outra” Sintaxe: tipo *nome_var; Note que o tipo diz o tipo de variável que o ponteiro pode apontar

71 Endereço de memória Variável na memória
Exemplos: char *p; int *temp, *inicio; Endereço de memória Variável na memória Operadores de ponteiros & - end. de memória do operando * - conteúdo Ex.: end_cont = &cont; leia-se “end_cont recebe o endereço de cont” val = *end_cont; leia-se “val recebe o valor do endereço end_cont”

72 Exemplo ponteiro imprime
Ex.: val = *end_cont; leia-se “val recebe o valor do endereço end_cont” Exemplo ponteiro imprime main() { int *end_cont, cont, val; cont = 100; end_cont = &cont; val = *end_cont; printf (“%d”,val); } Uso do tipo: Atribuimos valores indiretos, mas como sabemos que o compilador transfere o número adequado de bytes para qualquer atribuição que use ponteiro? Você deve assegurar que suas variáveis com ponteiros sempre apontem para o tipo correto de dados

73 Exemplo apontador tipo errado
main() { float x = 10.1, y; int *p; p = &x; y = *p; printf(“%f”,y); } Expressões com ponteiros Atribuições com ponteiros Exemplo atribuição de ponteiros main() { int x; int *p1, *p2; p1 = &x; p2 = p1; printf (“ %p”,p2); } %p mostra endereço de ponteiro

74 Supondo ocuparem o endereço 3000: ch 3000 i ch+1 3001 ch+2 3002 i+1
Aritmética de ponteiros: uso das operações + e - Supondo p1 ponteiro para inteiro com valor 2000: p1++; faz com que p1 seja 2002 se fosse p1--; faria com que p1 tivesse o valor 1998 A aritmética de ponteiros funciona para tipos base diferentes char *ch; int *i; Supondo ocuparem o endereço 3000: ch i ch ch i+1 ch ch i+2 Massa! Você também pode adicionar ou subtrair valores inteiros a ponteiros. Veja o efeito: p1 = p1 + 9 /*p1 apontará para o nono elemento do seu tipo base */

75 Exemplo relacionamento entre ponteiros e matrizes
Comparações de ponteiros: if (p<q) printf (“p aponta para uma posição inferior\n”); Uso: quando 2 ponteiro apontam para um mesmo objeto Exemplo de dump: os ponteiros podem ser usados para o exame do conteúdo de memória Ponteiros e matrizes No programa abaixo entenda que o nome de uma matriz sem índice é o endereço do início da matriz Exemplo relacionamento entre ponteiros e matrizes char str[80], *p; char *p1; p1 = str; posso colocar str[4] ou *(p1+4); A aritmética de ponteiros pode ser mais rápida do que a indexação de matrizes!!!

76 Exemplo indexação com matrizes
main() { char str[80]; int i; printf(“digite uma string em minúsculas: “); gets (str); printf (“transformei para: ); for (i=0;str[i];i++) printf (“%c”,tolower(str[i]); } Exemplo acesso com ponteiros main() { char str[80], *p; printf(“digite uma string em minúsculas: “); gets (str); printf (“transformei para: ); p = str; while (*p) printf (“%c”,tolower(*p++)) } Acesso aleatório é melhor a indexação

77 Exemplo indexação de ponteiros
Indexando um ponteiro - pode se indexar um ponteiro como se ele fosse uma matriz Exemplo indexação de ponteiros main() { int i[5]={1,2,3,4,5} int *p, t; p = i; for (t=0;t<5;t++) printf(“%d”,p[t]); } Em C, o comando p[t] é o mesmo que *(p+t) Exemplo de pilha: uma pilha é uma lista “primeiro a entrar é o último a sair” é usada uma rotina para colocar valores na pilha (push) e também para tirá-los (pop) é preciso conter um endereço de início de pilha (tos)

78 Exemplo pilha int pilha[50]; int *p1, *tos; main() { int valor;
p1 = pilha; tos = p1; do { scanf (“%d”,&valor); if (valor != 0) push (valor); else printf (“aqui esta %d\n”, pop()); } while (valor != 0); } push(i) int i; p1++; if (p1 == (tos+50)) { printf estouro”); exit(); *p1 = i; pop() { if (p1 == (tos)) { printf (“estouro”); exit(); } p1--; return *(p1+1);

79 Exemplo passagem de parâmetros
Ponteiros e strings: na passagem de parâmetros o computador passa um ponteiro para strings e não o valor da string Exemplo passagem de parâmetros strcmp() char *s1, *s2; { while (*s1) if (*s1-*s2) return *s1-*s2; else { s1++; s2++; } return ‘\0’; Mas e quando eu passo uma constante de uma string como parâmetro?

80 Exemplo constante de string
O computador trata a constante como se ela fosse um ponteiro para o primeiro caractere da string Exemplo constante de string main() { char *s; s = “oi, tudo bem?” printf(s); } Obter o endereço do elemento de uma matriz p = &x[2]; - útil na localização de substring Exemplo substring main() { char s[80], *p; int i; gets(s); for (i=0;s[i] && s[i] != ‘ ‘;i++); p = &s[i]; printf(p); }

81 Exemplo mensagens de erros
Matrizes de ponteiros: feita como com qualquer outro tipo. Exemplo: int *x[10]; Atribuir o endereço de uma variável inteira ao terceiro elemento: x[2] = &var; Achar o valor de var: *x[2] Uso comum: mensagem de erros Exemplo mensagens de erros char *err[]= { “não pode abrir arquivo\n”, “erro de leitura\n”, “erro de escrita\n”, “falha de dispositivo\n” }; serro(num) int num; { printf (“%s”,err[num]); }

82 Ponteiros para ponteiros
Matriz de ponteiros é o mesmo que ponteiros para ponteiros, o seu conceito é direto, mas o de ponteiros para ponteiros é mais complicado ponteiro (endereço) variável (valor) ponteiro (endereço) ponteiro (endereço) variável (valor) Declarando uma variável que é um ponteiro para um ponteiro. Ex.: float **novo; Exemplo ponteiro de ponteiro main() { int s, *p, **q; x = 10; p = &x; q = &p; printf (“%d”,**p); }

83 Exemplo ponteiro nulo Exemplo uso de string
Inicialização de ponteiros: se um ponteiro é declarado e não há uma atribuição, ele tem um valor desconhecido Ponteiro que não aponta para lugar algum deve ser dado um valor nulo Mas a segurança não é total Ponteiro nulo pode tornar as rotinas mais eficientes Exemplo ponteiro nulo for (t=0;p[t];++t) if (!strcmp(p[t],nome)) break; É comum inicializar strings com ponteiros. Ex.: char *p = “alo mundo\n”; - tabela de strings Exemplo uso de string char *p = “alo mundo”; main() { register int t; print(p); for (t=strlen(p)-1;t>-1;t--) printf(“%c”,p[t]); }

84 Exemplo erro ponteiro não inicializado
Problemas com ponteiros “ponteiros perdidos” o problema em si não é o ponteiro lendo / gravando em posições desconhecidas Há alguns erros que são comuns: Exemplo erro ponteiro não inicializado main() { int x, *p; x = 10; *p = x; } Exemplo erro ponteiro interpretação main() { int x, *p; x = 10; p = x; printf (“%d”,*p); }

85 Alocação dinâmica de memória
Existem 2 métodos através dos quais um programa em C pode armazenar informações na memória principal 1 - através de variáveis locais e globais 2 - através de funções de alocação dinâmica de memória: malloc() e free() - nesse método o programa aloca armazenamento para informações da área de memória livre (heap) Pilha ______ Memória livre para alocação ________________________ Variáveis globais _________________________ Programa

86 Função malloc() - aloca uma parte do restante de memória livre, serve para alocação de memória com finalidades gerais. Sintaxe: void *malloc (int número_de_bytes) retorna um ponteiro do tipo void que significa que deve ser usado um tipo cast quando atribuir o ponteiro devolvido por malloc() a um ponteiro desejado malloc() devolve um ponteiro para o primeiro byte da região de memória que foi alocada na área de alocação dinâmica se não houver memória suficiente, malloc devolve um tipo nulo pode usar sizeof Função free() - devolve ao sistema memória previamente alocada. Sintaxe: free (void *p); free nunca deve ser chamado com um argumento inválido, pois será destruída a lista livre

87 Exemplo uso de alocação dinâmica
main() { int *p, t; p = (int *)malloc(40*sizeof(int)); if (!p) printf (“memória insuficientes\n”); else { for (t=0;t<40;++t) *(p+t)=t; for (t=0;t<40;++t) printf(“%d “,*(p+t)); } Lembre-se: antes de usar o ponteiro que malloc devolve, assegura-se que o pedido foi bem sucedido testando o valor devolvido!!!!!

88 Funções em detalhes Funções são blocos de construção nos quais ocorrem todas as atividades dos programas As funções em maiores detalhes possuem formas de modificar argumentos, regras de escopo, tempo de vida de variáveis, recursividade especificidades da função main Sintaxe: especificador_tipo nome_função(lista_parâmetros) declarações de parâmetros { corpo }

89 A chamada é encerrada por “;”, mas a declaração não
Uma função simples main() { clrscr(); linha(); printf("\xDB UM PROGRAMA EM C \xDB\n"); getche(); } linha() int j; for(j=1;j<=20;j++) printf("\xDB"); printf("\n"); A chamada é encerrada por “;”, mas a declaração não

90 Variáveis locais: declaradas dentro de uma função ou de um bloco (existem durante a execução desse bloco de código) Uso de variáveis locais func1() func2() { { int x; int x; x = 10; x = -199; } } Mais uso de variáveis locais f() { char ch; printf (“continua (s/n)? :”); ch = getche(); if (ch == ‘s’) { char s[80]; printf (“digite nome:”); gets(s); }

91 Funções que retornam um valor – são a maioria e têm como padrão o valor inteiro
main() { char ch; printf("digite 'a' e depois 'b': "); ch=minusculo(); switch(ch) { case 'a': printf("\n vc pressionou 'a'."); break; case 'b': printf("\n vc pressionou 'b'" ); default: printf("\n vc escolheu algo desconhecido."); } minusculo() { char ch; ch = getche(); if (ch >= 'A' && ch <= 'Z') ch+='a'-'A'; return(ch); } char s[80]; printf ("digite nome:"); gets(s); puts(s);

92 Comando return: faz com que haja uma saída da função e devolve valores
Retorno de uma função - A função retorna com uma chave (}) e com return. Usos: Devolver valor e retornar para a próxima instrução Causar uma saída imediata da função Só retorna um valor a cada chamada Exemplos de uso de return potência(base, exp) int base, exp; { int t; if (exp<0) return; /* expoente negativo não executa */ i = 1; for(;exp;exp--) i = base * i; printf (“a resposta é: %d: “,i); } minusculo() char ch; ch=getche(); if (ch >= ‘A’ && ch <= ‘Z’) return (ch + ‘a’ – ‘A’); else return(ch);

93 Passando valores por chamada – para passar dados para uma função, C usa argumentos e passagem por valores Exemplo passando constante main() { printf (“%d %d %d\n”, abs(0),abs(-3),abs(10)); } abs(x) int x; return((x < 0?-x:x); Exemplo passando argumentos int enpontos; while (1) { printf(“(0 para terminra) pontos = “); scanf(“%d”&enpontos); if (!enpontos) break; else bar(enpontos); bar(pontos) int pontos; { int j; for (j=1;j<=pontos;j++) printf(“\xCD”); printf(“\n”); }

94 Tipos de valores devolvidos:
Erro de uso de função swap (x,y) = 100; Tipos de valores devolvidos: Valores computacionais - devolve valores com base em uma operação. Ex.: sqrt() e sin() Valores que indicam sucesso na operação. Ex: fwrite() Valores não explícitos. Ex.: printf() Valores podem não ser atribuídos: Exemplo de valores não atribuídos mul (a,b) > no main: z = mul(x,y) int a, b; printf(“%d”,mul(x,y)); { mul(x,y) return a*b; } Regras de escopo: em c cada função é um bloco de código discreto. As variáveis podem ser locais, globais e parâmetros formais

95 Parâmetros formais: variáveis que assumem valores dos argumentos
Exemplo de uso de parâmetros formais esta_em(s,c) > alternativo esta_em(char*s, char c) char *s; char c; { while (*s) if (*s == c) return 1; else s++; return 0; } Variáveis globais: conhecidas em todo o programa e declaradas fora de qualquer função mesmo que não seja antes do main. Variáveis globais func1() func2() int cont; {int temp; {int cont; main() temp = cont; for(cont=1;cont<10;cont++) { cont = 100; func2(); printf(“.”); func1(); printf(“%d”,cont); } } }

96 Razões de se evitar as variáveis globais: ocupam espaço de memória
pouca generalização programação de erros alteração acidental Vantagem das variáveis globais: uso dos mesmos dados em várias funções no programa Ex. geral Ex. local mul(x,y) int x, y; int x, y; mul() { { return(x*y); return(x*y); } }

97 Argumentos de funções: parâmetros formais dos mesmos tipos dos argumentos, podem ser feitas atribuições aos parâmetros formais ou pode ser usada dentro de uma função, são usadas como outra variável local chamada por valor e por referência - em c é feita por valor chamada por referência - é simulada Exemplos main() troca(x,y){ { int t = 10; int *x, *y; printf (“%d %d”,sqr(t),t); temp = *x; } *x = *y; sqr(x) *y = temp; int x; } { chama: x = x*x; troca(&x,&y) return (x); }

98 Exemplo de funções com matrizes
chamando funções com matrizes - 3 formas: declarando o ponteiro como matriz Exemplo de funções com matrizes main() { int t[10], I; for(I=0;I<10;++I) t[I]=I; mostre(t); } mostre(num) int num[10]; int I; for (I=0;I<10;I++) printf(“%d “,num[I]); especificar o parâmetro como uma matriz sem tamanho Exemplo de matriz sem tamanho mostre() int num[]; { int I; for (I=0;I<10;I++) printf(“%d “,num[I]);}

99 Exemplo de matriz com ponteiro
especificar o parâmetro como um ponteiro Exemplo de matriz com ponteiro mostre() int *num; { int I; for (I=0;I<10;I++) printf(“%d “,num[I]);} especificar o elemento de uma matriz Exemplo de especificar elemento de uma matriz main() { int t[10], i; for (I=0;I<10;I++) t[I] = I; for (I=0;I<10;I++) mostre(t[I]); } mostre(num) int num; printf(“%d “,num);

100 Exemplo de uso de argc e argv
Argumentos argc e argv: argumentos de linha de comando. Argc e argv são os únicos argumentos aceitos por main. Argc - número de argumentos (int). No mínimo um. Argv - ponteiro para uma matriz de ponteiros para caracteres. Cada elemento na matriz aponta para um argumento da linha de comando Exemplo de uso de argc e argv main(argc,argv) int argc; char *argv[]; { if (argc != 2) { printf(“esqueceu o nome\n”); exit(0); } printf(“alo %s”,argv[1]);

101 Outro exemplo de uso de argc e argv
/* contagem regressiva */ main(argc,argv) int argc; char *argv[]; { int disp, cont; if (argc < 2) { printf(“faltou comprimento. Tente novamente.\n”); exit(0); } if (arg == 3 && !strcmp(argv[2],”display”)) disp = 1; else disp = 0; for(cont=atoi (argv[1];cont;--cont) if (disp) printf (“%d “,cont); printf(“%c”,7);

102 Exemplo caracteres individuais da linha de comando
Para se ter acesso a um caractere individual em uma das strings de comando acrescenta-se um segundo índice a argv. Exemplo caracteres individuais da linha de comando main(argc,argv) { int argc; char *argv[]; int t, I; for (t=0;t<argc;++t) { I=0; while (argv[t][I]) { printf (“%c”,argv[t][I]); ++I; } printf(“ “);

103 Exemplo funções não-inteiras
Funções que devolvem não inteiros - quando não é o valor default é necessário duas etapas: 1) dar à função um especificador de tipo explicito; 2) identificar o tipo da função antes de chamá-la pela primeira vez Exemplo funções não-inteiras float soma(); main() { float primeiro, segundo; primeiro = ; segundo = 99.09; printf(“%f”,soma(primeiro,segundo)); } float soma(a,b) float a,b; return a+b;

104 Exemplo protótipo Funções void - padrão do unix (nenhum valor)
Protótipos - funções que se pode declarar o número e o tipo de argumentos - para grandes programas ou quando muitos programadores trabalham em um projeto Exemplo protótipo float func(int, float) /* prototipo */ main() { int x, y; x = 10; y =10; func(x,y); /* não coincide tipos */ } float func(x,y) int x; float y; { printf(“%f”,y/float)x);

105 Lógica e lógica de programação
O que é a lógica Procedimentos utilizados para tirar conclusões de premissas e o estudo de tais procedimentos Uma idéia é classificada como lógica se ela puder a partir de pressupostos utilizados para raciocinar ser considerada uma conclusão apropriada Vantagens do estudo da lógica: Facilidades para apresentar e organizar as idéias Facilitar a análise das idéias apresentadas por outros “Se as idéias forem reduzidas ao seu essencial se terá mais facilidade para discordar e refutar as mesmas”

106 Lógica dedutiva e lógica indutiva
Na lógica dedutiva as conclusões são presumivelmente necessárias (se as premissas são verdadeiras então as conclusões também o são). Ex.: a soma de dois inteiros é um inteiro - a e b são inteiros - logo, a soma de a e b é um inteiro. Na lógica indutiva os argumentos são considerados prováveis, mas não necessários. Ex.: a galinha e o passarinho botam ovo - a galinha e o passarinho são ovíparos - logo, os ovíparos botam ovo. Fora da lógica formal existem os vários tipos de lógica: a lógica capitalista, a lógica marxista, a lógica da fome, a lógica da guerra, a lógica da engenharia, a lógica do direito, a lógica matemática, a lógica da programação etc.

107 Argumentações em lógica são utilizadas como um padrão da seguinte forma: duas premissas e uma conclusão A esta construção denominamos silogismo Verdade e validade dos silogismos (a lógica do dia-a-dia e a lógica formal) 1a construção: Todos os homens são mortais Sócrates é homem Logo, Sócrates é mortal 2a construção: Todos as mulheres têm voz fina Pessoas roucas não têm a voz fina Logo, não existem mulheres roucas

108 Consideração sobre a construção:
Todo X é Z Todo Y é Z Todo X é Y Todo mamífero é mortal Todo homem é mortal Todo mamífero é homem 3a construção: As pessoas que fazem muitos exercícios físicos são musculosas Alguns homens são musculosos Logo, alguns homens fazem muitos exercícios físicos

109 4a construção: Todos os peixes nadam Alguns mamíferos nadam Logo, alguns mamíferos são peixes A verdade de uma conclusão (correspondência ou não à verdade) é diferente da validade da conclusão A constatação da verdade, seja ela uma premissa ou uma conclusão depende da relação da afirmativa com a realidade e não com as outras afirmativas do argumento. A validade depende apenas da consideração dos elementos do argumento em que ela se encontra. Se a premissa leva a uma consideração ela é considerada válida.

110 Conclusões válidas e verdadeiras
Não verdadeira Verdadeira Todos os homens são mortais Sócrates é homem Logo, Sócrates é mortal Todos as mulheres têm voz fina Pessoas roucas não têm a voz fina Logo, não existem mulheres roucas Válida As pessoas que fazem muitos exercícios físicos são musculosas Alguns homens são musculosos Logo, alguns homens fazem muitos exercícios físicos Todos os peixes nadam Alguns mamíferos nadam Logo, alguns mamíferos são peixes Não é válida

111 Formas de regras de inferência da lógica dedutiva
Modus Ponens: Se estiver chovendo, Pedro voltará molhado. ( Se P então Q.) Está chovendo ( P ) Conclusão: Pedro voltará molhado. ( Q ) Modus Tollens: Pedro não voltará molhado. ( Não Q ) Conclusão: Não está chovendo. ( Não P ) Afirmação do Consequente: Pedro voltará molhado. ( Q ) Conclusão: Está chovendo. ( P )

112 Negação do Antecedente:
Se estiver chovendo, Pedro voltará molhado. ( Se P então Q.) Não está chovendo. ( Não P ) Conclusão: Pedro não voltará molhado. ( Não Q ) As pessoas costumam inferir por Modus Ponens, apesar de uma quantidade substancialmente menor tirar inferências por Modus Tollens. Afirmação do Consequente e Negação do Antecedente são consideradas inválidas.

113 Teoria das regras abstratas: diz que o raciocínio humano usa um conjunto de regras bastante abstratas e parecidas com as da lógica, as quais seriam aplicáveis a qualquer domínio de conhecimento Conclusões inválidas ocorrem por três na teoria: Erros de compreensão ocorrem quando as premissas ou conclusões não são bem construídas, de alguma maneira. Erros de inadequação da heurística ocorrem quando a conclusão do problema de raciocínio não é alcançada porque as estratégias para coordenar numerosos conjuntos de regras de raciocínio não se mostram apropriadas, provavelmente devido ao problema ser difícil por natureza. Erros de processamento podem resultar de lapsos de atenção, uma falha no armazenamento de informação relevante na memória de trabalho ou ainda deslizes na aplicação das regras.

114 Teoria das regras concretas: diz que os indivíduos são afetados pelo tipo de material (abstrato ou concreto) apresentado, o que não é previsto pelas teorias de regras abstratas Falácias lógicas Se constituem em maneiras inverídicas de se chegar a uma conclusão. São elas: Apelos emocionais Apelos à piedade Apelo popular Apelo à autoridade Argumento ad hominem Falsa causa Apelo à ignorância

115 Exemplos de define - número
Entrada e Saída Como ocorre em C Através do uso de bibliotecas Dois sistemas: o sistema de arquivo bufferizado (Ansi) e o sistema não-bufferizado (Unix) As funções do padrão Ansi não têm o sistema não-bufferizado, mas devem ser as mais usadas Comandos do pré-processador # define identificador string Exemplos de define - número #define verdadeiro 1 #define falso 0 ... printf(”%d %d %d”,falso,verdadeiro,verdadeiro+1)

116 Exemplos de define - parte de definição
#define um 1 #define dois um+um #define tres um+dois Exemplos de define - saída #define ms_e “erro padrao na entrada \n” ... printf(ms_e); Exemplos de define - em string #define xyz “isto e um teste\n” ... printf(xyz); Exemplos de define - tamanho de elementos #define tamanho_max 16 unsigned int pots_de_dois[tamanho_max]; main() { int i; pots_de_dois[0]=1; for (i=1; i<tamanho_max; i++) pots_de_dois[i]=pots_de_dois[i-1]*2; for (i=0; i<tamanho_max; i++) printf(“%u “,pots_de_dois[i]);

117 Exemplos de include - stdio
Comandos do pré-processador # include arquivo Exemplos de include - stdio #include <stdio.h> #include “stdio.h” Os arquivos colocados no include são chamados arquivos-cabeçalho (stdio.h ou io.h) fila de bytes = abstração entre o dispositivo e o programador dispositivo real = arquivo embora cada dispositivo seja diferente, o sistema de arquivo bufferizado transforma cada um em um dispositivo lógico chamado fila de bytes as funções que escrevem em um arquivo em disco podem também escrever no console fila de texto = sequência de caracteres organizada em linhas encerradas por \n

118 filas binárias = sequência de bytes que têm correspondência unívoca com os bytes do dispositivo externo Contudo, o computador pode usar bytes nulos para completar a informação para que seja preenchido o setor de um disco Arquivos É associada uma fila de bytes a um determinado arquivo realizando uma opção de abertura Todas as filas de bytes são iguais, mas nem todos os arquivos são iguais Na solicitação de posicionamento de arquivo a abertura do mesmo também inicializa o indicador de posição do arquivo para o início do arquivo. O indicador de posição é incrementado.

119 Para que um arquivo deixe de ser associado a uma fila de bytes é realizada uma opção de fechamento. Esse processo, chamado esvaziamento de buffer, garante que o computador fechará automaticamente os arquivos quando o programa terminar. E quando houver uma queda do sistema? Na execução de um programa, são abertas três filas de texto pré-definidas: stdin, stdout, sterr Cada fila de bytes associada a um arquivo tem uma estrutura de controle de arquivo do tipo FILE Para o programador, toda entrada e saída é feita através de filas de bytes

120 Entrada e saída do console
Operações que ocorrem no teclado e na tela do computador. Caso especial do sistema de arquivo não-bufferizado. Existem funções especiais para este sistema de arquivo. getche() - lê um caractere do teclado putchar() - imprime um caractere na tela Exemplo getche - putchar #include “stdio.h” main() { char ch; do { ch = getche(); if (islower(ch)) putchar (toupper(ch)); else putchar(tolower(ch)); } while (ch != ‘.’); }

121 Exemplo gets Variações de getche:
getchar() - armazena a entrada até que seja dado um enter getch() - igual a getche, só que não ecoa na tela Funções que permitem que sejam lidas e gravadas strings de caracteres no console: gets() - lê uma string de caracteres que podem ser inseridos no teclado formato do gets: char *gets(char *s) Exemplo gets main() { char str[80]; gets (str); printf (“comprimento e %d”, strlen(str)) } puts() - escreve uma string e um \n na tela formato do puts: char *puts(char *s)

122 Qual das funções deve ser mais usada: O puts ou o printf?
Formatos de entrada e saída de console: são verificados no printf e no scanf formato do printf: printf(“string”, argumentos); Código Formato %c um caractere %d decimal %i decimal %e notação científica %f decimal flutuante %g %e ou %f %o octal %s string de caracteres %u decimal sem sinal %x hexa %% % %p ponteiro %n ponteiro inteiro com o número de caracteres

123 formato do scanf: scanf(“string”, argumentos);
Código Formato %c um caractere %d decimal %i decimal %e notação científica %f decimal flutuante %o octal %h hexa %s string de caracteres %x hexa %% % %p ponteiro %n ponteiro inteiro com o número de caracteres

124 Entrada e saída bufferizado
Possui várias funções: fopen() abre uma fila fclose() fecha uma fila putc() grava um caractere na fila getc() lê um caractere da fila fseek() procura byte específico fprintf() printf de uma fila fscanf() scanf de uma fila feof devolve verdadeiro ao achar EOF ferror() devolve verdadeiro quando erro rewind() restabelece o localizador de posição remove() apaga arquivo

125 O ponteiro de arquivo: mantém unido o sistema de entrada e saída bufferizado.
Define vários aspectos como nome, status e posição corrente. O ponteiro de arquivo é uma variável de ponteiro do tipo FILE. Função fopen(): abre uma fila de bytes e liga um arquivo àquela fila forma: FILE *fopen(char *nomearquivo,char *modo); para abrir: fp = fopen(“teste”,”w”); uso comum: if ((fp=fopen(“teste”,”w”))==null) { puts (“não pode abrir arquivo\n”); exit(1); }

126 “w” cria arquivo texto p/ gravação “a” anexa a um arquivo texto
Modo Significado “r” abre arquivo texto p/ leitura “w” cria arquivo texto p/ gravação “a” anexa a um arquivo texto “rb” abre arq. binário p/ leitura “wb” cria arq. binário p/ gravação “ab” anexa a um arq. binário “r+” abre arq. texto p/ l/e “w+” cria arq. texto p/ l/e “a+” abre ou cria arq. texto p/ l/e “r+b” abre arq. binário p/ l/e “w+b” cria arq. binário p/ l/e “a+b” abre arq. binário p/l/e “rt” abre arq. texto p/ leitura “wt” cria arq. texto p/ gravação “at” anexa a um arq. texto “r+t” abre arq. texto p/ l/e “w+t” cria arq. texto p/ l/e “a+t” abre ou cria arq. texto p/ l/e

127 Função putc(): grava caracteres em uma fila previamente aberta
forma: int putc(int ch, FILE*fp); putc é int por razões históricas se a gravação for bem sucedida devolve o caractere, caso contrário devolve EOF Função getc(): lê caracteres de uma fila forma: int getc(FILE *fp); devolve EOF quando é alcançado o final de arquivo uso comum ch = getc(fp); while (ch != eof) { ch = getc(fp);} ou while (!feof(fp)) ch = getc (fp);

128 Função fclose(): fecha uma fila aberta com fopen.
forma: int fclose(FILE *fp); valor de retorno 0 significa operação de fechamento bem-sucedida Função ferror(): determina se uma operação produziu erro forma: int ferror(FILE *fp); retorna 1 se houver ocorrido um erro e 0 se a operação de arquivo foi bem sucedida Função rewind(): restabelece o localizador de posição para o início de arquivo forma: void rewind(FILE *fp);

129 Exemplo escreve em arquivo
main(argc, argv) int argc; char *argv[]; { file *fp; char ch; if (argc != 2){ printf(“esqueceu o nome do arquivo\n”); exit(1); } if ((fp = fopen(argv[1], “w”)) == null) { printf(“não pode abrir arquivo\n”); do { ch = getchar(); putc = (ch, fp); while (ch != ´$´); fclose (fp);

130 Exemplo escreve arquivo em arquivo
main(argc, argv) int argc; char *argv[]; { file *in, *out; char ch; if (argc != 3) { printf(“esqueceu nome do arquivo\n”); exit(1); } if (in = fopen (argv[1],“rb”)) == null) { printf(“não pode abrir arq fonte\n”); exit (1); if (out = fopen (argv[2],“wb”)) == null) { printf(“não pode abrir arq dest\n”); exit (1);} while (!feof(in)) putc(get(in),out); fclose (in); fclose (out);

131 Função getw(): lê inteiro de um arquivo
mesma forma de getc Função putw(): grava inteiro em um arquivo mesma forma de putw. Ex.: putw(100,fp); Função fgets(): lê fila de arquivo forma:char *fgets(char *str,int comprimento, FILE *fp); lê até \n ou comprimento - 1 Função fputs(): grava fila em arquivo forma: char *fputs(char *str, FILE *fp); Função fread(): lê bloco de dados forma:int fread(void *buffer,int num_bytes, int cont, FILE *fp);

132 Exemplo fwrite - fread Função fwrite(): lê bloco de dados
forma:int fwrite(void *buffer,int num_bytes, int cont, FILE *fp); Exemplo fwrite - fread main() { FILE *fp; float f = 12.23; if((fp=fopen(“teste”,”wb”)) == NULL) { printf(“não pode abrir arquivo\n”); return; } fwrite(&f,sizeof(float),1,fp); fclose(fp) Função fseek(): leitura e gravação aleatórias forma:int fseek(FILE*fp,long int num_bytes,int origem); Origem: início = seek_set, corrente = seek_cur, fim de arquivo = seek_end

133 Exemplo fseek Exemplo filas padrão func1() { FILE *fp;
if((fp=fopen(“teste”,”rb”)) == NULL) { printf(“não pode abrir arquivo\”); exit(1); } fseek (fp,234l,0); return getc(fp); Filas de bytes stdin, stdout e stderr podem ser redirecionadas Exemplo filas padrão putchar() char c { putc(c, stdout); }

134 Função fprintf(): printf para arquivos
forma: fprintf(fp,”string de controle”,argumentos); Função fscanf(): scanf para arquivos forma: fscanf(fp,”string de controle”,argumentos); Função remove(): apaga arquivos forma: int remove(char *nomearquivo); se bem sucedido devolve zero, senão não-zero

135 Entrada e saída não-bufferizado
Funções tipo Unix de baixo nível read() lê um buffer de dados write () grava um buffer de dados open() abre arquivo em disco close() fecha aquivo em disco lseek() procura arquivo pelo byte unlink() remove arquivo do diretório Função open(): forma:int open(char *nomearquivo, int modo, int acesso); modo é uma das macros: o_rdonly, o_wronly, o_rdwr Função close(): forma: int close(int fd);

136 Função creat(): forma: int creat(char *nomearquivo, int acesso); Função write(): forma: int write(int fd, void *buf, int tamanho); Função read(): forma: int read(int fd, void *uf, int tamanho); Função unlink(): forma: int unlink(char *nomearquivo); Função lseek(): forma: long lseek(int fd, long num_bytes, int origem);

137 Dados definidos pelo usuário
C permite 5 tipos de dados personalizados pelo usuário: estrutura, campo de bit, união, enumeração e typedef Estrutura Coleção de variáveis; referência pelo mesmo nome Variáveis que formam a estrutura são elementos de estrutura Exemplo estrutura struct addr { char nome[30]; char rua[40]; char cidade[20]; char estado[3] unsigned long int cep; };

138 Exemplo variável com estrutura
Declarando variável com a estrutura anterior Exemplo variável com estrutura struct addr ender_info; Exemplo outra forma declarar variável como estrutura struct addr { char nome[30]; char rua[40]; char cidade[20]; char estado[3] unsigned long int cep; }ender_info, binfo, cinfo; Exemplo outra forma declarar uma variável como estrutura struct { char nome[30]; char rua[40]; char cidade[20]; char estado[3] unsigned long int cep; }ender_info;

139 Exemplo acesso a variável com estrutura
Forma geral: struct nome_tipo_estrut { tipo nome_variável; ... } variáveis_estrut; Referências aos elementos da estrutura forma: nome_estrutura.nome_elemento Exemplo acesso a variável com estrutura ender_info.cep = 12345; printf(“%lu”,ender_info.cep); ou gets(ender_info.nome); Acesso a elementos individuais é indexado: Exemplo acesso a elementos individuais int t; for (t=0; ender_info.nome[t];++t) putchar (ender_info.nome[t]);

140 Exemplo matrizes de estrutura
Matrizes de estruturas: define a estrutura e depois declara uma variável daquele tipo Exemplo matrizes de estrutura struct addr ender_info[100]; Acesso a um elemento: indexa printf(“%lu”, ender_info[2].cep); Exemplo estrutura de enderecos struct addr { char nome[30]; char rua[40]; char cidade[20]; char estado[3]; } ender_ info[tamanho];... gets(ender_info[1].nome); /* inserir elemento */ ... printf(“%s \n”,ender_info[1].nome);/* mostrar elemento */ fread(&ender_info[i],sizeof(struct_addr),1,fp); /* lê */ fwrite(&ender_info[i],sizeof(struct_addr),1,fp);/*salva*/

141 Exemplos de passagens para estrutura
Passando estruturas para funções Passando elementos de estruturas para funções: passa-se uma variável simples ou endereços Exemplos de passagens para estrutura struct aluno { char x; int y; float z; char s[10]; } joao; ... Func1(joao.x); Func2(joao.y); Func3(joao.z); Func4(joao.s); Func5(joao.s[3]);

142 Exemplos de passagens de endereços para a estrutura
... Func1(&joao.x); Func2(&joao.y); Func3(&joao.z); Func4(joao.s); Func5(&joao.s[3]); Passando estruturas inteiras para funções: quando uma estrutura é um argumento de uma função ela é passada inteira usando a passagem por valor; o tipo de argumento é o tipo de parâmetro. Exemplos de passagens de estrutura inteira main() f1(parm) { struct { struct { int x, y; int a, b; char ch; char ch; }parm; } arg; { arg.a = 1000; printf(“%d”, parm.x); f1(arg); } }

143 Exemplos de outra forma de passar a estrutura inteira
struct struct_tipo { int a, b; char ch; }; main() f1(parm) { struct struct_tipo parm; struct struct_tipo arg; { arg.a = 1000; printf(“%d”,parm.a); f1(arg); } } Ponteiros para estruturas declaração: struct tipo_estrutura *ponteiro uso: obtendo chamada por referência e criando listas e outras estruturas desvantagem no uso da estrutura: esforço extra para tirar e colocar elementos na pilha. A solução é a passagem de apenas um ponteiro o conteúdo será modificado e a passagem será mais rápida

144 Exemplos de uso de ponteiro para estruturas
struct bal { float balanço; char nome[80]; } pessoa; struct bal *p ... Colocando o endereço de pessoa no ponteiro p: p = &pessoa; ... Fazendo referência ao indivíduo: (*p).balanco Existem dois métodos de fazer referência a uma variável de estrutura com ponteiros: com referências explícitas e com o operador flecha o primeiro método é considerado arcaico o segundo método é considerado uma abreviação do segundo o primeiro método é a base de entendimento do segundo

145 Exemplo de método de referências explícitas
struct tm { int horas; int minutos; int segundos; }; main() { struct tm time; time.horas = 0; time.minutos = 0; time.segundos = 0; for (;;) { update (&time); display (&time); } /* função update com referências explícitas */

146 update(t) struct tm *t; { (*t).segundos++; if ((*t).segundos == 60) { (*t).segundos = 0; (*t).minutos++; } if ((*t).minutos == 60) { (*t).minutos = 0; (*t).horas++; if ((*t).horas == 24) (*t).horas = 0; delay(); display(t) delay() struct tm *t; { { long int t; printf(“%d:”,(*t).horas); for (t=1;t<128000;++t); printf(“%d:”,(*t).minutos); } printf(“%d:”,(*t).segundos);

147 Exemplo de método de flecha
/* função update com flecha */ update(t) struct tm *t; { t->segundos++; if (t->segundos == 60) { t->segundos = 0; t->minutos+++; } if (t->minutos == 60) { t->minutos = 0; t->horas++; if (t->horas == 24) t->horas = 0; delay();

148 Exemplo com uma estrutura complexa
Matrizes e estruturas dentro de estruturas: um elemento de uma estrutura pode ser simples ou complexo Exemplo com uma estrutura complexa struct x { int a[10][10]; float b; } y; ...referência ao inteiro 3,7 em a da estrutura y: y.a[3][7] ...estrutura complexa aninhada struct emp { struct addr endereço; float salario; }trabalhador; ...atribuição trabalhador.endereco.cep = 98765 As referências são feitas da esquerda para a direita do mais externo para o mais interno

149 Campos de bit Método de acessar um único bit em um byte
Vantagens: se o armazenamento for limitado, pode se armazenar várias variáveis booleanas em um byte; interfaces de dispositivos transmitem informações codificadas em bits dentro de um byte; algumas rotinas de codificação precisam acessar bits dentro de bytes Sintaxe: struct nome_tipo_estrutura { tipo nome1: comprimento; tipo nome2: comprimento; ... tipo nome3: comprimento; } O Campo de bit é declarado como int, unsigned ou signed; campos de bit de comprimento 1 são unsigned

150 Exemplo com campo de bit
struct device { unsigned active: 1; unsigned ready: 1; unsigned xmt_error: 1; } dev_code; ... wr_tape() char c; { while (!dev_code.ready) rd(&dev_code); wr_to_tape() while (dev_code.active) rd(&dev_code); if (dev_code.xmt_error) printf(“erro de gravação) } Não é preciso dar nome a cada campo de bit Exemplo com campo de bit sem nome struct device { unsigned active: 1; unsigned ready: 1; unsigned xmt_error: 1; unsigned: 2; unsigned eot:1; } dev_code;

151 Exemplo mistura estrutura normal com campo de bit
Desvantagens dos campos de bit: não se pode utilizar o endereço de uma variável de campo de bit; não se pode colocar as variáveis de campo de bit em matrizes; não ultrapassa limite de inteiros; é dependente de máquina. Pode se misturar estrutura comum com campos de bit Exemplo mistura estrutura normal com campo de bit struct emp { struct addr endereco; float pagamento; unsigned lay_off: 1; unsigned horista: 1; unsigned deducoes: 3; } dev_code; Uniões Localização de memória usada por variáveis diferentes que podem ser de tipos diferentes

152 Exemplo passando para uma função um ponteiro
union u_type { int i; char ch; }; union u_type cn Para se ter acesso a union pode ser usado o ponto ou a flecha. Ex.: cn.i = 1; Exemplo passando para uma função um ponteiro func1(un) union u_type *un; { un->i = 10; } Union ajuda a produzir código independente Exemplo union put(word,fd) union pw { union pw, word; int i; file *fp; char ch[2]; { putc(word->ch[0],fp); } putc(word->ch[1],fp); }

153 Exemplo mostra inteiro de símbolo
Enumerações Conjunto de constantes inteiras com nome e especificação de todos os valores legais forma: enum nome_tipo_enum{lista_enum}lista_var Exemplo enumeração enum moeda{penny, nickel, dime, quarter, half_dolar,dolar}; enum moeda dinheiro; ...referências: dinheiro = dine; if (dinheiro == quarter) printf(“é um quarter\n”); Na enumeração cada símbolo também é um valor inteiro: Exemplo mostra inteiro de símbolo enum moeda{penny, nickel, dime, quarter, half_dolar,dolar}; enum moeda dinheiro; ...referências: dinheiro = dine; if (dinheiro == quarter) printf(“é um quarter\n”);

154 Exemplo inicializa símbolo
Pode se atribuir o valor inteiro de um ou mais símbolos usando um inicializador; os próximos símbolos seguirão a sequência Exemplo inicializa símbolo enum moeda {penny, nickel, dime, quarter=100, half_dolar, dolar}; ERRO no uso de enumeração (achar que o símbolo pode ser tratado diretamente) Exemplo erro na enumeração dinheiro = dolar; printf(“%s”dinheiro); ...outro gets(s) strcpy(dinheiro,s) Para usar os nomes dos símbolos é preciso escrevê-los explicitamente

155 Exemplo mostrar nome do símbolo
switch (dinheiro) { case penny: printf(“penny”); break; case nickel: printf(“nickel”); case dime: printf(“dime”); case quarter: printf(“quarter”); case half_dolar:print(“half_dolar”); case dolar: printf(“dolar”); } Exemplo mostrar nome do símbolo através do array char nome[][20] = { “penny”, “nickel”, “dime”, “quarter”, “hal_dolar”, “dolar” } ... printf(“%s”,nome[diheiro]);

156 Exemplo uso correto de símbolo associado a array
enum moeda {penny, nickel, dime, quarter, half_dolar, dolar}; char nome[][20] = { “penny”, “nickel”, “dime”, “quarter”, “half_dollar”, “dolar” }; main() { enum moeda dinheiro; for (dinheiro=penny;dinheiro<=dolar;dinheiro++) printf(“%s”,nome[dinheiro]); } Uso de sizeof para portabilidade: ajuda a eliminar código dependente de máquina Exemplo mostrar tamanho da variável char ch; int i; double f; printf(“%d %d %d”,sizeof(ch), sizeof(i), sizeof(f));

157 Exemplo qual é o tamanho da union? sizeof(tom)
union x { char ch; int i; float f; } tom; Typedef Forma de definir explicitamente novos nomes de tipos de dados forma: typedef tipo nome; Exemplo para dados simples typedef float balanco; ... balanco bal_do_ano; Exemplo para dados complexos typedef struct { float vencimento; int em_atraso; char nome[40]; } cliente; cliente clist[num_clientes];

158 Tipos de dados avançados
Apesar de existirem 5 tipos de dados em C, algumas vezes eles não conseguem satisfazer a todas as situações. O turbo C permite que sejam aplicados alguns modificadores de tipo que podem se enquadrar nas seguintes categorias: modificadores de acesso modificadores de armazenamento modificadores dos tipos de função modificadores de modelos de memória Sintaxe: modificador_tipo especificação_tipo lista_variáveis;

159 Ex.: const float versão=2.5;
Modificadores de acesso – controla a maneira como as variáveis são modificadas Modificador const – a variável não é mudada durante a execução, exceto na inicialização Ex.: const float versão=2.5; Const assegura que nenhuma parte do programa modificará aquela variável. Um exemplo disso seria na passagem de parâmetros por ponteiros. Exemplo não modificando com const void code(); void code(str) main() const char *str; { code(“oi, tudo bem ?”);} { void code(str) while(*str) { const char *str; *str=*str+1; { printf(“%c”,*str++); while(*str) } printf(“%c”,(*str++)+1); } }

160 Exemplo modificando com volatile
Modificador volatile – para fazer com que o valor de uma variável seja alterado sem uma especificação explícita do programa Exemplo modificando com volatile volatile int clock; int timer; ... timer = clock; printf(“tempo decorrido e %d\n”,clock-timer); Modificadores de armazenamento – são quatro: auto, extern, static, register. auto - utilizado para declarar variáveis locais extern - ocorre um problema se, para cada arquivo de um só projeto, todas as variáveis globais forem declaradas. Devem ser declaradas as variáveis globais em um só arquivo e nos outros deve ser usado o modificador extern.

161 Exemplo modificador extern
Arquivo Arquivo 2 int x, y; extern int x, y; char ch; extern char ch; main() func2() { { x=y/10; } } func1() func3() x=123; y=10; static - para variáveis que são permanentes nas suas próprias funções ou arquivos (mantêm seus valores entre chamadas). Útil quando se escreve funções generalizadas que outros as usam. Varíaveis static locais - são conhecidas apenas no bloco em que são declaradas, mas mantêm o valor Exemplo usando static local series() { static int series_num; series_num = series_num +23; return (series_num); }

162 Exemplo usando static global
Varíaveis static globais - a variável global é conhecida apenas no arquivo no qual foi declarada a variável static global. Exemplo usando static global static int series_num; series() { series_num = series_num + 23; return (series_num); } series_inicio(semente) int semente; series_num = semente; register - a variável declarada será armazenada no registrador da CPU e não na memória Exemplo usando register int_pwr(m,e) int m; register int e; { register int temp; temp = 1; for(;e;e--) temp*=m; return temp; }

163 Modificadores de função
Ponteiros de função: é o endereço de localização de memória de uma função Exemplo usando ponteiro de função main() { int strcmp(); char s1[80], s2[80]; void *p; p = strcmp; gets(s1); gets(s2); check(s1,s2,p); } check(a,b,cmp) char *a, *b; int (*cmp) (); if (!(*cmp)(a,b) printf(“igual”); else printf(“diferente”);

164 Operadores avançados Operadores bit a bit
C possui alguns operadores especiais que melhoram o seu poder a nível de sistema Operadores bit a bit Operadores bit a bit se referem a teste, ajusta ou troca de bits, se aplicam a char ou int OPERADOR EFEITO & AND | OR ~ complemento (NOT) ^ OR exclusivo >> deslocar a direita << deslocar a esquerda

165 Exemplo operador bit a bit &
As operações bit a bit são encontradas a nível de sistema ou em controle de dispositivos O OR bit a bit pode ligar um determinado bit O & pode ser utilizado para desligar bits O OR exclusivo pode ligar um bit se apenas os bits que estiverem sendo comparados forem diferentes Exemplo operador bit a bit & if (status & 4) printf (“bit 3 esta ligado/n”); Exemplo operador bit a bit & mostra_binario(i) int i; { register int t; for (t=128;t<0;t=t/2) if (i&t) printf("1 "); else printf ("0 "); }

166 Os operadores de deslocamento, >> e <<, deslocam, respectivamente, todos os bits de uma variável, para a direita ou para a esquerda formato dos operadores de deslocamento: variável>>num_de_bits ou variável<<num_de_bits Ex.: char x x internamente valor de x x=7; x<<1; x<<3; x<<2; x>>1; x>>2;

167 Exemplo rotação usando Union
Na rotação de bits, um bit pode ser perdido, mas uma forma de não perder os bits rotacionados é a implementação usando Union Exemplo rotação usando Union union rotate{ char ch[2]; unsigned int i; }rot; ... rotaciona(rot) union rotate *rot; { rot->ch[1]=0; rot->i=rot->i << 1; if (rot->ch[1]) rot->i=rot->i:1; }

168 Exemplo complemento Operador ?
O operador de complemento de um (~) inverte o estado de cada bit. Utilidade: encriptação, p. ex. Exemplo complemento main() { char ch; do { ch = getch(); printf(“%c”,~ch); } while (ch != ‘q’); Operador ? Tem mesma função do if-else, só que é aplicado a expressões. Possui 3 operandos. Sintaxe Exp1?Exp2:Exp3 - funciona assim: Se Exp1 é verdadeiro, Exp2 se torna o valor de toda a expressão; se Exp1 for falsa, Exp3 se torna o valor de toda a expressão

169 Parentêses e colchetes
Exemplo operador ? X=10; y=x>9?100:200; ... scanf(“%d”,&t); t ? f1(t) + f2() : printf(“inserido 0”); Formas abreviadas x = x > x+=10; x = x > x-=10; Operador , Junta expressões. Ex.: x = (y=3,y+1) ... y = 10; x = (y=y-5,25 / y); Parentêses e colchetes São considerados operadores


Carregar ppt "LINGUAGEM C Centro Federal de Educação Tecnológica da Paraíba Coordenação de Informática Professor: Lafayette B. Melo."

Apresentações semelhantes


Anúncios Google