Iniciação em C - Dúvidas

Obrigado dragas46...

Segui a sugestão de colocar o getchar () antes do sex = getchar () e funcionou bem.

Quanto ao resto para ver que é o que explicaste que está a acontecer, eu queria ver se seguia o manual que estou a ler. É que estão-me a falar de funções que eu ainda não conheço como o putchar ().

Ninguém tem o manual do Luis Damas de título "Linguagem C - com Luís Damas"?

Neste momento vou na página 81. Se o tiverem podiam ver o exercício que estou a fazer e compreender melhor os meus problemas...
 
Se já percebes o que faz o getchar() não é difícil perceberes o que faz o putchar(char letra).

O getchar lê uma letra do standard input, o putchar imprime essa mesma letra no standard output
 
Alguém tem o manual do "Luís Damas - Linguagem C".

Por vezes torna-se complicado explicar e se o tivessem era mais imples consultarem o exercício que estou a tentar resolver para me ajudarem!

Obrigado
 
Fui buscar o meu "Linguagem C" que estava ali parado já à uns tempos e a pág. 81 fala de um programa que só recebe dois inteiros e aplica os operadores relacionais (==, >. >=, <, <=, !=); É isso?
 
Fui buscar o meu "Linguagem C" que estava ali parado já à uns tempos e a pág. 81 fala de um programa que só recebe dois inteiros e aplica os operadores relacionais (==, >. >=, <, <=, !=); É isso?

Penso que não mas não faz mal. Já passei essa parte e acho que já entendi o que tinha para entender.

Ou indiquei a página errada ou então não é o mesmo livro... Mas obrigado.

Neste momento estou na página 86 no prog0317.c e tenho outra dúvida.

O programa, para o caso de ninguém ter o livro ou não ser bem igual, é:

Peça ao utilizador um número de horas e diga a quantos segundos corresponde

PHP:
#include <stdio.h>

main ()

int n_horas;
long n_seg; /*pode ser muito grande*/

printf ("Nº de Horas: "); scanf ("%d", &n_horas);
n_seg = n_horas < 0 ? 0 : n_horas * 3600L
printf ("%d horas tem %ld segundos\n", n_horas, n_seg);

Lá mais para trás no livro, aprendi a fazer o casting. E fazia-se na hora, colocando a letra correspondente à nova variável temporária entre o % o identificador da variável. -> &d passava a %ld por exemplo.

Neste exercício 0317, sugerem um casting de forma diferente.Para além de não estar explicado quando explicaram o casting pela primeira vez, não entendo muito bem o porquê de fazerem casting a uma constante se esta nunca se vai alterar.
 
Nesse exercício não está a ser feito casting. Fazer casting é por exemplo isto:

Código:
char letra = 'a';
int num; 

num = (int) letra; /* casting de char para int */

print("imprimir um char: %c", letra);
print("imprimir um numero: %d", num);

usares %ld que apenas dizer que vais imprimir um long int.
 
Penso que não mas não faz mal. Já passei essa parte e acho que já entendi o que tinha para entender.

Ou indiquei a página errada ou então não é o mesmo livro... Mas obrigado.

Neste momento estou na página 86 no prog0317.c e tenho outra dúvida.

Na minha edição do livro (16) o prog0317.c está na página 113. :D
De qualquer forma o que o diutsu está correcto tu não estás a fazer casting estás só a dizer que vais imprimir um long int como quando fazes scanf("%d",&var_qualquer) estás especificar o tipo que vais ler (neste caso int).
 
Nesse exercício não está a ser feito casting. Fazer casting é por exemplo isto:

Código:
char letra = 'a';
int num; 

num = (int) letra; /* casting de char para int */

print("imprimir um char: %c", letra);
print("imprimir um numero: %d", num);

usares %ld que apenas dizer que vais imprimir um long int.

Ok, percebi.

No entanto expliquei mal e estava a fazer confusão.

O exrcício é que fala que faz casting quando coloca o L a seguir ao valor de uma constante. Mas esta parte não foi explicada como funciona.

Na minha edição do livro (16) o prog0317.c está na página 113. :D
De qualquer forma o que o diutsu está correcto tu não estás a fazer casting estás só a dizer que vais imprimir um long int como quando fazes scanf("%d",&var_qualquer) estás especificar o tipo que vais ler (neste caso int).

Pois, o meu é a edição 10... A ver se arranjo a 16 ou outra mais recente!

Agora tenho outra dúvida.

Um exercício pede para solicitar um número de horas ao utilizador e depois para mostrar o numero de minutis, ou segundos ou décimas de segundo consoante o que o utilizador escolher.

