51
Introdução ao C Parte 3 Ponteiros

Introdução Ao C (Partes 3 e 4)

Embed Size (px)

DESCRIPTION

Programação em C - Partes finais

Citation preview

Page 1: Introdução Ao C (Partes 3 e 4)

Introdução ao C

Parte 3

Ponteiros

Page 2: Introdução Ao C (Partes 3 e 4)

Definição

• Como já visto, uma variável é o nome deuma posição na memória que podearmazenar um valor de um determinadotipo• Um ponteiro é uma variável ou um valorque contem o endereço de uma posiçãona memória• A linguagem C faz uso intensivo deponteiros

Page 3: Introdução Ao C (Partes 3 e 4)

Exemplo

#include <stdio.h>

void main(void)

{int *iptr; /* Declara variavel ponteiro */

int conta = 1;

iptr = &conta;

printf("Valor de iptr %x Valor de conta %d

Endereço de conta %x\n", iptr, conta, &conta);

}

Page 4: Introdução Ao C (Partes 3 e 4)

Operador &

#include <stdio.h>void main(void){

int conta = 1;float salario = 40000.0;long distancia = 1234567L;printf("O endereço de conta ‚ %x\n", &conta);printf("O endereço de salario ‚ %x\n", &salario);printf("O endereço de distancia ‚ %x\n", &distancia);

}

Page 5: Introdução Ao C (Partes 3 e 4)

Operador *

#include <stdio.h>void main(void){

int *iptr; /* Declara variavel ponteiro */int conta = 1;int conteudo_ponteiro;iptr = &conta;conteudo_ponteiro = *iptr;printf("Valor de iptr %x

Valor de conteudo_ponteiro %dEndereço de conteudo_ponteiro %x\n",iptr, conteudo_ponteiro,&conteudo_ponteiro);

}

Page 6: Introdução Ao C (Partes 3 e 4)

Usando o valor apontado peloponteiro

#include <stdio.h>void main(void){

int contador = 10;int *iptr = NULL; /* Declara ponteiro */

/* NULL significa que o ponteiro não apontaPara variável alguma */

iptr = &contador; /* Atribui o endereço */printf("Endereço em iptr %x Valor em *iptr %d\n“ iptr, *iptr);

*iptr = 25; /* Altera o valor na memória */printf("Valor de contador %d\n", contador);

}

Page 7: Introdução Ao C (Partes 3 e 4)

Matrizes como ponteiros

#include <stdio.h>void main(void){

int conta[10];float salario[10];long distancia[5];printf("O endereço de conta ‚ %x\n", conta);printf("O endereço de salario ‚ %x\n", salario);printf("O endereço de distancia ‚ %x\n", distancia);

}

Page 8: Introdução Ao C (Partes 3 e 4)

Aritmética de ponteiros

• Ao se incrementar ou decrementar um ponteiro, deve-se levar em consideração o tipo do ponteiro

• Exemplo: considere um ponteiro que aponta para a posição de memória 1000.

Após incremento (++), teremos:

– Tipo char: 1001

– Tipo int: 1002

Page 9: Introdução Ao C (Partes 3 e 4)

Incrementando ponteiros

#include <stdio.h>void main(void){

int valores[5] = {1, 2, 3, 4, 5};int contador;int *iptr;iptr = valores;for (contador = 0; contador < 5; contador++){

printf("%d\n", *iptr);iptr++;

}

}

Page 10: Introdução Ao C (Partes 3 e 4)

#include <stdio.h>

void troca_valores(int *a, int *b)

{

int temp;

temp = *a; /* Armazena temporariamente o valor */

/* apontado por a */

*a = *b; /* Atribui o valor de b a a */

*b = temp; /* Atribui o valor de a a b */

}

void main(void)

{

int um = 1, dois = 2;

troca_valores(&um, &dois);

printf("um contém %d dois contém %d\n", um, dois);

}

Ponteiros como parâmetros defunções

Page 11: Introdução Ao C (Partes 3 e 4)

Passagem de parâmetros por valor

• Normalmente, quando definimos um parâmetro de uma função é feita uma cópia da variável da função chamadora para a função chamada

• Este mecanismo é chamado de passagem de parâmetro por valor

• Entretanto, em alguns casos queremos alterar o valor da variável na função chamadora como resultado da chamada

Page 12: Introdução Ao C (Partes 3 e 4)

Passagem de parâmetros porreferência

• A utilização de um ponteiro para uma variável ao invés da variável como parâmetro na chamada de uma função caracteriza a passagem de parâmetros por referência

