• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Guest tsenart

Novamente os apontadores

6 mensagens neste tópico

Pessoal... Não consigo perceber o que está errado.

Dá-me segmentation fault quando executa a função inic()....

#include <stdio.h>
#include <strings.h>

#define MIN_GRAMAS 900
#define MAX_GRAMAS 1600
#define PESO_TAB 1000


typedef struct
{
float peso_gramas;
char nome[50];
} TABULEIRO;

float total_gr = 0;
int ntabs = 0;
int nalunos = 0;


char *MenuPrincipal[] = {
"1 - Iniciar Refeição",
"0 - Sair",
NULL			};

char Menu(char *Opcoes[])
{
	int i;
	char ch;

	while(1)
	{
		printf("\n\n\n\n");
		for(i = 0; Opcoes[i] != NULL; i++)
			printf("\t\t%s\n\n", Opcoes[i]);

		printf("\t\tOpcao: ");
		ch = getchar(); fflush(stdin);
		for(i = 0; Opcoes[i] != NULL; i++)
			if(Opcoes[i][0] == ch)
				return ch;
	}
}

    void inic(TABULEIRO *ptabs[])
    {
        int i;

        for(i = 0; i < 10; i++)
        {
           ptabs[i]->peso_gramas = 0;
           strcpy(ptabs[i]->nome, "0");

        }
    }


void iniciar_refeicao(TABULEIRO *ptab[], int ntabs, int nalunos)
{
	int i;

	for(i = 0; i < ntabs; i++)
	{
		printf("\t\t\n\nTABULEIRO %d\n", i+1);
		printf("\t\tPeso do tabuleiro com a comida(em gramas)-> "); scanf("%f", &ptab[i]->peso_gramas);
		printf("\t\tNome da receita-> "); fgets(ptab[i]->nome, 50, stdin);
		total_gr += ptab[i]->peso_gramas - PESO_TAB;
	}

	printf("\nCada alunos só pode comer %f gramas de comida.\n", total_gr/nalunos);
}



int main()
{
	char op;
	TABULEIRO tabs[10];

	inic(&tabs);

	while((op = Menu(MenuPrincipal)) != '0')
	{
		switch(op)
		{
		case '1':   printf("\n\nQuantos tabuleiros foram cozinhados?\n");
			scanf("%d", &ntabs);
			printf("Quantos alunos estão no refeitório?\n");
			scanf("%d", &nalunos);
			iniciar_refeicao(&tabs, ntabs, nalunos);
			break;
		default : printf("\nOpcao invalida\n");
		}
	}
	return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

muda a função inic de "TABULEIRO *ptabs[]" para "TABULEIRO ptabs[]" e retira o "&" quando a invocas, só complicam a função (e aparentemente estás a fazer as coisas de maneira errada)...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Thankz.... Funcionou.

Mas não percebi porque pois se eu quero um apontador para uma array...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Thankz.... Funcionou.

Mas não percebi porque pois se eu quero um apontador para uma array...

um array já é um apontador...

acho estranho isso estar a funcionar, não te deu nenhum warning? é que onde tens 'ptabs[ i ]->' acho que devia estar 'ptabs[ i ].'

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não é assim que as coisas funcionam. /*edit: (escrevi antes do Rui Carlos, isto é dirigido ao Tsenart) */

Tu se queres passar um vector por referência, passas um único apontador, que é o apontador para a primeira posição do vector.

Tu quando tens um vector definido "v[10]", por exemplo.

"v" representa o apontador para a primeira posição do vector. Fazer "v[0]" e "*v" é a mesma coisa, tal como "&v[0]" e "v" são a mesma coisa.

Usar os "[]" ou usar "*" tem o mesmo significado: aceder ao conteúdo de uma dada posição, com uma ligeira diferença: ao elemento é incrementado o que está no interior dos "[]".

Por exemplo, "*(v+5)" == "v[5]".

Dado isto, tu se queres passar um vector para uma função, passas somente a sua posição inicial. (ao passar um apontador estás automaticamente a passa-lo por referência. Não há maneira (que eu conheça) de passar um vector por valor em C)

ou seja, "inic(tabs);"

Por outro lado, se o queres receber, tanto:

"void inic(TABULEIRO ptabs[])" como "void inic(TABULEIRO *ptabs)" funcionam.

Como podes ver pelo que te expliquei em cima, estás a passar um apontador, recebes um apontador.

PS: Eu pessoalmente uso sempre "*" quando me quero referir a um apontador. Sei que se passo um apontador, recebo um apontador, ponto final. A única excepção é quando acedo a uma posição do vector, onde usar v[5] é manifestamente mais legível do que *(v+5).

Como nota adicional, percorrer um ciclo usando "v[ i ]" ou "i[v]" (incrementando o i em ambos os casos) tem exactamente o mesmo significado.

A explicação está em cima. Alguns compiladores dão, no entanto, warning, porque controlam o facto de estares a "aceder a uma posição de um inteiro".

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não é assim que as coisas funcionam. /*edit: (escrevi antes do Rui Carlos, isto é dirigido ao Tsenart) */

Tu se queres passar um vector por referência, passas um único apontador, que é o apontador para a primeira posição do vector.

Tu quando tens um vector definido "v[10]", por exemplo.

"v" representa o apontador para a primeira posição do vector. Fazer "v[0]" e "*v" é a mesma coisa, tal como "&v[0]" e "v" são a mesma coisa.

Usar os "[]" ou usar "*" tem o mesmo significado: aceder ao conteúdo de uma dada posição, com uma ligeira diferença: ao elemento é incrementado o que está no interior dos "[]".

Por exemplo, "*(v+5)" == "v[5]".

Dado isto, tu se queres passar um vector para uma função, passas somente a sua posição inicial. (ao passar um apontador estás automaticamente a passa-lo por referência. Não há maneira (que eu conheça) de passar um vector por valor em C)

ou seja, "inic(tabs);"

Por outro lado, se o queres receber, tanto:

"void inic(TABULEIRO ptabs[])" como "void inic(TABULEIRO *ptabs)" funcionam.

Como podes ver pelo que te expliquei em cima, estás a passar um apontador, recebes um apontador.

PS: Eu pessoalmente uso sempre "*" quando me quero referir a um apontador. Sei que se passo um apontador, recebo um apontador, ponto final. A única excepção é quando acedo a uma posição do vector, onde usar v[5] é manifestamente mais legível do que *(v+5).

Como nota adicional, percorrer um ciclo usando "v[ i ]" ou "i[v]" (incrementando o i em ambos os casos) tem exactamente o mesmo significado.

A explicação está em cima. Alguns compiladores dão, no entanto, warning, porque controlam o facto de estares a "aceder a uma posição de um inteiro".

Muito obrigado warrior.

Muito util esta informação.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora