Jump to content
alphasil

Ordenação, a vossa opinião sff

Recommended Posts

alphasil

Olà

Pedem-me para ordenar esta estrutura pelo titulo.

Estrutura

typedef struct liv
{
   char isbn[20], titulos[100];
   char autores[10][100];
   double preco;
}LIVRO;

Função criada por mim.

int orderByTitle(LIVRO livros[])
{
   int i, j;
   LIVRO aux;
   for(i=0;i<MAX;i++)
   {
       for(j=0; j<MAX-1; j++)
       {
           if(strcmp(livros[j].titulos, livros[j+1].titulos)>0)
           {
               aux =livros[j];
               livros[j]=livros[j+1];
               livros[j+1]= aux;
           }
       }
   }
   return 0;
}

Está correta?

Agora tive problemas porque costumo criar funçoes de odenação usando um array auxiliar e usar a função strcpy.

Aqui não pude usar, alguém me consegue explicar porquê??

Obrigado

Edited by pmg
GeSHi adicionada ao segundo bloco de codigo

Share this post


Link to post
Share on other sites
brunoais

Está correta?

Depende da relação entre o numero de elementos usados em livros e do valor em MAX

Agora tive problemas porque costumo criar funçoes de odenação usando um array auxiliar e usar a função strcpy.

Aqui não pude usar, alguém me consegue explicar porquê??

Fácil! LIVRO não é um char array.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
pmg

A variavel aux ja contem o array auxiliar. De facto contem 3 arrays auxiliares e eles sao inteiramente copiados com as atribuicoes, substituindo o strcpy.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
alphasil

Então quer dizer que pondo este código (atenção que é feito a mão e não no pc) estaria certo.

Depende do número de elementos?? Bem o max é 1400, mas por acaso só pus 4.

Vou para o próximo exercício...recursividade de

se n<=7, seq(n)=10

se n>7, seq(n)= 3*n+seq(n-1)-21

A minha dúvida é a seguinte,

se o n introduzido for menor que 7, assume-se que é 10, certo?

Share this post


Link to post
Share on other sites
Flinger

Não está correcto... LIVRO é uma estrutura não um apontador para estrutura, logo não podes simplesmente fazer aux=livro[j]. Ou copias campo a campo ou usas algo como o memcpy para te copiar o conteúdo inteiro.

Share this post


Link to post
Share on other sites
alphasil

Oi

Mas se ponho com strcpy:

int i, j;
   char aux[199]; //Declaro outra estrutura igual
   for(i=0;i<MAX;i++)
   {
    for(j=0; j<MAX-1; j++)
    {
	    if(strcmp(livros[j].titulos, livros[j+1].titulos)>0)
	    {
		    strcpy(aux,livros[j]);
		    strcpy(livros[j],livros[j+1]);
		    strcpy(livros[j+1],aux);
	    }
    }
   }

Dá-me issto:

error: incompatible type for argument 2 of 'strcpy'|

c:\mingw\bin\..\lib\gcc\mingw32\4.6.2\..\..\..\..\include\string.h|45|note: expected 'const char *' but argument is of type 'LIVRO'|

D:\2012\c_exe\Pergunta 1 exame 09_06\main.c|85|error: incompatible type for argument 1 of 'strcpy'|

c:\mingw\bin\..\lib\gcc\mingw32\4.6.2\..\..\..\..\include\string.h|45|note: expected 'char *' but argument is of type 'LIVRO'|

D:\2012\c_exe\Pergunta 1 exame 09_06\main.c|85|error: incompatible type for argument 2 of 'strcpy'|

c:\mingw\bin\..\lib\gcc\mingw32\4.6.2\..\..\..\..\include\string.h|45|note: expected 'const char *' but argument is of type 'LIVRO'|

D:\2012\c_exe\Pergunta 1 exame 09_06\main.c|86|error: incompatible type for argument 1 of 'strcpy'|

c:\mingw\bin\..\lib\gcc\mingw32\4.6.2\..\..\..\..\include\string.h|45|note: expected 'char *' but argument is of type 'LIVRO'|

Isto com o srcpy

Share this post


Link to post
Share on other sites
Flinger

o strcpy copia strings, não estruturas. Ou usas o strcpy para copiar campo a campo:

strcpy(aux.isbn,livros[j].isbn);
strcpy(aux.titulo,livros[j].titulo);
...

Ou usas o memcpy para te copiar a estrutura inteira.

Share this post


Link to post
Share on other sites
alphasil

Oi

Só preciso de ordenar o titulo por isso pus assim.

int orderByTitle1(LIVRO livros[])
{
int i, j;
LIVRO aux; //Declaro outra estrutura igual
for(i=0;i<MAX;i++)
{
 for(j=0; j<MAX-1; j++)
 {
	 if(strcmp(livros[j].titulos, livros[j+1].titulos)>0)
	 {
		 strcpy(aux.titulos,livros[j].titulos);
		 strcpy(livros[j].titulos,livros[j+1].titulos);
		 strcpy(livros[j+1].titulos,aux.titulos);
	 }
 }
}
return 0;
}

Então deixa ver se percebi uma coisa, se tiver uma estrutura e quiser ordenar um campo tenho de usar o que me disseste?

Edited by alphasil

Share this post


Link to post
Share on other sites
alphasil

Oi HHH, então tenho de fazer para todos??

Por isso valia 4 valores :)

Já vou fazer...

Obrigado

Share this post


Link to post
Share on other sites
HappyHippyHippo

usa o memcpy como te disseram

o strcpy copia strings, não estruturas. Ou usas o strcpy para copiar campo a campo:

Ou usas o memcpy para te copiar a estrutura inteira.


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

HHH, nunca usei o memcpym, já vi o que o flinger pôs mas fiquei meio cego a ver aquilo lol

Já alterei, ficou assim:

{
		 strcpy(aux.isbn,livros[j].isbn);
		 strcpy(aux.titulos,livros[j].titulos);
		 strcpy((char*)aux.autores,(char*)livros[j].autores);
		 aux.preco=livros[j].preco;
		 strcpy(livros[j].isbn,livros[j+1].isbn);
		 strcpy(livros[j].titulos,livros[j+1].titulos);
		 strcpy((char*)livros[j].autores,(char*)livros[j+1].autores);
		 livros[j].preco=livros[j+1].preco;
		 strcpy(livros[j+1].isbn,aux.isbn);
		 strcpy(livros[j+1].titulos,aux.titulos);
		 strcpy((char*)livros[j+1].autores,(char*)aux.autores);
		 livros[j+1].preco=aux.preco;
	 }

Está correto?

Agora o que se passa é que não me imprime nada

chamo a função, faço um print para ver se passa, e passa, mas não imprime nada.

writeBooks(livros,valor); //envia a função estes parametros
orderByTitle1(livros);
printf("passei"); //Imprime esta linha
for(i=0;i<2;i++)
{
	printf("%s", livros->titulos); //Não imprime nada
}

Edited by alphasil

Share this post


Link to post
Share on other sites
Flinger

{
		 strcpy(aux.isbn,livros[j].isbn);
		 strcpy(aux.titulos,livros[j].titulos);
		 strcpy((char*)aux.autores,(char*)livros[j].autores);
		 aux.preco=livros[j].preco;
		 strcpy(livros[j].isbn,livros[j+1].isbn);
		 strcpy(livros[j].titulos,livros[j+1].titulos);
		 strcpy((char*)livros[j].autores,(char*)livros[j+1].autores);
		 livros[j].preco=livros[j+1].preco;
		 strcpy(livros[j+1].isbn,aux.isbn);
		 strcpy(livros[j+1].titulos,aux.titulos);
		 strcpy((char*)livros[j+1].autores,(char*)aux.autores);
		 livros[j+1].preco=aux.preco;
	 }

Está correto?

Ainda não :D

Não te adianta fazer um cast da matriz autores para char *... não é assim que deixa de ser uma matriz e passa a ser uma string... o strcpy apena copia strings, por isso, para copiares o campo autores tens de copiar posição a posição também.

A outra hipótese é usar o memcpy como te disse. O memcpy copia-te um bloco de memória integralmente de um sítio para o outro.

void *memcpy(void *dest, const void *src, size_t n);

dest, é para onde queres copiar, neste caso (aux=livros[j]), o endereço da tua variável aux.

src, é o endereço de onde tu queres copiar, neste caso o endereço do livro que queres copiar.

n é a quantidade de bytes que tu queres copiar. Como queres copiar uma estrutura LIVRO, é o tamanho dessa tua estrutura (dica: sizeof)