Eu tenho assim a 1ª versão do código:

PHP:
/*Programa cap03-18*/

#include <stdio.h>

main ()

{

float horas;
long decs, seg, min;
char op;

    printf ("Introduza o numero de horas: ");
    scanf ("%f", &horas);
    printf ("Introduza se deseja o resultado em minutos, segundos ou decimas de segundo: ");
    scanf (" %c", &op);
    if (horas < 0)
        printf ("O numero de horas introduzido nao e valido!");
    else
        if (op == 'm' || op == 'M') {
           min = horas * 60;
           printf ("%.2f tem %ld minutos!\n", horas, min);
        }
           if (op == 's' || op == 'S') {
              seg = horas * 3600;
              printf ("%.2f tem %ld segundos!\n", horas, seg);
           }
               if (op == 'd' || op == 'D') {
                  decs = horas * 36000;
                  printf ("%.2f tem %ld decimas de segundo!\n", horas, decs);
               }
}

O problema é se introduzir um valor negativo para o número de horas, ele faz os cálculos na mesma e apresenta os valores dos cálculos e depois diz que o "O numero de horas introduzido nao e valido!".

Porque é que ele está a verificar a condição do if como verdadeira e no entanto segue pelo else na mesma?
 
O programa só faz isso quando o números de horas é inferior a 0 e queres mostrar o resultado em minutos. Os 2 últimos if's(segundos e décimos de segundos) estão a ser sempre testados, mesmo quando o número de horas é inválido. Consegues perceber porque? Aí está o teu problema. É algo muito simples de se resolver

Podias alterar a ordem do código. Punhas a pedir o número de horas ao utilizador e se fosse menor que 0 mostravas logo que o número de horas não é válido em vez de perguntar se o utilizador quer ver o resultado em minutos, segundos ou décimas de segundos para depois mostrares a mensagem de número de horas inválido. É só um preciosismo

Tens de abrir uma chaveta depois do else e fechar a chaveta antes de fechares a chaveta da main
 
Última edição:
O programa só faz isso quando o números de horas é inferior a 0 e queres mostrar o resultado em minutos.

E não só. Se pedir em Décimas de Segundo, acontece igual.

Os 2 últimos if's(segundos e décimos de segundos) estão a ser sempre testados, mesmo quando o número de horas é inválido. Consegues perceber porque? Aí está o teu problema. É algo muito simples de se resolver

Sem ver o spoiler, não chegava lá. Depois de ver o spoiler, percebi. Nos if's e elses, quando queremos mais que uma instrução, temos que as agrupar num bloco com as {}.

Ou seja, só estava correcto o primeiro if depois do else. Os dois outros if's já eram código fora do else que iriam ser verificados caso o número de horas fosse < 0.

Ah e também se por acaso os dois últimos if's fossem mesmo para serem exteriores ao primeiro if, também podia dizer que a identação estava incorrecta.

Podias alterar a ordem do código. Punhas a pedir o número de horas ao utilizador e se fosse menor que 0 mostravas logo que o número de horas não é válido em vez de perguntar se o utilizador quer ver o resultado em minutos, segundos ou décimas de segundos para depois mostrares a mensagem de número de horas inválido. É só um preciosismo

Pois, era também uma boa solução.

Obrigado



Edited;

Só agora, depois de ter ido corrigir e voltar a executar o código é que percebi melhor o que dizes de dizer logo que o númer de horas é inválido. loool...

É redundante pedir o valor para a variável "tipo" se não vai ser executado nenhum código caso o valor da variável "horas" for negativo.
 
Última edição:
PHP:
/*Programa cap03-18.v1*/

#include <stdio.h>

main ()

{

float horas;
int min, seg, decs, res;
char tipo;

    printf ("N Horas: ");
    scanf ("%f", &horas);
    if (horas < 0 )
        printf ("O numero de horas introduzido nao e valido!");
        else {
            printf ("Mostrar (Minutos\\Segundos\\Decimas de segundo): \n");
            scanf ("%c", &tipo);
            switch (tipo) {
                case 'm' :
                case 'M' : res = horas >= 0 ? horas * 60 : 0;
                    break;
                case 's' :
                case 'S' : res = horas >= 0 ? horas * 3600 : 0;
                    break;
                case 'd' :
                case 'D' : res = horas >= 0 ? horas * 36000 : 0;
            }
        }
        printf ("%.2f tem %d %c!", horas, res, tipo);
}

Este código tem vários problemas...

O scanf () para armazenar o valor da variável "tipo" não funciona, ou seja, o programa não me pede o valor para a variável tipo.

