Operatore NOT

di il
8 risposte

Operatore NOT

Salve a tutti, sono nuovo nel forum e sono alle prime armi con il linguaggio C. L'altro giorno, vedendo la soluzione proposta per un esercizio di calcolo MCD e mcm, mi sono soffermato su una cosa che mi è poco chiara. Vi allego il codice:

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


unsigned int num1=0, num2=0, max=0;
int mcd (int a, int b) {
    while (a!=b)
        if (a>b)
            a=a-b; else
                b=b-a;
    return a;
}
int mcm (int n, int m) {
    return m*n/mcd(n,m); }
int main() {
    /* Fase di input */
    printf(" - CALCOLO MASSIMO e mcm - \n");
    
    while(!(num1>=50) && (num1<=150)) {
        printf("Immetti il primo numero intero: "); scanf("%d", &num1);
    } printf("\n");
    while (!((num2>=50) && (num2<=150))) {
        printf("Immetti il secondo numero intero: "); scanf("%d", &num2);
    }
    /* Fase di elaborazione */ if (num1 >= num2)
        max = num1;
    else
        max = num2;
    /* Fase di output */
    printf("\nIl massimo vale: %d \n\n", max); printf("\nIl mcm vale: %d \n\n", mcm(num1,num2));
    
    return(0);
}

La cosa che non mi torna è il punto esclamativo dopo i cicli while. Perchè è stato inserito? So che si tratta di un operatore NOT e dovrebbe restituire come falso un input vero, ma nonostante tutto il programma funziona correttamente e non sto capendo come mai. Grazie a chiunque volesse darmi una mano a riguardo

