Jump to content

vetor dinâmico dentro de uma estrutura


Baptistazito
 Share

Recommended Posts

Pode-se definir um vetor dinâmico numa estrutura?

Algo do género uma vez que com aquilo que pretendo fazer não sei se o vetor vai ter tamanho 0,1, ... ou 1000:

struct Coiso{
 int dados;
 int vetor[x]
}

e à medida que vou lendo numeros vou aidicionanto à posicão x do vetor

caso não posso como faço?

Edited by Baptistazito
Link to comment
Share on other sites

não é essa a minha dúvida. a minha dúvida é uma coisa do género, ter a estrutura em questão.

e depois de criar a lista com inserção à cabeça faço algo do género:

_coiso * coiso;

scanf("%d", &dados);
coiso -> dados = dados

scanf("%d", &dadosVetor);
coiso -> vetor[0] = dadosVetor

scanf("%d", &dadosVetor);
coiso -> vetor[1] = dadosVetor

scanf("%d", &dadosVetor);
coiso -> vetor[2] = dadosVetor

e por aí fora até à posicao n do vetor. Não sei se estás a perceber o q quero dizer. De referir também que os scanfs estariam dentro de um ciclo embora acho que estar a pôr aqui o código todo é irrelevante

Edited by Baptistazito
Link to comment
Share on other sites

O que deves fazer é definir funções para manipular o teu tipo de dados, e nessas funções verificas se já tens o vetor alocado, ou se precisas de adicionar mais espaço. Será conveniente teres um campo na estrutura de dados que te diga quantos elementos já tens no vetor.

Tipo:

scanf("%d", &dados);
definirDados(coiso, dados);

scanf("%d", &dadosVetor);
adicionarAoVetor(coiso, dadosVetor);

scanf("%d", &dadosVetor);
adicionarAoVetor(coiso, dadosVetor);

scanf("%d", &dadosVetor);
adicionarAoVetor(coiso, dadosVetor);

A função adicionarAoVetor seria algo do género:

  • verificar se o vetor já foi alocado
    • se ainda não foi, alocar
    • se já foi, verificar se tem espaço suficiente
      • se não tem, realocar o vetor

    [*]inserir o valor na primeira posição livre do array

    [*]se ocorreu algum erro, devolver 1, caso contrário 0

Link to comment
Share on other sites

então nesse caso declaro o vetor na estrutura assim?

struct{
 int dados
 int  * vetor
}

Já agora, eu sei que não é muito correto(caso dê para fazer) mas será que posso fazer algo do género

Declarar no main o vetor

int main()

int vetor [x]

ler as variáveis e em seguida, e uma vez que não vai voltar a ser mexido a não ser para consulta passar como argumento para dentro da estrutura o vetor?

Edited by Baptistazito
Link to comment
Share on other sites

Na declaração da estrutura, convém ainda adicionar um campo a dizer quantos elementos já foram adicionados ao vetor (para saberes onde adicionar o próximo).

Não me parece boa ideia usar um vetor declarado na main, sobretudo se assumires que vais ter que redimensionar o vetor (deves evitar qualquer referência directa ao vetor).

  • Vote 1
Link to comment
Share on other sites

ok. é isso que vou fazer então.

Entretanto surgiu-me aqui um problema no código que não tou a conseguir solucionar. É o seguinte:


struct Pessoas
{
   int info;
   int ligacao;
 int nPartilhas;  
   struct Pessoas *prox;

};

void insereLista(struct Pessoas **p0, int nPessoa, int ligacao)
{
   struct Pessoas *p;
 p = (struct Pessoas*)malloc(sizeof(struct Pessoas));
 p->info = nPessoa;
 p->prox = *p0;
   *p0 = p;

}

int scc_vazio(struct Pessoas ** po)
{
int i = 0;
struct Pessoas *p;

while(p != NULL){
 if(p-> nPartilhas == 0)
 {
  i++; 
 }
p = p-> prox;
}
return i;
}

no main a chamada à função scc_vazio é apenas:

scc_vazio(&lista);

Eu sei que estou a inserir corretamente pois quando mando imprimir a lista ela imprime-me e faz exatamente o que é suposto. Mas na função scc_vazio não me chega a entrar no while. Sei que tem a ver algo com o argumento **p0 mas não sei o que poderá ser. Pois se faço só com *p0 dá-me erro w warnings, também não sei porque.