• Neste caso, o valor da variável na função chamadora também é alterado, caso ele seja alterado na função chamada

• Uso do operador &

Page 13: Introdução Ao C (Partes 3 e 4)

Chamada por valor - Exemplo#include <stdio.h>void exibe_e_altera(int primeiro, int segundo, int terceiro){

printf("Valores originais da função %d %d %d\n",primeiro, segundo, terceiro);primeiro += 100;segundo += 100;terceiro += 100;printf("Valores finais da função %d %d %d\n",primeiro, segundo, terceiro);

}void main(void){

int a = 1, b = 2, c = 3;exibe_e_altera(a, b, c);printf("Valores finais em main %d %d %d\n", a,b,c);

}

Page 14: Introdução Ao C (Partes 3 e 4)

Chamada por referência - Exemplo#include <stdio.h>

void exibe_e_altera(int *primeiro, int *segundo, int *terceiro)

{

printf("Valores originais da função %d %d %d\n",

*primeiro, *segundo, *terceiro);

*primeiro += 100;

*segundo += 100;

*terceiro += 100;

printf("Valores finais da função %d %d %d\n",

*primeiro, *segundo, *terceiro);

}

void main(void)

{

int a=1, b=2, c=3;

exibe_e_altera(&a, &b, &c);

printf("Valores finais em main %d %d %d\n", a, b ,c);

}

Page 15: Introdução Ao C (Partes 3 e 4)

Ponteiros para funções

#include <stdio.h>int pega_result(int a, int b, int (*compare)()){

return(compare(a, b)); // Chama a função passada}int max(int a, int b){

printf("Em max\n");return((a > b) ? a: b);

}int min(int a, int b){

printf("Em min\n");return((a < b) ? a: b);

}

Page 16: Introdução Ao C (Partes 3 e 4)

Ponteiros para funções

void main(void)

{

int result;

result = pega_result(1, 2, &max);

printf("O maximo entre 1 e 2 ‚ %d\n", result);

result = pega_result(1, 2, &min);

printf("O minimo de 1 e 2 ‚ %d\n", result);

}

Page 17: Introdução Ao C (Partes 3 e 4)

Percorrendo uma string componteiros

/* Lembre-se: uma string é uma matriz de caracteresterminada por NULL (0) */#include <stdio.h>void exibe_string(char *string){

while (*string)putchar(*string++);

}void main(void){

exibe_string(“FAETERJ Petropolis");

}

Page 18: Introdução Ao C (Partes 3 e 4)

Ponteiros para ponteiros

#include <stdio.h>void main(void){

char *diasuteis[] = {"Segunda", "Terça", "Quarta","Quinta", "Sexta", "" };char **dia_util;dia_util = diasuteis;while (*dia_util)

printf("%s\n", *dia_util++);

}

Page 19: Introdução Ao C (Partes 3 e 4)

Ponteiros para ponteiros paraponteiros

#include <stdio.h>int qual_e_o_valor(int ***ptr){

return(***ptr);}void main(void){

int *nivel_1, **nivel_2, ***nivel_3, valor = 1001;nivel_1 = &valor;nivel_2 = &nivel_1;nivel_3 = &nivel_2;printf("O valor ‚ %d\n", qual_e_o_valor(nivel_3));

}

Page 20: Introdução Ao C (Partes 3 e 4)

Exercício

• Escreva um programa que copie o conteúdo de uma string A para uma string B usando ponteiros para percorrer ambas as strings. O que acontece se o tamanho de A é maior que o tamanho de B?

Page 21: Introdução Ao C (Partes 3 e 4)

Alocação Dinâmica de Memória

• Muitas vezes nós não sabemos qual deve ser o tamanho de um vetor quando da codificação do programa, apenas quando da sua execução

• Duas soluções

– Definir um vetor MUITO grande (pior caso)

– Alocar memória dinamicamente

Page 22: Introdução Ao C (Partes 3 e 4)

Crivo de Erastótenes

#include <stdlib.h>void varia_crivo (int);void varia_crivo (int n)/* Achar todos os primos de 1 ate n */{

int *crivo;int i;crivo= (int *)malloc (n*sizeof(int));/* inicializa memoria */for (i= 0; i < n; i++)

crivo[i]= NAO_MARCADO;/* Resto do codigo */free (crivo); /* libera a memoria */

}

Page 23: Introdução Ao C (Partes 3 e 4)

malloc em detalhe

Page 24: Introdução Ao C (Partes 3 e 4)

free

• A declaração free libera a memória alocada de volta para o S.O.

free(crivo);

Esta declaração informa ao S.O.

