Iniciação em C - Dúvidas

Compilaste o código?

Isso deveria ter dado erro a compilar

Não deu porque os erros foram cometidos quando escrevi aqui o code... Não devo ter usado o copiar/colar!

Sim, ele tem ai uns 2/3 erros no código ("" a mais faltam os {} e não há getch () ou é getchar())
Em todo o caso que valores estás a usar para num1 e num2?

Já corrigi. Penso que agora está correcto.

na multiplicaçao da resultado errado? acho que na multiplicaçao de inteiros podes usar int como reultado..
quanto a divisao eu normalmente faço:

float a;
int b, c;
a=(float)b/(float)c;

Faz diferença ter (float) (num1 / num2) ou ter float (num1 / num2) ou ter como tu colocaste ali????

porque como tu tens:
a=(float)(b/c);
ele primeiro faz b/c e so depois e que converte para float se nao me engano e isso da resultados errados

Eu lembrei-me se haveria ordem pela qual o programa executa os cálculos. Mas pensei que o float tivesse igual "direito" ao multiplicar, dividir, módulo (%), potências, raízes e etc.

Se assim fôr, qual é a diferença de transformar um valor numa variável antes ou depois de terem sido feitos cálculos com ela?

E se falarmos numa situação hipotética como se fosse possível armazenar um valor numa variável antes de declarar qual o tipo de variável, qual seria o formato do valor armazenado na variável? Ou seja, se desse para atribuir um valor a uma variável que fosse o resultado de uma divisão entre dois valores quaisquer, sem declararmos o tipo de variável e depois pedissemos para ser mostrado esse valor com o printf (), como seria apresentado o resultado?

O que eu queria saber com isto é se ao declararmos as variáveis como sendo de um tipo ou de outro, estamos a "obrigar" o programa a ler o valor daquela divisão de uma determinada forma consoante o tipo de variável e assim estarmos a limitar a precisão do resultado ou se independentemente do tipo de variável, o resultado será sempre exacto e preciso!!!

Não sei se me consegui fazer entender...

resumindo o que disse, substitui esta linha:
printf ("A divisão da: %f",(float) (num1 / num2));

por:
printf ("A divisão da: %f",(float)num1 / (float) num2));

Posso tentar isso e ver o que dá!!!
 
Posso tentar isso e ver o que dá!!!

Há diferença em fazer (float) (num1/num2) e (float) num1/(float) num2.

No 1º caso, é feito primeiro a divisão de 2 inteiros. Ou seja. se tiveres os inteiros 3 e 2 ao fazer a divisão dá 1 pois é o resultado da divisão inteira de 3 por 2. Ao fazer o cast para float ficas com 1.0

No 2º caso, como fazes o cast para float, o que está a acontecer, é que vais dividir 3.0 por 2.0 (aqui a parte decimal já interessa porque se tratam de float), e aí o resultado dá 1.5

Desculpa, não percebi!!

O que o diutsu disse é que basta pores ((float) num1)/num2, porque pegando no exemplo que dei em cima, ficas com 3.0 a dividir por 2 o que dá 1.5. Por isso mesmo é que ele disse que basta fazer o cast a um operador.

Quando fazes (float) num1, diz-se que fizeste um cast para float à variável num1.

Espero que tenha ficado mais claro agora
 
Última edição:
Há diferença em fazer (float) (num1/num2) e (float) num1/(float) num2.

No 1º caso, é feito primeiro a divisão de 2 inteiros. Ou seja. se tiveres os inteiros 3 e 2 ao fazer a divisão dá 1 pois é o resultado da divisão inteira de 3 por 2. Ao fazer o cast para float ficas com 1.0

No 2º caso, como fazes o cast para float, o que está a acontecer, é que vais dividir 3.0 por 2.0 (aqui a parte decimal já interessa porque se tratam de float), e aí o resultado dá 1.5

Então quer dizer que a linguagem C interpreta logo à partida os números e/ou algarismos e/ou resultados de operações como números inteiros e considera apenas as partes inteiras de divisões que não têm resto zero?

