Coisas simples que eu não sei, mas que vocês de certeza que me podem ajudar :D

FrostPt

Membro
Ok, sou eu mais uma vez, com um problema aparentemente simples, mas que já está farto de aparecer como um erro e que eu não sei resolvê-lo. O que acontece é o seguinte, faço um 'if' normal e quero um 'else' logo a seguir, concluo o código e quando dou por mim tenho isto:

erro: ‘else’ without a previous ‘if’

Alguém me pode explicar se é necessário, qualquer coisa antes do 'if' e a mesma coisa para o 'else' ? :/

Se calhar é mais produtivo meter o código e onde se encontra os erros, é capaz de facilitar a análise e posterior resolução. Ok, então ai vai:

#include <stdio.h>
#include <stdlib.h>

int main ()
{
int euros, E2, E1, cent, C50, C20, C10, C5, C2, C1, aux;

printf ("\nNesse montante, quantos euros há?\n");
scanf ("%d", %euros);

E2 = euros/2; /* Para saber quantas moedas de 2€ são necessárias */
if (euros%2 != 0); /* Caso o montante seja um número ímpar, ou seja se o resto da divisão for igual a 1 */
{
E1 = 1; /* Temos de somar 1€ */
}
else
{
E1 = 0; /* Caso contrário, sendo o número par, não é necessário somar nada */
}

printf ("\nNesse montante, quantos cêntimos há?\n");
scanf ("%d", %cent);

aux = cent;

if (aux != 0); /* Se for diferente de 0 cêntimos */
{
if (aux >= 50);
{
aux - 50;
C50 = 1; /* temos 1 moeda de 50 cêntimos */
}
if (aux >= 20);
{
aux - 20;
C20 = 1; /* temos 1 moeda de 20 cêntimos */
}
if (aux >= 10);
{
aux - 10;
C10 = 1; /* temos 1 moeda de 10 cêntimos */
}
if (aux >= 5);
{
aux - 5;
C5 = 1; /* temos 1 moeda de 5 cêntimos */
}
if (aux >= 2);
{
aux - 2;
C2 = 1; /* temos 1 moeda de 2 cêntimos */
}
if (aux >= 1);
{
aux - 1;
C1 = 1; /* temos 1 moeda de 1 cêntimos */
}
}
else
{
cent = 0;
}

printf ("\nNesse montante há %d€ e %f cêntimo(s)\n", &euros, &cent);

printf ("%d moeda(s) de 2€\n", &E2);
printf ("%d moeda de 1€\n", &E1);
printf ("%d moeda de 50 cêntimos\n", &C50);
printf ("%d moeda de 20 cêntimos\n", &C20);
printf ("%d moeda de 10 cêntimos\n", &C10);
printf ("%d moeda de 5 cêntimos\n", &C5);
printf ("%d moeda de 2 cêntimos\n", &C2);
printf ("%d moeda de 1 cêntimo\n", &C1);

return 0;
}

Como já deu para perceber, após a leitura do número de euros e de cêntimos é feito um conjusto de intruções que têm como objectivo:
- Calcular quantas moedas de 2€ são necessárias, seguidamente calcula quantas de 1€ são necessárias e assim sucessivamente.

Quanto aos erros:

lab2_5.c: Na função ‘main’:
lab2_5.c:9:19: erro: expected expression before ‘%’ token
lab2_5.c:16:6: erro: ‘else’ without a previous ‘if’
lab2_5.c:22:19: erro: expected expression before ‘%’ token
lab2_5.c:30:14: aviso: statement with no effect [-Wunused-value]
lab2_5.c:35:14: aviso: statement with no effect [-Wunused-value]
lab2_5.c:40:14: aviso: statement with no effect [-Wunused-value]
lab2_5.c:45:14: aviso: statement with no effect [-Wunused-value]
lab2_5.c:50:14: aviso: statement with no effect [-Wunused-value]
lab2_5.c:55:14: aviso: statement with no effect [-Wunused-value]
lab2_5.c:59:6: erro: ‘else’ without a previous ‘if’
lab2_5.c:64:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:64:6: aviso: formato ‘%f’ expects argument of type ‘double’, but argument 3 has type ‘int *’ [-Wformat]
lab2_5.c:66:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:67:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:68:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:69:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:70:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:71:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:72:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
lab2_5.c:73:6: aviso: formato ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]