que a memória alocada não é mais necessária.

É FUNDAMENTAL em C liberar a memória

alocada com malloc.

Page 25: Introdução Ao C (Partes 3 e 4)

Exercício

• Complete o programa que codifica o crivo de Erastótenes (pesquise o algoritmo!!!!)

Page 26: Introdução Ao C (Partes 3 e 4)

Introdução ao C

Parte 4

Estruturas

Page 27: Introdução Ao C (Partes 3 e 4)

Definição

• Coleção de variáveis referenciadas por um nome

• As variáveis que compreendem a estrutura são conhecidas como campos

• Usada para definir novos tipos de dados

Page 28: Introdução Ao C (Partes 3 e 4)

Estrutura - exemplo

struct endereço{

char nome[30];

char rua[40];

char cidade[20];

char estado[3];

unsigned long int cep;

};

Page 29: Introdução Ao C (Partes 3 e 4)

declaração struct

#include <stdio.h>struct line {

int x1, y1; /* coord. inicio linha*/int x2, y2; /* coord. fim linha */

};main(){struct line line1;..}

A variável line1 é umavariável do tipo line

Page 30: Introdução Ao C (Partes 3 e 4)

Typedef

• Typedef permite a associação de uma nome a uma estrutura (ou outro tipo de dado).

typedef struct line {int x1, y1;int x2, y2;

} LINE;int main(){LINE line1;}

Page 31: Introdução Ao C (Partes 3 e 4)

Acessando partes de uma estrutura

• Para acessar partes de uma estrutura usamos a notação . (ponto)

LINE line1;line1.x1= 3;line1.y1= 5;line1.x2= 7;if (line1.y2 == 3) {

printf ("coord Y do final e 3\n");}

Page 32: Introdução Ao C (Partes 3 e 4)

Passando estruturas para funções

• Podemos passar e retornar estruturas de funções (o protótipo da função deve estar definido APÓS a declaração da estrutura )

typedef struct line {int x1,y1;

int x2,y2;

} LINE;

LINE find_perp_line (LINE);

Page 33: Introdução Ao C (Partes 3 e 4)

Poteiros para estruturastypedef struct great_mathematician {char name[80];int year_of_birth;int year_of_death;char nationality[80];} MATHEMATICIAN;..MATHEMATICIAN *cantor;cantor= (MATHEMATICIAN *)malloc (sizeof (MATHEMATICIAN));

(*cantor).year_of_birth= 1845;(*cantor).year_of_death= 1918;

strcpy ((*cantor).name, "Georg Cantor");strcpy ((*cantor).nationality, "German");free(cantor); /* Não esqueça de liberar a memória */

Page 34: Introdução Ao C (Partes 3 e 4)

Ponteiros para estruturas

• C permite name->bit como um atalho para (*name).bit

MATHEMATICIAN *cauchy;cauchy= (MATHEMATICIAN *)malloc (sizeof (MATHEMATICIAN));

cauchy->year_of_birth= 1789;cauchy->year_of_death= 1857;

strcpy (cauchy->name, "Augustin Louis Cauchy");strcpy (cauchy->nationality, "French");..free(cauchy);

Page 35: Introdução Ao C (Partes 3 e 4)

Strings em C

• Usadas para armazenar e imprimir texto

• Uma string é um vetor do tipo char que tem '\0' como último caracter.

• Podemos imprimir uma string com %s:

char ola[]= "Hello World!\n";

printf ("%s", ola);

Page 36: Introdução Ao C (Partes 3 e 4)

Strings – funções úteis

• Diversas funções úteis na biblioteca string.h

#include <string.h>int main(){

char test[100];char test2[]= "World!\n";strcpy(test,"Hello"); /*copia*/strcat(test,test2); /* concatenacao*/if (strcmp(test,"david") == 0)

printf ("Test é o mesmo que David\n");printf ("comprimento de test é is %d\n",strlen (test));

}

Page 37: Introdução Ao C (Partes 3 e 4)

Obtendo números de strings

• Se a string contém um número podemos usar atoi or atof para convertê-la em um número. Estas funções estão declaradas em stdlib.h e retornam 0 em caso de erro

char numberstring[]= "3.14";

int i;

double pi;

pi= atof (numberstring);

i= atoi ("12");

Page 38: Introdução Ao C (Partes 3 e 4)

Função scanf()

/* leitura de inteiros do teclado */

#include <stdio.h>

void main(void)

{

int a,b;

scanf("%d,%d", &a, &b);

}

Page 39: Introdução Ao C (Partes 3 e 4)