O que o diutsu disse é que basta pores (float) num1/num2, porque pegando no exemplo que dei em cima, ficas com 3.0 a dividir por 2 o que dá 1.5. Por isso mesmo é que ele disse que basta fazer o cast a um operador.

Quando fazes (float) num1, diz-se que fizeste um cast para float à variável num1.

Espero que tenha ficado mais claro agora

Ah sim, percebi agora...

Ali o termo operador eu entendi como um +, ou um -, ou um *, ou um /.
 
Então quer dizer que a linguagem C interpreta logo à partida os números e/ou algarismos e/ou resultados de operações como números inteiros e considera apenas as partes inteiras de divisões que não têm resto zero?
Ali o termo operador eu entendi como um +, ou um -, ou um *, ou um /.

Quando declaras um int em C vais guardar um inteiro. Se chegares a um ponto onde queres atribuir um valor fraccionário a essa mesma variável o que ele faz é guardar apenas a parte inteira pois é um inteiro. Claro que em divisões que tenham resto 0 não haverá problema pois o resultado dá também um inteiro, no entanto, se o resto não for 0, o resultado já vai estar errado pois apenas vai ter a parte inteira da solução
 
Ok... Entendi!

Agora o exercício é:

Escreva um programa em C que solicite um determinado número de segundos e, em seguida, indique quantas horas, minutos e segundos esse número de segundos representa.

No meu entender, e segundo a proposta de resolução do exercício, não faz grande sentido o enunciado e a proposta de resolução.

A proposta de resolução é:

PHP:
#include <stdio.h>

main ()

{
long int sec;

printf ("Introduza um numero de segundos: ");
scanf ("%ld", &sec);
printf ("Horas: %d", (int) sec/3600);
printf ("Minutos: %d", (int) (sec % 3600 / 60)); 
printf ("Segundos: %d", (int) sec % 60); /*1*/
}

Não concordo com a linha /*1*/.

O meu raciocínio é o seguinte:

Dividir o valor inicial por 3600 e a parte inteira dessa divisão dá-nos o número máximo de horas possível com o valor inserido na variável. - sec / 3600.

Depois, obter a parte inteira da divisão por 60, da parte décimal que "sobrou" do cálculo anterior. - (sec % 3600 / 60).

Por fim, o que sobrou da divisão anterior, seriam os segundos restantes dos cálculos anteriores. - Aqui nem sei como representar isso matematicamente.

A soma destes 3 resultados teria que dar o valor inserido inicialmente. Mas acho que a linha /*1*/ não traduz o que eu disse na linha anterior e é isso que não estou a conseguir entender!!!

Ajudam-me a entender????
 
Última edição:
Sabes o que significa o operador %?

Se souberes é bastante fácil perceber o porquê de se usar nessa situação.

O % representa o resto da divisão. Deste modo se introduzires 60, ficas com 1 minuto e 0 segundos, pois o resto de 60/60 é 0.

Se inserires 1 segundo, ficas com 1 segundo pois o resto de 1/60 é 1.

O resto da divisão inteira é muito útil quando tens valores que se repetem. Ou seja, 120 segundos dá 2 minutos e 0 segundos e 60 segundos dá 1 minuto e 0 segundos. Aqui repetem-se os segundos é bastante útil que para todos os múltiplos de 60 o valor dos segundos seja sempre 0. Se usarmos o resto da divisão inteira conseguimos garantir que isso acontece

Mais à frente vais ver que o resto da divisão inteira pode ser bastante útil em arrays circulares.

Percebido?

Já chegaste à parte do livro em que fala de macros?
 
Última edição:
Bom dia...

Eu acho que sei o que faz o %.

Mas acho que vou perceber melhor quando for ali rever umas coisas da 4ª classe.

Acho que tenho estado a confundir divisão inteira com divisões de resto zero e com a parte inteira e parte decimal de uma divisão.

Ainda não cheguei à parte do livro que fala sobre macros. Comecei à apenas 3 ou 4 dias...

Daqui a pouco já vou rever uns conceitos da 4ª classe e depois já volto à carga...

Obrigado
 
Boas de novo...

Tenho uma pequena dúvida.