Desculpem o tamanho do post e estar a ser bastante chato, mas agradeço desde já a quem me possa ajudar ^^
 
Tira os pontos e virgulas depois de todos os if(...), vai ver como se guardam valores em variáveis e como se mostram ao utilizador. Tens aí vários erros.
 
Última edição:
Ok, já consegui meter a funcionar, tirei todos os pontos e vírgulas que tinha a seguir aos if's, segui uma sugentão de não meter chavetas se fosse só uma linha de código e estive a mudar uma pequena parte do código, depois por burrice minha n reparei que nos printf's tinha lá o 'e' comercial -.- pronto tirei isso e já está a funcionar correctamente :D
Obrigado pela resposta ^^
 
Já agora umas explicações básicas:

; <- Fim de instrução, logo se escreves if (condição); {coisas}, a instrução "if" termina imediatamente depois de começar, e o bloco {coisas} não tem nada a ver com o "if"

{} <- Bloco de código, ou seja, se escreves if (condição) {coisas}, o bloco coisas é executado completo ou nada (claro que depois pode estar subdividido em outros blocos), a mesma coisa se aplica nas declarações de funções, etc etc.

Quanto ao retirar as chavetas quando o bloco tem apenas 1 instrução, é uma questão estética (tal como meter cada instrução numa linha, indentação, etc), na minha opinião as chavetas deviam estar sempre presentes porque facilita a leitura do código:

if (condicao) {
coisas;
} else {
outras;
coisas;
}

parece-me mais fácil de ler do que

if (condicao)
coisas;
else {
outras;
coisas;
}
 
Pois, também sou da opinião que as chavetas facilitam mais a leitura, e em alguns compiladores ajuda mesmo a saber onde estas fecham.

E pronto tens já problema resolvido das ; nos lugares errados, penso que pensasses que se metia ao final de cada linha que não seja chaveta certo? ;)
 
Era isso mesmo, queria agradecer ao 'cbangueses' pela explicação, ainda sou bastante inexperiente por isso até as coisas mais básicas me podem ajudar e sinceramente pensava mesmo que os pontos e vírgula se metiam sempre após cada linha.

Só um aparte e se calhar até vou criar um post diferente, mas qual é a diferença emtre malloc's e calloc's?
 
mas qual é a diferença entre malloc's e calloc's?

calloc inicializa a memória a zero (logo é mais lento)
malloc deixa sem inicializar (logo é mais rapido)

void *malloc(size_t size);

The function allocates an object of size_t size (size_t = int, char, float...etc), and returns the address of the object if successful; otherwise, it returns a null pointer. The values stored in the object are indeterminate. You can safely convert the return value to an object pointer of any type whose size is not greater than size.

void *calloc(size_t nelem, size_t size);

The function allocates an array object containing nelem (number of elements) each of size_t size, stores zeros in all bytes of the array, and returns the address of the first element of the array if successful; otherwise, it returns a null pointer. You can safely convert the return value to an object pointer of any type whose size in bytes is not greater than size.
 
calloc inicializa a memória a zero (logo é mais lento)
malloc deixa sem inicializar (logo é mais rapido)

Eu tenho um bocado de receio de perguntar isto, mas dêem-me um desconto

Em termos práticos qual é a vantagem de iniciar a memória a zero?
Quais as situações em que devo usar malloc em vez de calloc e vice-versa?
 
Depende do teu objectivo =P
Se vais alocar memória para depois inicializares com a tua própria informação ( o mais comum), usas o malloc.
Se queres que ela seja inicializada a zero, usas o calloc.

Eu pessoalmente nunca usei o calloc. Uso sempre o malloc, mesmo quando quero inicializar a zero (acabo por fazer um memset a seguir)
 
Não é por nada, mas porque é que está atribuir o valor 0 ao cent, quanto já se sabe que é 0?

Penso que o if (cent != 0) não faz nada e o else muito menos.
 
Back
Topo