Cara você utiliza o gcc como compilador ? Pois pelo que eu saiba o gets não pertence mais a biblioteca padrão e deve se utilizar fgets em vez do gets. Pelo menos é o que vi em alguns sites, como esses: http://gcc.gnu.org/ml/gcc-help/1999-10n/msg00077.html
Cara, essas coisas de 'função perigosa', 'não indicada', 'uso errado', 'uso não recomendado' etc, é complicado.
Se formos ser rigorosos, vamos acabar programando da maneira como se programa em C pro Kernel do Linux, ou seja, de uma maneira bem otimizada e altamente rígida.
Nosso objetivo aqui no curso é ensinar iniciantes, para quem está começando mesmo a aprender. Creio que se formos ensinar todos esses detalhes e pormenores, vai acabar ficando complicado e desestimulante.
Mas informação nunca é demais, por isso agradecemos e vamos deixar seu comentário aí. Sinta-se a vontade para nos dar outras dicas como esse e sua opinião.
Poderia me explicar o uso de dois asterisco **pPos e (*(pTemp)).prox = *Pos?
Ta meio obscuro isso para mim ainda.
Obrigado
10 de agosto de 2013 às 06:19
Anônimo disse...
Olá,
Muito bom sua apostila. Observei ali que uma função recebe por referencia uma estrutura. Como seria se esta função recebesse por referencia uma estrutura vetor ?
eu nao entendi bem porque usar &(*car).anoFabricacao, tipo, o asterisco serve pra dizer que queremos o valor, e o "&", pra dizer que queremos o endereço, entao oque voce fez foi pegar o valor do ponteiro car, e depois pegar o endereço do valor do ponteiro. Nao da pra simplesmente colocar car.anoFabricacao, sem o "&" nem o "*"?
Ao usar (*car).anoFabricacao na função printf("Ano de Fabricaco: %d, (*car).anoFabricacao); , estamos mostrando o valor do campo anoFabricacao da struct CARRO.
Usando &(*car).anoFabricacao na funcao scanf("%d",&(*car).anoFabricacao); , estamos armazenando um valor que o usuário informou no campo anoFabricaco da struct CARRO.
Tambem estou com a duvida de um amigo acima que não foi respondido porque sua pergunta não foi entendida, mas é o seguinte, no caso do exemplo de criação de carro temos a struct: typedef struct { char modelo[30]; int ano, poras; }CARRO; daí se o enunciado pedisse pra cadastrar mais de um carro CARRO cars[3]; quando eu fosse preencher o modelo do primeiro carro por exemplo na função, como ficaria? Eu tentei fgets(cars[cont]->modelo,30,stdin); porem deu errado, mudei pra "gets" e tambem deu errado apresentando o erro "invalid type argument '->'".
Guilherme0890, nessa situação como se trata de um vetor ele próprio já é passado por referência, daí não precisa usar "*" nem "->" para alterar o valor do campo no array. A passagem para a função é feita de forma direta, apenas colocando o tamanho do array. Ex:void ler(carro novo[2]){ int cont; for(cont=0;cont<MAX;cont++){ fflush(stdin); printf("\nDigite os dados do veiculo %d\n",cont+1); printf("Digite o modelo do carro: "); gets(novo[cont].modelo); printf("Digite a cor do carro: "); gets(novo[cont].cor); .... dentro da main ... ler(novo);
E seu eu passar um vetor do tipo 'carro'como argumento para uma função? Como ficaria? Por exemplo: CARRO car[5]; Como passaria isso como argumento? E como a função seria declarada de modo a receber?
5 de maio de 2021 às 07:12
Antes de mais nada, vamos deixar bem claro que, à rigor, não existe passagem por referência em linguagem C.
Mas por que vemos tanto falarem sobre isso, se não existe?
Na verdade, o que existe é uma espécie de 'truque', que é passar o endereço de memória, através de ponteiros, para funções, simulando uma passagem por referência.
Então não há problema em falar de passagem por referência em C, apenas use seu bom senso.
Baixe o conteúdo do site: Apostila de C
Como alterar uma struct em uma função
Embora tenhamos explicado passo por passo como chegar na
função anterior, temos que assumir que fica um pouco confuso e complexo nosso
código:
&(*car).numPortas
Note também que colocamos o asterisco e o ponteiro em
parêntesis separado.
Consegue imaginar o motivo disso?
Vamos imaginar que em vez de: (*car).numPortas
Usássemos: *car.numPortas
Podemos interpretar isso de duas maneiras:
1. Estamos
tentando acessar o elemento ‘numPortas’, que é um membro da struct que é apontada pelo ponteiro ‘car’.
Que é o que vínhamos fazendo, usando parêntesis.
2. Estamos
tentando acessar o ponteiro ‘numPortas’, da estrutura ‘car’.
Mas ‘car’ não é uma struct, muito menos tem o membro ‘numPortas’.
Sabemos que ‘car’ é apenas um ponteiro pra uma struct, ou
seja, ele é um endereço de memória. E é isso o que acontece quando não
colocamos os parêntesis, pois para o C, o ponto final (.) tem procedência maior
que o asterisco (*).
Para evitar problemas, usamos o parêntesis em volta do
ponteiro ‘car’.
Mas ainda assim fica confuso, e em programação C, ficar
confuso não é legal. Por isso, criaram um operador que vai facilitar isso, o
->
-> é simplesmente um atalho que substitui o asterisco
e os parêntesis (é fácil esquecer e se confundir com estes), e com o ‘->’ a
coisa se torna bem óbvia.
Por exemplo, em vez de: *(ponteiro).
Escrevemos: ponteiro->
No nosso exemplo do carro, as duas linhas seguintes são
equivalentes:
scanf("%d", &(*car).anoFabricacao);
scanf("%d", &car->anoFabricacao);
Fica bem fácil de entender o: car -> anoFabricação
Exemplo: Alterando e exibindo structs através de funções
em C
Crie um programa na linguagem C que define a estrutura de
um carro, altere seus dados através de uma função (use passagem por referência
e o operador ->) bem como use outra
função para exibir os membros da struct.
Nosso código, agora fazendo uso do operador -> , será:
#include <stdio.h>
// Curso C Progressivo: www.cprogessivo.net
// O melhor curso de C! Online e gratuito !
// Apostila online, tutorial completo sobre
// a linguagem de programação C !
typedef struct
{
char modelo[30];
float potenciaMotor;
int anoFabricacao,
numPortas;
}CARRO;
void Exibe(CARRO car)
{
printf("\n\tExibindo carro\n");
printf("Modelo: %s\n", car.modelo);
printf("Motor: %.1f\n", car.potenciaMotor);
printf("Ano: %dn", car.anoFabricacao);
printf("%d portas\n", car.numPortas);
}
void Preenche(CARRO *car)
{
printf("Modelo do carro: ");
gets( car->modelo );
printf("Motor: ");
scanf("%f", &car->potenciaMotor);
printf("Ano: ");
scanf("%d", &car->anoFabricacao);
printf("Numero de portas: ");
scanf("%d", &car->numPortas);
}
int main(void)
{
CARRO fusca;
Preenche(&fusca);
Exibe(fusca);
return 0;
}
Bem mais fácil e óbvio de entender, não acham?
É importante entender bem o conceito do operador -> e
da passagem de estruturas para funções, pois faremos uso desses conhecimentos
mais a frente em nossa apostila de C, na seção de “Estrutura de dados III:
Listas, Filhas e Pilhas”.
postado por Programação Progressiva às 11:41 em 29 de mar. de 2013
12 Comentários
Fechar esta janela Ir para formulário de comentárioCara você utiliza o gcc como compilador ? Pois pelo que eu saiba o gets não pertence mais a biblioteca padrão e deve se utilizar fgets em vez do gets. Pelo menos é o que vi em alguns sites, como esses:
http://gcc.gnu.org/ml/gcc-help/1999-10n/msg00077.html
3 de junho de 2013 às 20:59
Olá Unknown,
Cara, essas coisas de 'função perigosa', 'não indicada', 'uso errado', 'uso não recomendado' etc, é complicado.
Se formos ser rigorosos, vamos acabar programando da maneira como se programa em C pro Kernel do Linux, ou seja, de uma maneira bem otimizada e altamente rígida.
Nosso objetivo aqui no curso é ensinar iniciantes, para quem está começando mesmo a aprender.
Creio que se formos ensinar todos esses detalhes e pormenores, vai acabar ficando complicado e desestimulante.
Mas informação nunca é demais, por isso agradecemos e vamos deixar seu comentário aí.
Sinta-se a vontade para nos dar outras dicas como esse e sua opinião.
4 de junho de 2013 às 03:36
Amigo o código:
void transfereTempPos( Pilha **pPos, Pilha **pTemp, Pilha *aux )
aux = (*(*pTemp)).prox; //(*p).x = 7.0; ou p->x = 7.0;
(*(*pTemp)).prox = *pPos;
*pPos = *pTemp;
*pTemp = aux;
Poderia me explicar o uso de dois asterisco **pPos e (*(pTemp)).prox = *Pos?
Ta meio obscuro isso para mim ainda.
Obrigado
10 de agosto de 2013 às 06:19
Olá,
Muito bom sua apostila. Observei ali que uma função recebe por referencia uma estrutura. Como seria se esta função recebesse por referencia uma estrutura vetor ?
forte a todos.
obrigado.
17 de setembro de 2013 às 08:49
Olá Anônimo,
O que você quer dizer com 'estrutura vetor' ? Não entendi bem.
17 de setembro de 2013 às 20:44
eu nao entendi bem porque usar
&(*car).anoFabricacao, tipo, o asterisco serve pra dizer que queremos o valor, e o "&", pra dizer que queremos o endereço, entao oque voce fez foi pegar o valor do ponteiro car, e depois pegar o endereço do valor do ponteiro. Nao da pra simplesmente colocar car.anoFabricacao, sem o "&" nem o "*"?
7 de dezembro de 2013 às 04:57
lixo virtual,
Ao usar (*car).anoFabricacao na função printf("Ano de Fabricaco: %d, (*car).anoFabricacao); , estamos mostrando o valor do campo anoFabricacao da struct CARRO.
Usando &(*car).anoFabricacao na funcao scanf("%d",&(*car).anoFabricacao); , estamos armazenando um valor que o usuário informou no campo anoFabricaco da struct CARRO.
Não sei se ficou claro, mas é isso.
16 de janeiro de 2014 às 13:17
Tambem estou com a duvida de um amigo acima que não foi respondido porque sua pergunta não foi entendida, mas é o seguinte, no caso do exemplo de criação de carro temos a struct:
typedef struct
{
char modelo[30];
int ano, poras;
}CARRO;
daí se o enunciado pedisse pra cadastrar mais de um carro
CARRO cars[3];
quando eu fosse preencher o modelo do primeiro carro por exemplo na função, como ficaria?
Eu tentei
fgets(cars[cont]->modelo,30,stdin);
porem deu errado,
mudei pra "gets" e tambem deu errado
apresentando o erro "invalid type argument '->'".
Como seria a forma correta?
10 de maio de 2015 às 19:13
Guilherme0890, nessa situação como se trata de um vetor ele próprio já é passado por referência, daí não precisa usar "*" nem "->" para alterar o valor do campo no array. A passagem para a função é feita de forma direta, apenas colocando o tamanho do array.
Ex:void ler(carro novo[2]){
int cont;
for(cont=0;cont<MAX;cont++){
fflush(stdin);
printf("\nDigite os dados do veiculo %d\n",cont+1);
printf("Digite o modelo do carro: ");
gets(novo[cont].modelo);
printf("Digite a cor do carro: ");
gets(novo[cont].cor);
....
dentro da main
... ler(novo);
19 de setembro de 2016 às 00:08
Por favor, alguem me de uma ajuda de como passar por referencia VETORES de STRUCT. Não estou conseguindo de jeito nenhum.
17 de agosto de 2017 às 09:50
Autor, então como devo prosseguir com alocação dinamica? Veja:
CARRO *fusca = (CARRO*)calloc(10, sizeof(CARRO));
strcpy( (*fusca[2]).modelo , "Gol" );
Esse formato não deveria funcionar também de acordo com o texto?
10 de agosto de 2019 às 16:10
E seu eu passar um vetor do tipo 'carro'como argumento para uma função? Como ficaria? Por exemplo:
CARRO car[5];
Como passaria isso como argumento? E como a função seria declarada de modo a receber?
5 de maio de 2021 às 07:12