Share this post


Link to post
Share on other sites
pmg

Para copiar uma estrutura completa (atenção aos ponteiros! -- irrelevante neste caso especifico) podes usar atribuicoes normais

struct liv a = {0}, b = {0}, tmp;
/* change a and b */
tmp = a;
a = b;
b = tmp;

Não é preciso andar a fazer strcpy ou memcpy membro a membro.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
Flinger

Para copiar uma estrutura completa (atenção aos ponteiros! -- irrelevante neste caso especifico) podes usar atribuicoes normais

struct liv a = {0}, b = {0}, tmp;
/* change a and b */
tmp = a;
a = b;
b = tmp;

Não é preciso andar a fazer strcpy ou memcpy membro a membro.

oi!!! :confused: acho que me perdi... De facto fui confirmar e é possível mas não percebi como...

Andei a minha vida todo enganado nisto :S

Share this post


Link to post
Share on other sites
alphasil

Bem se tu está perdido, então imagina eu...lool

Então voltamos ao que pus inicialmente...o que o PMG foi examente o que fiz

               aux =livros[j];
		    livros[j]=livros[j+1];
		    livros[j+1]= aux;

Share this post


Link to post
Share on other sites
Flinger

Pois...

aux=vect[4];
0x0804850a <main+214>: lea    -0x78(%ebp),%ecx
0x0804850d <main+217>: lea    -0xec(%ebp),%edx
0x08048513 <main+223>: mov    $0x70,%eax
0x08048518 <main+228>: mov    %eax,0x8(%esp)
0x0804851c <main+232>: mov    %edx,0x4(%esp)
0x08048520 <main+236>: mov    %ecx,(%esp)
0x08048523 <main+239>: call   0x804837c <memcpy@plt>

Resumindo, o próprio compilador faz aquilo que eu te disse para fazer :D Isto não esteve sempre assim, pois não png?

Share this post


Link to post
Share on other sites
pmg

Isto não esteve sempre assim, pois não png?

Sim, pelo menos desde 1989, desde a primeira versao do Standard :)

E suspeito que já era assim muito antes, talvez até desde 1972, a primeira versão do compilador :D

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
Flinger

Gostava de saber como consegui andar 15 anos enganado a este respeito...

@alphasil

Na primeira linha do código tens a instrução, nas seguintes tens o assembly que é gerado pelo compilador para essa instrução.

Basicamente ele carrega os 2 endereços das estruturas para 2 registos do processador (as 2 instruções "lea"), depois carrega o tamanho da estrutura para outro registo (1.º mov), de seguida carrega os valores desses 3 registos para a stack de execução (os 3 movs seguintes) e chama a função memcpy, que vai usar os valores carregados na stack como argumentos.

Só não percebi é porque é que se está a borrifar para o __attribute__((packed)) que coloquei na estrutura, mas provavelmente é porque as variáveis não estão alinhadas.

Será que isto se aplica para arm?

Edited by Flinger

Share this post


Link to post
Share on other sites
pmg

Gostava de saber como consegui andar 15 anos enganado a este respeito...

É por isso que não se fazem funções que recebem (ou devolvem) estruturas (grandes); passam-se ponteiros para as estruturas senão é feita uma cópia completa da estrutura.

void foo(struct grande dados) { /* dados é uma cópia do original */ }
void bar(struct grande *pdata) { /* pdata aponta para o original */ }
void qux(const struct grande *pdata) { /* pdata aponta para o original,
                                         mas é prometido que não vai ser alterado */ }

Edited by pmg
const

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
alphasil

Isto está muito engraçado, o meu printf da ordenação não me dá nada !!!!

orderByTitle1(livros);
printf("passei");
   for(i=0;i<2;i++)
   {
    printf("%s", livros->titulos);
 }

Se puser um print dentro do ciclo funciona o print posto mas não imprime na mesma o livros->titulos :(

Share this post


Link to post
Share on other sites
Flinger

Eu desanimei :( não tento ensinar mais nada a ninguém :P

Não imprime nada ou imprime com a ordem errada?

Se não imprime mesmo nada tenta pôr um '\n'

printf("%s\n", livros->titulos);

EDIT: qual é o tipo de livros? Não queres antes

printf("%s\n", livros[i].titulo);

Edited by Flinger

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • 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.