E no último printf (), onde está o formato %c para armazenar a variável "tipo" também não está a funcionar. E o resultado das operações para determinar o número de minutos, segundos e décimas de segundo também ao estão a funcionar...

Podem-me dar dicas para ver se chego às soluções dos problemas?
 
while(getchar()!='\n');

Acrescentando esta linha logo no inicio do else deve resolver os teus problemas (apesar de ser um crime LOL).

Podes usar de preferencia o fpurge(stdin); mas não sei se vai funcionar na tua máquina ou não...
 
Última edição:
E não só. Se pedir em Décimas de Segundo, acontece igual.



Sem ver o spoiler, não chegava lá. Depois de ver o spoiler, percebi. Nos if's e elses, quando queremos mais que uma instrução, temos que as agrupar num bloco com as {}.

Ou seja, só estava correcto o primeiro if depois do else. Os dois outros if's já eram código fora do else que iriam ser verificados caso o número de horas fosse < 0.

Ah e também se por acaso os dois últimos if's fossem mesmo para serem exteriores ao primeiro if, também podia dizer que a identação estava incorrecta.



Pois, era também uma boa solução.

Obrigado



Edited;

Só agora, depois de ter ido corrigir e voltar a executar o código é que percebi melhor o que dizes de dizer logo que o númer de horas é inválido. loool...

É redundante pedir o valor para a variável "tipo" se não vai ser executado nenhum código caso o valor da variável "horas" for negativo.

Enganei-me. Era "só não faz isso"



PHP:
/*Programa cap03-18.v1*/

#include <stdio.h>

main ()

{

float horas;
int min, seg, decs, res;
char tipo;

    printf ("N Horas: ");
    scanf ("%f", &horas);
    if (horas < 0 )
        printf ("O numero de horas introduzido nao e valido!");
        else {
            printf ("Mostrar (Minutos\\Segundos\\Decimas de segundo): \n");
            scanf ("%c", &tipo);
            switch (tipo) {
                case 'm' :
                case 'M' : res = horas >= 0 ? horas * 60 : 0;
                    break;
                case 's' :
                case 'S' : res = horas >= 0 ? horas * 3600 : 0;
                    break;
                case 'd' :
                case 'D' : res = horas >= 0 ? horas * 36000 : 0;
            }
        }
        printf ("%.2f tem %d %c!", horas, res, tipo);
}

Este código tem vários problemas...

O scanf () para armazenar o valor da variável "tipo" não funciona, ou seja, o programa não me pede o valor para a variável tipo.

E no último printf (), onde está o formato %c para armazenar a variável "tipo" também não está a funcionar. E o resultado das operações para determinar o número de minutos, segundos e décimas de segundo também ao estão a funcionar...

Podem-me dar dicas para ver se chego às soluções dos problemas?

Porque é que em que alguns programas utilizas o getchar para receber char's e noutros usas o scanf?

Este programa só tem um problema e é um problema que já tiveste em exercícios anteriores.

Vê os post's #39 e #40 deste tópico. É exactamente o teu problema

