Escolar Documentos
Profissional Documentos
Cultura Documentos
(PdC)
Structs
typedef, operadores, funções, ponteiros
{ }
Cristiano Premebida
cpremebida@deec.uc.pt
Imaginemos que desejamos tratar dados relativos a uma pessoa. Poderíamos criar um conjunto
de variáveis com a informação (registo) da pessoa:
• char nome[100];
• char sexo, estado_civil;
• unsigned int idade;
• float salario;
Estruturas: permitem que toda esta informação esteja agrupada e relacionada entre si.
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 2
Structs - sintaxe
Sintaxe da declaração de uma estrutura
struct [nome_da_estrutura] A declaração de uma estrutura
{ define um tipo de dados
tipo_1 campo_1a, campo_1b; composto, mas não define
tipo_2 campo_2; variáveis de tipo estrutura.
...
tipo_n campo_n;
};
struct Data
{
int dia, ano; // campos numéricos
char mes[12]; // uma string para o mês
};
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 3
Structs – exemplo (acesso aos campos)
Para aceder aos membros de uma estrutura, usa-se o operador ponto (.),
por exemplo: Data.dia
#include <stdio.h>
#include <string.h>
int main() {
struct Data
{
int dia, ano;
char mes[12];
} data; // note o ; no final da declaração
data.dia = 11;
data.ano = 2049;
strcpy(data.mes, "Maio"); // nao eh possivel data.mes = "Maio";
return (1); }
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 4
Structs - Inicialização - declaração
Sintaxe da declaração com inicialização p/ex:
struct Data dy =
struct nome_da_estrutura nome_var = {25, 2035, "Abril"};
{valor_1, valor_2, ..., valor_n};
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 5
Structs - exemplo
#include <stdio.h>
int main() {
struct Data {
int dia, ano;
char mes[12];
} dx = {10, 2099, "Outubro"}, tab[2]; ;
return (1);}
Page 6
Structs: definição de tipos – typedef
Sintaxe:
typedef tipo_existente nova_designação;
typedef permite criar um sinónimo (uma só palavra) para um tipo já existente, de acordo com as
preferências/necessidades do programador. Num typedef não há declaração de variáveis.
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 7
Exemplos com typedef
/* Sinónimos */
typedef float decimal;
typedef int inteiro;
/* Mais curto */
typedef long unsigned int LUint;
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 8
Âmbito da declaração de uma estrutura e typedef
• Assim, se quisermos que uma estrutura seja conhecida/visível para várias funções de
um programa, a sua definição deve estar fora de qualquer função e de preferência no
início, antes dos protótipos da funções.
Curiosidade:
• O tipo FILE é um exemplo da utilização de
typedef:
typedef struct _IO_FILE FILE;
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 9
Operadores e estruturas
• Sendo uma estrutura definida pelo utilizador, não podemos utilizar os operadores relacionais
<, >, >=, <=, == ou ! =
• Se v é uma estrutura então &v devolve o endereço dessa estrutura em memória (ou seja
o menor dos endereços que ela ocupa)
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 10
Estruturas – exemplo (operadores)
#include <stdio.h>
struct ponto {
double x; //Coordenada segundo o eixo dos x
double y; //Coordenada segundo o eixo dos y
};
int main() {
struct ponto P1={0.0,0.0}, P2, P3;
printf(" Coord. de P1 (%.1f,%.1f) \n", P1.x, P1.y);
// Preenche novas coordenadas
printf("De-me as coordenadas x, y de um ponto:\n");
scanf("%lf%lf", &P1.x, &P1.y);
printf("\n Novas coord. P1 (%.1f,%.1f) \n", P1.x, P1.y);
// usa atribuição ie, copia para P2
P2 = P1;
printf("P2 = (%.1f,%.1f) \n", P2.x, P2.y);
return (1);}
Page 11
Estruturas que contêm estruturas
• um membro de uma estrutura pode ser do tipo estrutura. Basta para tal que esse tipo já tenha sido
definido previamente.
Exemplo de uma estrutura com um membro que aponta para uma estrutura com o mesmo tipo:
struct Elem
{
int valor;
struct Elem *pElem; // Ponteiro para uma struct Elem
}; // Útil em Estrutras de Dados e Algoritmos
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 12
Estruturas que contêm estruturas - exemplo
Podemos definir um ponto 2D num plano: struct ponto {
double x; //Coord. x
double y; //Coord. y
};
E em seguida definir um segmento:
struct segmento {
struct ponto origem; // extremo 1 do segmento
struct ponto destino; // extremo 2 do segmento
};
Sendo Seg do tipo struct segmento, que tem como mebro a estrutura ponto, para aceder aos
membros basta usarmos a notação:
Page 13
Exemplo: passagem de estruturas a funções – por valor
#include <stdio.h>
#include <math.h>
int main(){
struct ponto a = {1.2, 2.3};
struct ponto b = {4.2, 6.3};
mostra_ponto(a);
mostra_ponto(b);
mostra_ponto((struct ponto){5.7, 8.9});
return (1); }
Page 14
Exemplo: Função que retorna uma estrutura
#include <stdio.h>
struct ponto { double x, y; };
void mostra_ponto(struct ponto p)
{ printf("ponto (%.1f,%.1f)\n", p.x, p.y); }
int main(){
struct ponto a;
a = retorna_ponto(); // a <- valor retornado
mostra_ponto(a);
return (1); }
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 15
Exemplo: funções e estuturas que contêm estruturas
#include <stdio.h>
#include <math.h>
struct ponto {double x, y;};
struct segmento {struct ponto origem, destino;};
double comprimento(struct segmento s);
void main(){
struct ponto a = {1.2, 2.3};
struct ponto b = {4.2, 6.3};
struct segmento z;
z.origem = a;
z.destino = b;
printf("O segmento mede %.0f\n", comprimento(z));
return (1);}
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 16
Exemplo anterior: com typedef
#include <stdio.h>
#include <math.h>
typedef struct {double x, y; } ponto;
typedef struct {ponto origem, destino; } segmento;
double comprimento(segmento s);
int main(){
ponto a = {1.2, 2.3};
ponto b = {4.2, 6.3};
segmento z;
z.origem = a;
z.destino = b;
printf("O segmento mede %.0f\n", comprimento(z));
return (1);}
double comprimento(segmento s) {
double dx, dy;
dx = fabs(s.origem.x - s.destino.x);
dy = fabs(s.origem.y - s.destino.y);
return ((double)(sqrt(dx*dx + dy*dy))); }
Page 17
Passagem de estruturas a funções – por ponteiro
• Em C só existe passagem por valor.
• Se desejamos que uma função seja capaz de modificar uma variável que lhe é externa, tal
só é possível se a função receber um ponteiro para o valor dessa variável.
• O ponteiro é passado por valor, mas permite à função aceder e alterar o valor apontado.
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 18
Exemplo: passagem por ponteiro
#include <stdio.h>
struct ponto {
double x, y; };
int main(){
struct ponto a;
le_ponto(&a);
mostra_ponto(a);
return (1);}
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 19
Passagem de estruturas a funções – por ponteiro
No exemplo anterior temos, struct ponto *ptr; e para
acedermos aos membros x e y de struct ponto escrevemos:
(*ptr).x , porque o que desejamos é o campo x da struct
apontada por ptr, a qual é *ptr
• Não podemos escrever *ptr.x porque o operador ponto (.) tem precedência sobre o
operador de desreferencia (*)
Operador ->
Se ptr for um ponteiro para uma estrutura e campo um membro dessa estrutura, então as
expressões (*ptr).campo e ptr->campo são equivalentes.
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 20
Exemplo: passagem por ponteiro
#include <stdio.h>
struct ponto {
double x, y; };
int main()
{
struct ponto a;
le_ponto(&a);
mostra_ponto(a);
return (1); }
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 21
Estruturas – ficheiros
A escrita de estruturas em ficheiros pode ser feita em modo texto.
@Créditos/referência: partes do conteúdo são baseados no material didático, de anos anteriores, da Profª. Teresa Gomes – DEEC-UC. Page 22
Exemplo: criar ficheiro texto
#include <stdio.h>
struct ponto {double x, y; };
void mostra_ponto(struct ponto p) {
printf("ponto (%.1f,%.1f)\n", p.x, p.y); }
void le_ponto(struct ponto *ptr){
printf("De-me as coordenadas x, y de um ponto:\n");
scanf("%lf%lf", &(*ptr).x, &(*ptr).y); }
int main(){
struct ponto a[4];
for(int i = 0; i < 4; i++) le_ponto(&a[i]);
FILE *fich;
fich= fopen("pontos.txt","w"); // Cria/Reescreve para escrita
if(fich == NULL) return (-1);
for(int i = 0; i < 4; i++)
fprintf(fich, "%g;%g\n", a[i].x, a[i].y);
fclose(fich);
// Abre o ficheiro para leitura
fich= fopen("pontos.txt","r");
struct ponto b[4];
for(int i = 0; i < 4; i++)
fscanf(fich, "%lf%*c%lf\n", &b[i].x, &b[i].y);
//print
for(int i = 0; i < 4; i++) mostra_ponto(b[i]);
fclose(fich);
return (1);}
Page 23
Exemplo: criar ficheiro binário
struct ponto {double x, y; };
void mostra_ponto(struct ponto p) {
printf("ponto (%.1f,%.1f)\n", p.x, p.y); }
void le_ponto(struct ponto *ptr){
printf("De-me as coordenadas x, y de um ponto:\n");
scanf("%lf%lf", &(*ptr).x, &(*ptr).y); }
int main(){
struct ponto a[4];
for(int i = 0; i < 4; i++) le_ponto(&a[i]);
FILE *fich;
fich= fopen("pontos.bin","wb");
if(fich == NULL) return (-1);
int k = fwrite(a, sizeof(struct ponto), 4, fich);
fclose(fich);
if(k != 4) {
printf("Erro a criar o ficheiro pontos.bin");
return -2; }
fich= fopen("pontos.bin","rb");
struct ponto b[4];
k = fread(b, sizeof(struct ponto), 4, fich);
fclose(fich);
if(k != 4) {
printf("Erro a ler o ficheiro pontos.bin");
return -2; }
for(int i = 0; i < 4; i++) mostra_ponto(b[i]);
return (1);}
Page 24