Há situações em que ao atribuir dois valores a duas varáveis através de dois scanf's (), a segunda variável não retorna o segundo valor lá armazenado mas sim um carcater new line.

Esta situação resolve-se colocando um espaço antes da instrução que define o formato de saída do segundo valor armazena do na seguda variável, ou seja, em vez de ter a instrução assim:

PHP:
scanf ("%c", ch2);

temos a instrução assim:

PHP:
scanf (" %c", ch2);

A minha dúvida é se esta situação só acontece com o tipo de variável char ou se também acontece com os outros tipos de variável...


Exemplo:

PHP:
#include <stdio.h>

main ()

{

char ch1, ch2;

         printf ("Introduza um caracter: ");
         scanf ("%c", &ch1);
         printf ("Introduza outro caracter: ");
         scanf ("%c", &ch2);
         printf ("Os caracteres introduzidos foram %c e %c");

}

Se introduzirmos o 'a' e o 'b', o output seria 'a' e ', este último caracter ' estaria numa nova linha porque o programa assumia o "enter" como um caracter também.

Para contornar isto, coloca-se um espaço antes do "%c" do segundo scanf ().

A minha pergunta é se isto é válido apenas para as variáveis do tipo char ou para todo o tipo de variáveis???
 
Última edição:
Para além do post anterior, tenho um exercício que pede para introduzir uma data e a apresentar no formato dd/mm/aaaa.

Eu fiz assim o code mas não está a dar:

PHP:
/*teste*/

#include <stdio.h>

main ()

{

int dia, mes, ano;

    printf ("Introduza o dia, o mes e o ano pela ordem indicada: "); scanf ("%d &d &d", &dia, &mes, &ano);
    printf ("A data iontroduzida foi %d\\%d\\%d\n", dia, mes, ano);
    getch ();
}

O que é que está mal?
 
Para além do post anterior, tenho um exercício que pede para introduzir uma data e a apresentar no formato dd/mm/aaaa.

Eu fiz assim o code mas não está a dar:

PHP:
/*teste*/

#include <stdio.h>

main ()

{

int dia, mes, ano;

    printf ("Introduza o dia, o mes e o ano pela ordem indicada: "); scanf ("%d &d &d", &dia, &mes, &ano);
    printf ("A data iontroduzida foi %d\\%d\\%d\n", dia, mes, ano);
    getch ();
}

O que é que está mal?

O problema está no scanf. Se vais receber inteiros tens de ter %d. Para o ano e mês tens &d.


Quanto à questão do post anterior. No printf tens de dizer quais os argumentos que correspondem aos %c.

Se tiveres dois scanf consecutivos, o 2º começa a ler onde o 1º parou. Se tiveres por exemplo "a b", o 1º lê o 1º caracter e o 2º vai ler o espaço. Isso é perfeitamente normal e só acontece com tipos char.

O que te aconselho é em vez de usar scanf para um caracter, usar getchar(). Se quiseres ler um caracter e guardar na variável c usas c=getchar(). Para imprimir o valor de c fazes putchar(c);

Ficavas com algo deste tipo:

Código:
[COLOR=#7f4726]#include [COLOR=#e20300]<stdio.h>[/COLOR][/COLOR]


main ()


{
    
    [COLOR=#cc00a2]char[/COLOR] ch1, ch2;
    
[COLOR=#e20300][COLOR=#000000]    printf ([/COLOR]"Introduza um caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch1=getchar();[COLOR=#000000]
[/COLOR]    getchar();/*Lê o espaço*/
[COLOR=#e20300][COLOR=#000000]    printf ([/COLOR]"Introduza outro caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch2=getchar();
[COLOR=#e20300][COLOR=#000000]    printf ([/COLOR]"Os caracteres introduzidos foram "[COLOR=#000000]);[/COLOR][/COLOR]
    putchar(ch1);
    printf([COLOR=#e20300]" e "[/COLOR]);
    putchar(ch2);
    printf([COLOR=#e20300]"\n"[/COLOR]);
    
}

também podes imprimir os valores sem putchar:

Código:
[COLOR=#7f4726]#include [COLOR=#e20300]<stdio.h>[/COLOR][/COLOR]


main ()


{
    
    [COLOR=#cc00a2]char[/COLOR] ch1, ch2;
    
[COLOR=#e20300][COLOR=#000000]   printf ([/COLOR]"Introduza um caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch1=getchar();[COLOR=#000000]
[/COLOR]   getchar();/*Lê o espaço*/
[COLOR=#e20300][COLOR=#000000]   printf ([/COLOR]"Introduza outro caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch2=getchar();
[COLOR=#e20300][COLOR=#000000]   printf ([/COLOR]"Os caracteres introduzidos foram %c e %c\n"[COLOR=#000000], ch1, ch2);[/COLOR][/COLOR]
    
}
 
Última edição:
PsyScOrpiOn, como li algures que pretendes entrar para Electro aqui em coimbra aproveito para te deixar as folhas praticas de programação...não são as deste ano mas devem ser parecidas, foi as unicas a que tenho acesso porque ja fiz isso ha varios anos e agora so quem esta inscrito tem acesso. Se qujiseres despois tambem posso arranjar exames e material teorico...

http://ul.to/ki1tewd8
 
O problema está no scanf. Se vais receber inteiros tens de ter %d. Para o ano e mês tens &d.


Quanto à questão do post anterior. No printf tens de dizer quais os argumentos que correspondem aos %c.

Se tiveres dois scanf consecutivos, o 2º começa a ler onde o 1º parou. Se tiveres por exemplo "a b", o 1º lê o 1º caracter e o 2º vai ler o espaço. Isso é perfeitamente normal e só acontece com tipos char.

O que te aconselho é em vez de usar scanf para um caracter, usar getchar(). Se quiseres ler um caracter e guardar na variável c usas c=getchar(). Para imprimir o valor de c fazes putchar(c);

Ficavas com algo deste tipo:

Código:
[COLOR=#7f4726]#include [COLOR=#e20300]<stdio.h>[/COLOR][/COLOR]


main ()


{
    
    [COLOR=#cc00a2]char[/COLOR] ch1, ch2;
    
[COLOR=#e20300][COLOR=#000000]    printf ([/COLOR]"Introduza um caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch1=getchar();[COLOR=#000000]
[/COLOR]    getchar();/*Lê o espaço*/
[COLOR=#e20300][COLOR=#000000]    printf ([/COLOR]"Introduza outro caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch2=getchar();
[COLOR=#e20300][COLOR=#000000]    printf ([/COLOR]"Os caracteres introduzidos foram "[COLOR=#000000]);[/COLOR][/COLOR]
    putchar(ch1);
    printf([COLOR=#e20300]" e "[/COLOR]);
    putchar(ch2);
    printf([COLOR=#e20300]"\n"[/COLOR]);
    
}

também podes imprimir os valores sem putchar:

Código:
[COLOR=#7f4726]#include [COLOR=#e20300]<stdio.h>[/COLOR][/COLOR]


main ()


{
    
    [COLOR=#cc00a2]char[/COLOR] ch1, ch2;
    
[COLOR=#e20300][COLOR=#000000]   printf ([/COLOR]"Introduza um caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch1=getchar();[COLOR=#000000]
[/COLOR]   getchar();/*Lê o espaço*/
[COLOR=#e20300][COLOR=#000000]   printf ([/COLOR]"Introduza outro caracter: "[COLOR=#000000]);[/COLOR][/COLOR]
    ch2=getchar();
[COLOR=#e20300][COLOR=#000000]   printf ([/COLOR]"Os caracteres introduzidos foram %c e %c\n"[COLOR=#000000], ch1, ch2);[/COLOR][/COLOR]
    
}

Obrigado pelas sugestões...

Vou tê-las em conta mas para já vou seguir pelo livro.

Para além das explicações que deste, também detectei agora que a sintaxe do scanf () também está mal quando escrevi scanf ("%d &d &d", &dia, &mes, &ano); quando devia ter escrito scanf ("%d %d %d", &dia, &mes, &ano);

De qualquer das maneiras já passei essa lição.
Mas obrigado na mesma.

PsyScOrpiOn, como li algures que pretendes entrar para Electro aqui em coimbra aproveito para te deixar as folhas praticas de programação...não são as deste ano mas devem ser parecidas, foi as unicas a que tenho acesso porque ja fiz isso ha varios anos e agora so quem esta inscrito tem acesso. Se qujiseres despois tambem posso arranjar exames e material teorico...

http://ul.to/ki1tewd8

Obrigado pela partilha.

Neste momento tenho outra dúvida:

Neste código, acidentalmente coloquei uma vírgula onde está vermelho

Código:
#include <stdio.h>

main ()

{

float sal;
char estc;

    printf ("Qual o seu salario e diga se e solteiro ou casado: "); scanf ("[COLOR=#ff0000]%f, %c[/COLOR]", &sal, &estc);
    if (estc == 's' || estc == 'S')
        printf ("A taxa a pagar e de %.2f", sal * 0.1);
    else
        if (estc == 'c' || estc == 'C')
            printf ("A taxa a pagar e de %.2f", sal * 0.09);
        else
            printf ("Nao introduziu solteiro ou casado");
getchar();
}

O que faz aquela vírgula ali? Sei que não devia lá estar pois o programa não faz o pretendido.
 
Última edição:
Essa virgula diz ao programa quando é que deve deixar de procurar o float e começar a procurar o char.

Por exemplo, se quisesses fazer um programa que perguntasse as horas, em vez de fazeres

Código:
...
printf("Insira as horas: ");
scanf("%d", &horas);
printf("Insira os minutos: ");
scanf("%d", &minutos);
...

podias fazer logo:
Código:
...
printf("Insira as horas no formato hh:mm ");
scanf("%d:%d", &horas,&minutos);
...

E assim o programa sabia que quando encontrasse os dois pontos ( : ), devia começar a preencher no campo minutos.
No teu caso é uma coisa parecida mas com virgula.

Se no input do teu programa meteres uma virgula entre o salario e o estado civil, ele ja deve funcionar "normalmente" como antes.
 
Essa virgula diz ao programa quando é que deve deixar de procurar o float e começar a procurar o char.

Por exemplo, se quisesses fazer um programa que perguntasse as horas, em vez de fazeres

Código:
...
printf("Insira as horas: ");
scanf("%d", &horas);
printf("Insira os minutos: ");
scanf("%d", &minutos);
...

podias fazer logo:
Código:
...
printf("Insira as horas no formato hh:mm ");
scanf("%d:%d", &horas,&minutos);
...

E assim o programa sabia que quando encontrasse os dois pontos ( : ), devia começar a preencher no campo minutos.
No teu caso é uma coisa parecida mas com virgula.

Se no input do teu programa meteres uma virgula entre o salario e o estado civil, ele ja deve funcionar "normalmente" como antes.

Mas isso eu tenho feito apenas com um espaço e quando coloquei a vírgula, ele só me aceitou receber um valor e passou logo à instrução seguinte.
 
Mas isso eu tenho feito apenas com um espaço e quando coloquei a vírgula, ele só me aceitou receber um valor e passou logo à instrução seguinte.

Sim, porque quando metes um espaço o programa está a espera de receber dois valores separados com um espaço.
Ao meteres a virgula e um espaço, ele está a espera de receber o primeiro valor depois uma virgula e um espaço e depois o segundo valor.
Se não metes a virgula no input, ele não encontra nunca o segundo valor :)

Ou seja, no teu caso, um input válido seria:
1200, S
 
Obrigado pelas sugestões...

Vou tê-las em conta mas para já vou seguir pelo livro.

Para além das explicações que deste, também detectei agora que a sintaxe do scanf () também está mal quando escrevi scanf ("%d &d &d", &dia, &mes, &ano); quando devia ter escrito scanf ("%d %d %d", &dia, &mes, &ano);

Foi precisamente isso que te expliquei aqui

O problema está no scanf. Se vais receber inteiros tens de ter %d. Para o ano e mês tens &d.
 
Ok, obrigado pelas respostas...

Não sei se entendi bem a parte da vígula e dos espaços e dos dois pontos mas significa que o compilador não ignora espaços, vírgulas, dois pontos, etc, etc????

O espaço ali não é sempre necessário por causa do caracter que é representado pelo <enter> ou podia colocar por exemplo %d,%d que o scanf funcionava bem?


Agora tenho outra dúvida

neste code

Código:
/*Programa 03-14*/

#include <stdio.h>

main ()

{

char sex;
float sal;

    printf ("Introduza o seu salario: "); scanf ("%f", &sal);
    printf ("Qual o seu sexo: "); [COLOR=#ff0000]sex = getchar ();[/COLOR]

}

acho que o que está a vermelho não está a funcionar... O programa ainda não está terminado mas já o tentei executar e ele não me está a pedir o char para armazenar em sex...
 
Ok, obrigado pelas respostas...

Não sei se entendi bem a parte da vígula e dos espaços e dos dois pontos mas significa que o compilador não ignora espaços, vírgulas, dois pontos, etc, etc????

O espaço ali não é sempre necessário por causa do caracter que é representado pelo <enter> ou podia colocar por exemplo %d,%d que o scanf funcionava bem?

Basicamente serve para dizeres o formato em que o utilizador vai inserir os dados. Imagina que queres que o utilizador introduza uma hora no formato hh:mm, o que fazes é scanf("%d:%d", &hora, &minutos).

Se quiseres que o utilizador introduza uma data no formato dd-mm-aa, ficas com scanf("%d-%d-%d", &dia, &mes, &ano).

Podes também querer apenas que o utilizador insira 2 números. Se quiseres que o utilizador insira no formato "num1, num2" fazes scanf("%d, %d", &num1, &num2).

Se quiseres que insira no formato "num1 num2" fazes scanf("%d %d", &num1, &num2).

Depois é só andar a brincar com isto. Se quiseres até podes por strings e chars ao barulho.

Podes fazer scanf("%d e %d", &num1, &num2). Deste modo o utilizador insere "15 e 14" por exemplo.

Agora tenho outra dúvida

neste code

Código:
/*Programa 03-14*/

#include <stdio.h>

main ()

{

char sex;
float sal;

    printf ("Introduza o seu salario: "); scanf ("%f", &sal);
    printf ("Qual o seu sexo: "); [COLOR=#ff0000]sex = getchar ();[/COLOR]

}

acho que o que está a vermelho não está a funcionar... O programa ainda não está terminado mas já o tentei executar e ele não me está a pedir o char para armazenar em sex...

Isso é um erro bastante comum. Estás a pedir ao utilizador para introduzir um float e depois do float tem de introduzir um char. O que acontece é que o utilizador introduz um número e depois carrega enter. Neste caso o que vai ficar no char vai ser o enter. Para resolver esta questão tem duas soluões:

1 - Trocas a ordem do código, ou seja, pedes ao utilizador que introduza 1º o char e depois o float.

2 - Antes de fazeres sex=getchar() fazes apenas getchar(). Deste modo o getchar() apanha o enter e o sex=getchar() já apanha o que queres.

Coloca um putchar(sex) no fim do código para que consigas ver que a variável sex tem o valor pretendido

Se quiseres confirmar que é isto que está a acontecer faz o seguinte:

1 - Declara duas variáveis, int p.ex.

2 - Faz um printf onde pedes ao utilizador para introduzir o salário.

3 - Faz o scanf para guardares o valor.

4 - Faz um printf onde pedes ao utilizador para introduzir a idade

5 - Faz o scanf para guardares o valor.

6 - Compila e corre o programa.

7 - Ao te ser pedido para inserires o sálario, introduz dois números (separados por uma vírgula, claro), introduzindo assim o salário e a idade e vais ver que o programa mostra-te o printf a pedir a idade mas nem te deixa inserir nada, terminando logo.

Uma sugestão:
Tenta escrever apenas uma instrução por linha. Em códigos pequenos, como estes, não é problemático mas em códigos maiores já começa a ser mais difícil a leitura
 
Última edição:
Back
Topo