Edited by Baptistazito
Link to comment
Share on other sites

Peço desculpa por estar outra vez a postar mas só à medida que as dúvidas vão surgindo é que as vou tendo.

Estou a tentar fazer o vetor dinâmico dentro da estrutura. Confesso que não sei muito bem o que estou a fazer pois nunca tinha feito e tou a inventar um bocado, para não dizer praticamente tudo por isso gostaria que me pudessem aconselhar sobre o que está mal aqui?!


struct Pessoas
{
int info;
int ligacao;
   int nPartilhas; //numero de partilhas(tamanho do array partilhas)
int *partilhas;
struct Pessoas *prox;

};


void adiciona_partilha(struct Pessoas * p0, int nPessoa)
{
struct Pessoas *p = p0;
while(p != NULL){
 if(p->info == nPessoa){
  p->nPartilhas = (p-> nPartilhas) + 1; // incrementa numero de partilhas
  p->partilhas = malloc(sizeof (p->partilhas)*p->nPartilhas); //aloca partilhas
  p->partilhas[p->nPartilhas] = nPessoa;
 }
 p = p->prox;
}
}
Edited by Baptistazito
Link to comment
Share on other sites

código não testado : feito de cabeça ...

#define PARTILHAS_DEFAULT_INCREMENT 8

struct Pessoa
{
   struct Pessoa * prox;

   int info; // vou assumir que este valor é identificador da pessoa
             // isso que dizer que é único para cada pessoa
   int ligacao;

   struct {
       int * lista; // array que guarda os valores de partilha
       int tamanho; // tamanho do array
       int numero;  // numero de elementos guardados no array
       int inc;     // número de espaços adicionais a serem adicionados ao
                    // array quando for necessário redimencionar-lo
   } partilhas;
};

/**
* @brief Função usada para adicionar um novo nó à lista de pessoas
*
* @param lista   Ponteiro para a lista de pessoas onde o novo nó será inserido
* @param info    Valor identificador da pessoa criada/inserida
* @param ligacao Valor de ligação a ser atribuido à pessoa
* @param inc     Valor de incremento do array de partilhas
*
* @return O valor de 0 (zero) caso a inserção tenha ocurrido com sucesso, ou os
*         seguintes valores de erro:<br />
*         -1 : erro de alocação de memória<br />
*         -2 : pessoa já existente com o valor identificador de "info"
*/
int listaAdicionarPessoa(struct Pessoa ** lista,
                        int info,
                        int ligacao,
                        int inc)
{
   struct Pessoas * novo = NULL, * iter = NULL;

   // alocar memória para o novo nó da lista ligada
   if ((novo = calloc(1, sizeof(struct Pessoa))) == NULL)
       return -1;

   // guardar a informação da pessoa
   novo->info = info;
   novo->ligacao = ligacao;
   novo->partilhas.inc = inc;

   // verificar se a lista não se encontra vazia
   if (*lista != NULL)
   {
       // verificar se o primeiro elemento da lista tem um valor de "info"
       // superior ao do elemento a ser inserido
       if ((*lista)->info > info)
       {
           // inserir o nó criado à cabeça da lista
           novo->prox = *lista;
           *lista = novo;
       }
       else
       {
           // procurar pela posição da lista onde inserir o nó criado
           // (ordenado pelo valor de info)
           for(iter = *lista;
               iter->prox != NULL && iter->info < info;
               iter = iter->prox)
               /* void */;

           // verificar se o valor de info já está inserido na lista
           if (iter->info == info)
               return -2;

           // inserir o nó criado na posição iterada da lista
           novo->prox = iter->prox;
           iter->prox = novo;
       }
   }
   else
       // definir o nó criado como o único no da lista
       *lista = novo;

   return 0;
}

