Programar em C/Estruturas: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Albmont (discussão | contribs)
Alguma formatação, mas o texto está muito ruim
Linha 13:
== Declarar uma estrutura ==
A sintaxe é:
<pre>
 
struct <identificador> {
<tipo> campo_um ;
<tipo> campo_dois ;
};
</pre>
 
Aqui o tipo struct indica que vamos criar uma estrutura.
Linha 26 ⟶ 27:
<b>Primeiro Método :</b><br>
 
<pre>
struct minha_estrutura
{
Linha 32 ⟶ 34:
char fruta[40];
} ;
</pre>
 
Aqui o identificador do tipo "struct" é "minha_estrutura" dentro dessa estrutura temos três campos o ultimo é
Linha 39 ⟶ 42:
 
Para ter acesso aos membros definidos dentro da estrutura utilizamos um operador de seleçao de membro "."(um ponto).
<pre>
nova_estrutura.fruta[0] ;
</pre>
Nos da o primeiro caracter da palavra contida dentro do membro "fruta".
 
== Matriz (uma maneira de ver a coisa) ==
 
AUma maneira mais fácil para que eu costumo fazer para entender as structures é fazer a associação com uma matriz.
{| border 1
|Person || String Name || int height
Linha 71 ⟶ 76:
Podemos declarar os objectos ao de duas formas:
* Ao mesmo tempo que declaramos a estrutura
<pre>
struct product {
int weight;
float price;
} apple, banana, melon;
</pre>
* Ou como uma variável normal
<pre>
struct product
{
Linha 84 ⟶ 92:
product apple, banana, melon;
}
</pre>
 
E até podemos declarar um array delas
<pre>
Person p[20];
</pre>
 
'''Pergunta''': como é que é feito exactamente os objectos?
 
'''Pergunta''': como é que é feito exactamente os objectos
Para cada objecto vão ser feito uma cópia dos elementos da estrutura.
 
Agora isso significa que os objectos são distintos entre si em termos de reserva de memória? ie, á medida que enumero os objectos vão ser reservado para cada objecto o tamanho x de bytes? ou somam-se todos os objectos e reserva-se para todos os objectos de uma forma seguida? Penso que deve ser a 1ª opção.
 
Se tivermos apenas um objecto (ou variável da estrutura) não é necessário darmos o nome da estrutura
<pre>
struct {
char item[40]; // name of item
Linha 100 ⟶ 113:
int lead_time; // number of days before resupply
} temp;
</pre>
 
'''Pergunta''': neste caso como é que chamamos o objecto fora da declaração da estrutura?
Linha 116 ⟶ 130:
 
Agora queremos dar valores a cada uma das pessoas, queremos dar o nome e a altura, para isso faríamos;
<pre>
p1.name = “Tiago”
p1.alturaname =1,9 "Tiago";
p1.altura =1.9;
</pre>
 
Se quiséssemos imprimir o valor guardado
<pre>
cout << "The name of p1 is " << p1.name;
</pre>
 
Um '''erro''' usual é fazer
<pre>
Person.name =”Tiago” "Tiago"; //não funciona
</pre>
 
A forma genérica é:
<pre>
structure-varname.member-name
</pre>
 
ou seja é o
<pre>
[objecto_estrutura][member_estrutura]
</pre>
 
 
Exemplo
<pre>
#include <iostream>
#include <string>
Linha 164 ⟶ 190:
return 0;
}
</pre>
 
== Iniciar uma estrutura ==
Linha 170 ⟶ 197:
* Usando uma '''lista de iniciação'''
esta seria algo:
<pre>
Person p1 = {"Jeff Kent", 72};
</pre>
isto basicamente é igual a arrays, apenas com a diferença de termos tipologias diferentes. Logo a ordem vai interessar, por exemplo se escrevêssemos
<pre>
Person p1 = {72", "Jeff Kent"}; //não iria funcionar- erro de compilação
</pre>
 
* Usando '''construtores'''
Os construtores são funções que são criadas automaticamente sempre que tentamos criar um objecto. A esses que são criados automaticamente são os chamados de defaut.
Se escrevermos o código
<pre>
#include <iostream>
#include <string>
Linha 195 ⟶ 227:
return 0;
}
</pre>
 