Função scanf()%c Lê um único caractere%d Lê um decimal inteiro%i Lê um decimal inteiro (não pode ser octal ou hexadecimal)%u Lê um decimal sem sinal%e Lê um número em ponto flutuante com sinal opcional%f Lê um número em ponto flutuante com ponto opcional%g Lê um número em ponto flutuante

com expoente opcional (double)%o Lê um número em base octal%s Lê uma string%x Lê um número em base hexadecimal%p Lê um ponteiro

Page 40: Introdução Ao C (Partes 3 e 4)

scanf() - Lendo Strings

#include <stdio.h>void main(void){

char nome[40];scanf("%s", nome);

}

#include <stdio.h>void main(void){

char str[40];scanf("%20s", str);/* le no máximo 20 caracteres */

}

Page 41: Introdução Ao C (Partes 3 e 4)

Manipulação de arquivos em C• Em C usamos FILE * para representar um ponteiro para um

arquivo• fopen é usado para abrir um arquivo (retorna NULL em

caso de erro) .

FILE *fptr;char filename[]= "file2.dat";fptr= fopen (filename,"w");if (fptr == NULL) {

fprintf (stderr, “ERRO”);/* faça algo aqui */

}

Page 42: Introdução Ao C (Partes 3 e 4)

Modos de abertura de arquivos

• O segundo argumento de fopen é o modo no qual abrimos um arquivo. Há três possibilidades básicas:

"r" – leitura

"w" - escrita – escreve sobre conteúdo existente

"a" - acrescenta – escrita no final do arquivo

Page 43: Introdução Ao C (Partes 3 e 4)

Modos de abertura de arquivos

• Possibilidades adicionais:

"r+" – leitura/escrita

"w+" - leitura/escrita – escreve sobre conteúdo existente

"a+" - leitura/escrita (acrescenta) – escrita no final do arquivo

Page 44: Introdução Ao C (Partes 3 e 4)

Arquivos padrão (streams)

• Arquivos padrão especiais (streams) definidos stdio.h

stdin – entrada padrão (teclado)

stdout – saída padrão (tela)

stderr - imprime erro em um dispositivo de erro (normalmente a tela)

stdaux – saída auxiliar (porta serial)

stdprn – impressora padrão (porta paralela)

Page 45: Introdução Ao C (Partes 3 e 4)

Arquivos padrão (streams)

• Não é necessário abrir os arquivos padrão

Exemplo:

fprintf (stdout,"Hello World!\n");

Page 46: Introdução Ao C (Partes 3 e 4)

Lendo um arquivo texto - fscanf

FILE *fptr;char line [1000];fptr= fopen (filename,"r");if (fptr == NULL) {

fprintf (stderr, “ERRO”);/* faça algo aqui */

}while (fscanf(fptr,”%s”,line) != EOF) {

printf ("Lendo linha %s\n",line);}

Page 47: Introdução Ao C (Partes 3 e 4)

Lendo um arquivo texto - fgets

FILE *fptr;char line [1000];/* primeiro abra o arquivo aqui */while (fgets(line,1000,fptr) != NULL) {printf ("Lendo linha %s\n",line);}

fgets tem 3 argumentos:– uma string,– O número máximo de caracteres– um ponteiro de arquivo( retorna NULL em caso de erro)

Page 48: Introdução Ao C (Partes 3 e 4)

Laços de leituraExemplo: laço while usando fgets

FILE *fptr;char tline[MAXLEN]; /* linha de texto */fptr= fopen ("texto.txt","r");/* verifica se arquivo está aberto aqui*/while (fgets (tline, MAXLEN, fptr) != NULL){

printf ("%s",tline);/* imprime string */}fclose (fptr);

Page 49: Introdução Ao C (Partes 3 e 4)

Escrevendo no arquivo usando fprintf

• fprintf funciona como printf, sendo o oprimeiro arugumento é um ponteiro para arquivo.

FILE *fptr;

fptr= fopen ("file.dat","w");

/* verifique se esta aberto */

fprintf (fptr,"Hello World!\n");

Page 50: Introdução Ao C (Partes 3 e 4)

Fechando um arquivo

Para isso usamos fclose e o ponteiro do arquivo:

FILE *fptr;char filename[]= "myfile.dat";fptr= fopen (filename,"w");if (fptr == NULL) {

printf ("Erro na abertura!\n");exit(-1);

}fprintf (fptr,"Hello World!\n");fclose (fptr);

Page 51: Introdução Ao C (Partes 3 e 4)

Exercício

• Abra o arquivo do programa que resolve o exercício da aula de estruturas e imprima todas as linhas na tela.