/**
* @brief Função usada para adicionar um novo elemento à lista de partilhas de
*        uma pessoa da lista de pessoas
*
* @param lista    Ponteiro para a lista de pessoas que contem a pessoa ao qual
*                 o valor de partinha será adicionado
* @param info     Valor identificador da pessoa
* @param partilha Valor de partilha a ser atribuido à pessoa
*
* @return O valor de 0 (zero) caso a inserção tenha ocurrido com sucesso, ou os
*         seguintes valores de erro:<br />
*         -1 : a lista se encontra vazia<br />
*         -2 : a pessoa não foi encontrada<br />
*         -3 : erro na alocação de memória<br />
*         -4 : erro no redimensionamento da memória alocada
*/
int listaAdicionarPartilha(struct Pessoa ** lista,
                          int info,
                          int partilha)
{
   struct Pessoas * iter = NULL;
   int * aux = NULL;

   if (*lista == NULL)
       return -1;

   for(iter = *lista;
       iter->prox != NULL && iter->info != info;
       iter = iter->prox)
       /* void */;

   if (iter == NULL)
       return -2;

   // verificar se não existe espaço no array para guardar o valor de partilha
   if (iter->partilhas.tamanho == iter->partilhas.numero)
   {
       // verificar se o array se encontra ainda por ser alocado
       if (iter->partilhas.array == NULL)
       {
           // alocar o array de partilhas
           if ((iter->partilhas.array = malloc(inc * sizeof(int))) == NULL)
               return -3;
       }
       else
       {
           // redimensionar o array de partilhas
           if ((aux = realloc(iter->partilhas.array,
                              (inc + ingo->partilhas.tamanho) * sizeof(int))) == NULL)
               return -4;

           iter->partilhas.array = aux;
       }

       // guardar o novo tamanho do array
       iter->partilhas.tamanho += inc;
   }

   // adicionar o valor de partilha à lista de partilhas da pessoa
   iter->partilhas.array[iter->partilhas.numero] = partilha
   ++iter->partilhas.numero;

   return 0;
}

int main(void)
{
   struct Pessoa * lista;

   // falta verificação de resultados de retorno de erro

   // adicionar duas novas pessoas
   listaAdicionarPessoa(&lista, 1, 1, PARTILHAS_DEFAULT_INCREMENT);
   listaAdicionarPessoa(&lista, 2, 2, PARTILHAS_DEFAULT_INCREMENT);

   // adicionar uma partilha com o valor de 1 à pessoa com o valor de "info" 2
   listaAdicionarPartilha(&lista, 2, 1);
}
Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

baos só agora cheguei a casa e agora é que tive tempo para pegar nisto e "estudar" o teu código que me causaram mais 1000 dúvidas.lol. Agradeço-o mas, e uma vez que não fui eu que o fiz é de dificil interpretação para mim. No problema em questão eu sei à partida o número total de Pessoas e de Partilhas, e por isso ainda antes de ler qualquer partilha, crio uma lista de pessoas vazia. Em seguida à medida que vou lendo as partilhas adiciono-as às pessoas respetivas, aí que possa descartar uma inserção ordenada de pessoas. Não sei é à partida quantas partilhas, nem quais, há por pessoa. Compreendo as variáveis postas por ti aí na struct no entanto não percebo qual a vantagem de uma struct dentro da struct além de me confundir um pouco mais. Por isso e não querendo parecer mal agradecido preferia que me dissesses o que tenho mal no meu código ou como o faria, ou então se puderes a vantagem da tua ideia em relação à minha ficaria agradecido.

Edited by Baptistazito
Link to comment
Share on other sites

Para começar tens na tua estrutura uma coisa que eu não gosto de fazer, que usar a mesma estrutura para representar uma pessoa e uma lista de pessoas (o código do HHH faz o mesmo).

Quanto à função de adição, dentro do ciclo estás sempre a alocar um novo array, o que está errado. Antes de inserir um novo elemento, precisas de testar se precisas de alocar o array, realocar o array, ou não fazer nada. Para corrigires a tua função, podes basear-te no seguinte código do HHH:

    // verificar se não existe espaço no array para guardar o valor de partilha
   if (iter->partilhas.tamanho == iter->partilhas.numero)
   {
       // verificar se o array se encontra ainda por ser alocado
       if (iter->partilhas.array == NULL)
       {
           // alocar o array de partilhas
           if ((iter->partilhas.array = malloc(inc * sizeof(int))) == NULL)
               return -3;
       }
       else
       {
           // redimensionar o array de partilhas
           if ((aux = realloc(iter->partilhas.array,
                              (inc + ingo->partilhas.tamanho) * sizeof(int))) == NULL)
               return -4;

           iter->partilhas.array = aux;
       }

       // guardar o novo tamanho do array
       iter->partilhas.tamanho += inc;
   }

   // adicionar o valor de partilha à lista de partilhas da pessoa
   iter->partilhas.array[iter->partilhas.numero] = partilha
   ++iter->partilhas.numero;
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.