Código:
[COLOR=#008400][FONT=Menlo]/*Programa cap03-18.v1*/[/FONT][/COLOR]
[FONT=Menlo]
[/FONT]
[COLOR=#78492A][FONT=Menlo]#include [COLOR=#d12f1b]<stdio.h>[/COLOR][/FONT][/COLOR]
[FONT=Menlo]
[/FONT]
[FONT=Menlo][COLOR=#bb2ca2]int[/COLOR] main ()[/FONT]
[FONT=Menlo]
[/FONT]
[FONT=Menlo]{[/FONT]

[FONT=Menlo]    [COLOR=#bb2ca2]float[/COLOR] horas;[/FONT]
[FONT=Menlo]    [COLOR=#bb2ca2]int[/COLOR] min, seg, decs, res;[/FONT]
[FONT=Menlo]    [COLOR=#bb2ca2]char[/COLOR] tipo;[/FONT]

[FONT=Menlo]    printf ([COLOR=#d12f1b]"N Horas: "[/COLOR]);[/FONT]
[FONT=Menlo]    scanf ([COLOR=#d12f1b]"%f"[/COLOR], &horas);[/FONT]
[FONT=Menlo]    [COLOR=#bb2ca2]if[/COLOR] (horas < [COLOR=#272ad8]0[/COLOR] )[/FONT]
[COLOR=#D12F1B][FONT=Menlo][COLOR=#000000]        printf ([/COLOR]"O numero de horas introduzido nao e valido!"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Menlo]    [COLOR=#bb2ca2]else[/COLOR] {[/FONT]
[COLOR=#D12F1B][FONT=Menlo][COLOR=#000000]        printf ([/COLOR]"Mostrar (Minutos\\Segundos\\Decimas de segundo): \n"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Menlo]        getchar();[/FONT]
[FONT=Menlo]        tipo=getchar();[/FONT]
[FONT=Menlo]        [COLOR=#bb2ca2]switch[/COLOR] (tipo) {[/FONT]
[FONT=Menlo]            [COLOR=#bb2ca2]case[/COLOR] [COLOR=#272ad8]'m'[/COLOR] :[/FONT]
[FONT=Menlo]            [COLOR=#bb2ca2]case[/COLOR] [COLOR=#272ad8]'M'[/COLOR] : res = horas >= [COLOR=#272ad8]0[/COLOR] ? horas * [COLOR=#272ad8]60[/COLOR] : [COLOR=#272ad8]0[/COLOR];[/FONT]
[FONT=Menlo]                [COLOR=#bb2ca2]break[/COLOR];[/FONT]
[FONT=Menlo]            [COLOR=#bb2ca2]case[/COLOR] [COLOR=#272ad8]'s'[/COLOR] :[/FONT]
[FONT=Menlo]            [COLOR=#bb2ca2]case[/COLOR] [COLOR=#272ad8]'S'[/COLOR] : res = horas >= [COLOR=#272ad8]0[/COLOR] ? horas * [COLOR=#272ad8]3600[/COLOR] : [COLOR=#272ad8]0[/COLOR];[/FONT]
[FONT=Menlo]                [COLOR=#bb2ca2]break[/COLOR];[/FONT]
[FONT=Menlo]            [COLOR=#bb2ca2]case[/COLOR] [COLOR=#272ad8]'d'[/COLOR] :[/FONT]
[FONT=Menlo]            [COLOR=#bb2ca2]case[/COLOR] [COLOR=#272ad8]'D'[/COLOR] : res = horas >= [COLOR=#272ad8]0[/COLOR] ? horas * [COLOR=#272ad8]36000[/COLOR] : [COLOR=#272ad8]0[/COLOR];[/FONT]
[FONT=Menlo]        }[/FONT]
[FONT=Menlo]    }[/FONT]
[FONT=Menlo]    printf ([COLOR=#d12f1b]"%.2f tem %d"[/COLOR], horas, res);[/FONT]
[FONT=Menlo]    putchar(tipo);[/FONT]
[FONT=Menlo]    printf([COLOR=#d12f1b]"\n"[/COLOR]);[/FONT]

[FONT=Menlo]    [COLOR=#bb2ca2]return[/COLOR] [COLOR=#272ad8]0[/COLOR];[/FONT]
[FONT=Menlo]}
[/FONT]
 
Última edição:
Ok, desta vez consegui resolver (também antes de ver o spoiler) mas não fiquei satisfeito.

O code ficou assim:

PHP:
/*Programa cap03-18.v1*/

#include <stdio.h>

main ()

{

float horas;
int min, seg, decs, res;
char tipo;

    printf ("N Horas: ");
    scanf ("%f", &horas);
    if (horas < 0 )
        printf ("O numero de horas introduzido nao e valido!\n");
        else {
            printf ("Mostrar (Minutos\\Segundos\\Decimas de segundo): \n");
            getchar (); tipo = getchar ();
            switch (tipo) {
                case 'm' :
                case 'M' : res = horas >= 0 ? horas * 60 : 0;
                    break;
                case 's' :
                case 'S' : res = horas >= 0 ? horas * 3600 : 0;
                    break;
                case 'd' :
                case 'D' : res = horas >= 0 ? horas * 36000 : 0;
            }
        printf ("%.2f tem %d ", horas, res); putchar (tipo);
        }
}

O último printf, eu queria que ele mostrasse a totalidade da variável "tipo" e não apenas o primeiro caractér!

E tenho outra questão relacionada com a sugestão de código que está no livro, que é a seguinte:

PHP:
/*Programa 03-18.m*/

#include <stdio.h>

main ()

{

int n_horas;
long res;
char tipo;

    printf ("Nº de horas: "); scanf ("%d", &n_horas);
    printf ("O que mostrar (m/s/d): ");
    scanf (" %c", &tipo);
    switch (tipo) {
        case 'm':
        case 'M': res = n_horas < 0 ? 0 : n_horas * 60L;
            break;
        case 's':
        case 'S': res = n_horas < 0 ? 0 : n_horas * 3600L;
            break;
        case 'd':
        case 'D': res = n_horas < 0 ? 0 : n_horas * 36000L;
            break;
    }
    printf ("%dh --> %ld%c ", n_horas, res, tipo);
}

O que falei há uns posts atrás de casting que eles dizem no livro é onde colocam o L a seguir às constantes 60, 3600 e 36000.






edited;

Ainda falta dizer porque uso às vezes o getchar () e outras o scanf (). Bem, não tenho razão específica. É conforme calha. Há alguma desvantagem nisso?
 
Última edição:
Ok, desta vez consegui resolver (também antes de ver o spoiler) mas não fiquei satisfeito.

O code ficou assim:

PHP:
/*Programa cap03-18.v1*/

#include <stdio.h>

main ()

{

float horas;
int min, seg, decs, res;
char tipo;

    printf ("N Horas: ");
    scanf ("%f", &horas);
    if (horas < 0 )
        printf ("O numero de horas introduzido nao e valido!\n");
        else {
            printf ("Mostrar (Minutos\\Segundos\\Decimas de segundo): \n");
            getchar (); tipo = getchar ();
            switch (tipo) {
                case 'm' :
                case 'M' : res = horas >= 0 ? horas * 60 : 0;
                    break;
                case 's' :
                case 'S' : res = horas >= 0 ? horas * 3600 : 0;
                    break;
                case 'd' :
                case 'D' : res = horas >= 0 ? horas * 36000 : 0;
            }
        printf ("%.2f tem %d ", horas, res); putchar (tipo);
        }
}

O último printf, eu queria que ele mostrasse a totalidade da variável "tipo" e não apenas o primeiro caractér!

Isso é fácil. Basta fazeres if-else. Se o tipo=='m' imprimes minutos e por aí fora.


E tenho outra questão relacionada com a sugestão de código que está no livro, que é a seguinte:

PHP:
/*Programa 03-18.m*/

#include <stdio.h>

main ()

{

int n_horas;
long res;
char tipo;

    printf ("Nº de horas: "); scanf ("%d", &n_horas);
    printf ("O que mostrar (m/s/d): ");
    scanf (" %c", &tipo);
    switch (tipo) {
        case 'm':
        case 'M': res = n_horas < 0 ? 0 : n_horas * 60L;
            break;
        case 's':
        case 'S': res = n_horas < 0 ? 0 : n_horas * 3600L;
            break;
        case 'd':
        case 'D': res = n_horas < 0 ? 0 : n_horas * 36000L;
            break;
    }
    printf ("%dh --> %ld%c ", n_horas, res, tipo);
}

O que falei há uns posts atrás de casting que eles dizem no livro é onde colocam o L a seguir às constantes 60, 3600 e 36000.

Não percebi qual é a questão :S






edited;

Ainda falta dizer porque uso às vezes o getchar () e outras o scanf (). Bem, não tenho razão específica. É conforme calha. Há alguma desvantagem nisso?

Não há desvantagem nenhuma mas para mim usar o getchar e putchar é bastante mais intuitivo que usar o scanf para receber char
 
Última edição:
Não percebi qual é a questão :S

Ok, percebi a parte do if para mostrar o conteúdo total da variável.

Quanto à minha questão do casting é a seguinte:

Eu lá mais para trás pedi para me explicarem o casting que eles estavam a fazer no livro porque não percebi a forma como ele foi feito que colocaram um L logo a seguir à constante. Eles dizem que é fazer casting mas que aquele tipo de casting só pode ser feito com constantes.

Digam-me se eu estou correcto:

Até agora existem pelo menos dois tipos de casting. O primeiro que é colocar por exemplo "(int) variável" e agora este de transformar um int num long desta maneira --> 3600L.

Então e como fazer este tipo de casting mas para outro tipo de variáveis, quais são as letras a usar.

Por exemplo, como transformar a constante 60 que é long numa variável do tipo int? É colocar um D à frente do 60? --> 60D?
 
Tenho outra questão... Esta prende-se com o code::blocks.

Como fazer o debugging dos nossos programas?

Por exemplo, eu em VB 6 tinhas as Watch Windows e podia fazer parar o programa nas linhas de código que eu quisesse.

Como posso fazer o mesmo no code::blocks??
 
Não sei se ja foi corrigido mas alguem aqui disse algo errado em relacao o range dos signed e unsigned e é precisamente ao contrario
unsigned permite ter numeros sem verificacao de overflow e permite numeros de 0 a 2^32
signed tem overflow check e é usado para numeros negativos, exemplo salvo erro que tou a fazer de cabeça. (-2^31 a 2^31-1)
neste caso como é signed int, o bit mais significativo é o que influencia o sinal. exemplo -128 = 1 0 0 0 0 0.....
 
Última edição:
Back
Topo