O resultado é
Linha 206 ⟶ 239:
 
Podemos ter um constructor sem argumentos que ao contrário do defaut constructor designa valores defaut ás variáveis membro.
<pre>
struct Person
{
Linha 216 ⟶ 250:
}
};
</pre>
 
* O nome do constructor é sempre igual ao nome da estrutura, sem excepção.
Linha 221 ⟶ 256:
 
Refazendo o nosso exemplo
<pre>
#include <iostream>
#include <string>
Linha 241 ⟶ 277:
return 0;
}
</pre>
 
Repare que demos valores defaut ás variáveis. Agora não estamos no caso de ter p1.name=???
Linha 251 ⟶ 288:
Termos um constructor sem argumentos é um melhoramento face ao defaut constructor pois agora temos valores defaut para as variáveis membro.
Porém seria melhor se conseguíssemos inicializar as variáveis membro com valores dados pelo utilizador enquanto o programa estivesse e a correr. E realmente podemos fazer se passarmos argumentos.
<pre>
#include <iostream>
#include <string>
Linha 285 ⟶ 323:
return 0;
}
</pre>
 
Repare que os argumentos do construtor têm de estar na ordem esperada
 
Linha 290 ⟶ 330:
 
== Separar o constructor prototype da implementação ==
<pre>
 
#include <iostream>
#include <string>
Linha 330 ⟶ 370:
return 0;
}
</pre>
 
* Vamos ver a função main(): declarámos 2 variáveis uma int e outra string. Pedimos para a pessoa escrever o nome e colocámos o valor na variável string, depois pedimos a altura e colocámos na variável int. Depois chamámos o constructor com dois argumentos e passamos as variáveis anteriores como argumentos. Por fim mandámos imprimir no ecrã os valores das variáveis membro da estrutura.
* Repare que para definirmos fora o construtor recorremos ao operador scope ::
<pre>
Person::Person()
Person::Person(string s, int h)
</pre>
* Repare que no prototype dos constructor apenas tivemos de dizer a tipologia dos parâmetros
 
Linha 343 ⟶ 386:
 
A ideia é ter uma estrutura dentro de outra estrutura.
<pre>
#include <iostream>
#include <string>
Linha 393 ⟶ 437:
<< "/" << pers.bDay.year << endl;
}
</pre>
 
Reparem que a estrutura Date tem de ser declarada antes da estrutura Person, pois caso contrário o compilador não entendia a tipologia declarada na estrutura Person.
 
Agora para termos os valores da estruturura é
<pre>
cin >> pers.bDay.month >> pers.bDay.day >> pers.bDay.year;
</pre>
 
== Passando estruturas com argumento do funções ==
<pre>
 
#include <iostream>
#include <string>
Linha 438 ⟶ 485:
cout << "Person's name is " << pers.name << " and height is " << pers.height << endl;
}
</pre>
 
A estrutura é passada por referência ou por address
Linha 445 ⟶ 492:
== Ponteiros para estruturas ==
 
<pre>
struct movies_t
{
Linha 453 ⟶ 501:
movies_t amovie;
movies_t * pmovie;
</pre>
 
Nós criámos algo
<pre>
movies_t title year
amovie
* pmovie
</pre>
 
Vejamos que temos um ponteiro como instância.
<pre>
// pointers to structures
#include <iostream>
Linha 491 ⟶ 543:
return 0;
}
</pre>
 
Como já devem ter deduzido o operador -> será muito similar a
pmovie->title é equivalente a (*pmovie).title
 
 
Mas olhem que é diferente a: