Upload
anderson-alves
View
16
Download
0
Embed Size (px)
DESCRIPTION
Programação em C - Partes finais
Citation preview
Introdução ao C
Parte 3
Ponteiros
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
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);
}
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);
}
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);
}
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);
}
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);
}
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
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++;
}
}
#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
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
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 &
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);
}
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);
}
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);
}
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);
}
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");
}
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++);
}
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));
}
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?
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
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 */
}
malloc em detalhe
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.
Exercício
• Complete o programa que codifica o crivo de Erastótenes (pesquise o algoritmo!!!!)
Introdução ao C
Parte 4
Estruturas
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
Estrutura - exemplo
struct endereço{
char nome[30];
char rua[40];
char cidade[20];
char estado[3];
unsigned long int cep;
};
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
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;}
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");}
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);
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 */
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);
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);
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));
}
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");
Função scanf()
/* leitura de inteiros do teclado */
#include <stdio.h>
void main(void)
{
int a,b;
scanf("%d,%d", &a, &b);
}
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
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 */
}
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 */
}
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
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
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)
Arquivos padrão (streams)
• Não é necessário abrir os arquivos padrão
Exemplo:
fprintf (stdout,"Hello World!\n");
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);}
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)
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);
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");
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);
Exercício
• Abra o arquivo do programa que resolve o exercício da aula de estruturas e imprima todas as linhas na tela.