8 Risposte

  • Re: Operatore NOT

    I while messi così fanno sì che il numero venga richiesto finchè il dato inserito è nell'intervallo di validità 50<=num<=150.
    Su questo devi essere d'accordo.
    Ora il while poteva essere scritto così:
    while( (num<50) || (num>150)
    ovvero: ripeti la richiesta di inserimento finchè il numero è fuori dall'intervallo.
    Ora per le regole di algebra di boole è la stessa cosa dire:
    while( ! ( (!(num<50)) && (!(num>150)) ) )
    ovvero
    while( ! ( (num>=50) && (num<=150) ) )
    A mio avviso però l'ideale sarebbe stato scrivere una funzioncina
    int IsValidInput(int num)
    {
    	if( num < 50 ) 
    		return 0;
    	if( num > 150 ) 
    		return 0;
    	return 1
    }
    e nel main:
    while( !IsValidInput(num1) )
    ...
  • Re: Operatore NOT

    Grazie mille innanzitutto per la risposta. Però scusa se insisto, ma proprio non sto riuscendo a capire l'utilità dell'operatore NOT dopo il while. Teoricamente, eliminandolo, non dovrebbe funzionare correttamente qualora l'input fosse vero? A cosa serve "invertire" l'input se i parametri richiesti sono effettivamente corretti? E soprattutto, perchè eliminandolo mi viene restituito errore?
    Grazie ancora
  • Re: Operatore NOT

    Non fare pasticci mentali !

    L'espressione "a != b" vuol dire a DIVERSO DA b

    che e' equivalente a dire "!(a == b)" e cioe' NON (a UGUALE A b)

    Nel primo caso, il punto escalmativo NON E' l'operatore NOT, ma fa parte dell'operatore di confronto "!=" (DIVERSO DA), il quale, a sua volta, fa parte degli OPERATORI DI CONFRONTO

    == UGUALE a
    != DIVERSO DA
    <= MINORE O UGUALE A
    < MINORE DI
    > MAGGIORE DI
    >= MAGGIORE O UGUALE A

    Mentre nel secondo caso, il punto esclamativo e' PROPRIO l'OPERATORE NOT, che inverte il valore dell'espressione booleana che lo segue

    !true -> false
    !false -> true
  • Re: Operatore NOT

    Grazie migliorabile! E' proprio questo il punto. L'operatore NOT dovrebbe invertire il valore dell'espressione booleana che lo segue, perciò, dato questo ciclo while

    while(!(num1>=50) && (num1<=150))

    e inserendo un numero compreso tra 50 e 150 (cioè un input true) non dovrebbe invertirlo in false? Oppure sto sbagliando qualcosa?
  • Re: Operatore NOT

    Com'è scritto ! opera sulla prima parte non su tutta l'espressione
  • Re: Operatore NOT

    Le basi della logica, dunque anche l'algebra di Boole,dovrebbero essere padroneggiate da chiunque si cimenti a programmare un calcolatore. Non ha importanza il livello di competenze attuali o quello a cui si vuole arrivare, basso o elevato che sia, lo studio di queste branche del sapere è fondamentale, o per lo meno lo è conoscerne le basi.

    Siano date due metavariabili (ossia simboli che stanno per altri simboli) A e B, si ha che la congiunzione (AND), dove A e B sono i congiunti, produce la seguente tabella di verità
    
    A B Y
    F F  F
    F V F
    V F F
    V V V
    
    La negazione è un operatore, o connettivo, unario che quindi si applica ad una singola (meta) variabile. Banalmente, una volta definita A come metavariabile,si ha le seguente tabella di verità:
    
    A Y
    F V
    V F
    
    La tua espressione si può sintentizzare così usando sempre le due famose metavariabili A e B,dove ^ è la congiunzione e ~ rappresenta la negazione:
    
    ~A ^ B
    
    Con tavole della verità alla mano puoi ricavare i valori di verità dell'espressione di cui sopra, ricordando che la negazione ha la precedenza sulla congiunzione che a sua volta ha priorità maggiore rispetto alla disgiunzione inclusiva (OR).

    Il tutto è in risposta a questo
    Grazie migliorabile! E' proprio questo il punto. L'operatore NOT dovrebbe invertire il valore dell'espressione booleana che lo segue, perciò, dato questo ciclo while

    while(!(num1>=50) && (num1<=150))

    e inserendo un numero compreso tra 50 e 150 (cioè un input true) non dovrebbe invertirlo in false? Oppure sto sbagliando qualcosa?
  • Re: Operatore NOT

    @Steek Hutzee:
    e inserendo un numero compreso tra 50 e 150 (cioè un input true) non dovrebbe invertirlo in false? Oppure sto sbagliando qualcosa?
    Infatti, lo inverte in false in modo da uscire dal ciclo proprio quando l'input è corretto.
    Se invece il dato inserito è fuori dall'intervallo, es. 0 come il valore di partenza di num1, abbiamo che
    ((num1>=50) && (num1<=150)) => FALSE
    con il ! diventa TRUE e quindi si richiede l'inserimento del dato.
    Ripeto: ti consiglio di scrivere una funzioncina che controlla l'input in modo che il codice sia scritto in modo più chiaro.
  • Re: Operatore NOT

    Steek Hutzee ha scritto:


    Grazie migliorabile! E' proprio questo il punto. L'operatore NOT dovrebbe invertire il valore dell'espressione booleana che lo segue, perciò, dato questo ciclo while
    while(!(num1>=50) && (num1<=150))
    e inserendo un numero compreso tra 50 e 150 (cioè un input true) non dovrebbe invertirlo in false? Oppure sto sbagliando qualcosa?
    Qui hai il secondo pasticcio: l'ordine di valutazione/precedenza degli operatori:

    http://en.cppreference.com/w/cpp/language/operator_precedence

    Il punto esclamativo ha la precedenza sull 'AND (&&)

    e le parentesi hanno la precedenza sul punto escalamativo!

    Quindi, la tua espressione sarebbe uguale a:
    while ((num1 < 50) && (num1 <= 150))
    Il che vuo dire che la condizione sara' true SOLO per i numeri MINORI DI 50!

    Se non sei sicuro di quale sia la precedenza, aggiungi parentesi!

    Non fanno mai male
Devi accedere o registrarti per scrivere nel forum
8 risposte