Esercizio C if else e while

Robert T.

Utente Attivo
Salve, oggi sono incorso in questo esecizio (in cui si possono usare solo while e if else)in C banale ma anche molto utile :

Ecco il testo:

Scrivere un programma che visualizzi il seguente disengo:

Codice:
* * * * * * * * 
 * * * * * * * * 
* * * * * * * * 
 * * * * * * * * 
* * * * * * * * 
 * * * * * * * * 
* * * * * * * * 
 * * * * * * * *
Il vostro programma dovrà utilizzare soltanto tre istruzioni printf, una per ognuna delle forme seguenti:

printf("* ");
printf(" ");
printf("\n");

Io ho risolto il problema tramite quest'approccio, voi come avreste agito? ricordo che è ammesso solo while come ciclo.:

Codice:
 19 #include <stdio.h> 20 
 21 int main(){
 22    
 23         int cont = 1;
 24         while(cont <= 8){
 25 
 26                 int cont1 = 0;
 27 
 28                         while(cont1<= 8){
 29 
 30                         printf("* ");
 31                         cont1++;
 32                         }
 33 
 34                         printf("\n");
 35                         if(cont % 2){
 36 
 37                                 printf(" ");
 38 
 39                         }
 40 
 41                         else{
 42                            
 43                         }
 44 
 45                         cont1++;
 46           
 47         cont++;
 48 }
 49 
 50 return 0;
 51 }
 
Ultima modifica da un moderatore:

ChryGigio

Utente Attivo
860
119
Hardware Utente
CPU
I5 3570K 4.1Ghz @ 1.15v
Scheda Madre
P67 Pro 3 SE
Hard Disk
M4 120GB + WD Green 1TB + WD Red 1TB
RAM
2x4GB Kingston HyperX 1600@1866 CL11 1.5V
Scheda Video
R9 290@Stock -0.25v + Arctic MX5
Scheda Audio
Xonar DGX
Monitor
G2460PF + Sconosciuto 22" 1080p @ 75Hz
Alimentatore
Thermaltake Smart SE 530W
Case
NZXT e Ventole PWM 120m + PWM 92m
Sistema Operativo
Windows 10
Ciao, leggendo questo tuo post mi hai fatto venire voglia di provare (sono circa 5 anni che non tocco c/c++ , dalle superiori...)

Codice:
#include <stdio.h>

int main()
{
    int starsToPrint = 8, rowsToPrint = 8;
    int starsCounter = 0;
    while(rowsToPrint > 0)
    {
        starsCounter = 0;
        while(starsCounter < starsToPrint)
        {
            printf("*");
            starsCounter++;
            if(starsCounter != starsToPrint)
            {
                printf(" ");
            }
        }
        printf("\n");
        rowsToPrint--;
    }
    return 0;
}
Solo non capisco a cosa serva il printf(" ") se si puo usare già il printf("* ") per fare lo spazio dopo la stellina, per questo nel codice ho usato printf("*") e printf(" ")
Si puo ovviare togliendo l'if dentro al secondo while ed aggiungendo lo spazio dentro il printf("*") ma... non capisco xD
 

Robert T.

Utente Attivo
Ciao, leggendo questo tuo post mi hai fatto venire voglia di provare (sono circa 5 anni che non tocco c/c++ , dalle superiori...)

Codice:
#include <stdio.h>

int main()
{
    int starsToPrint = 8, rowsToPrint = 8;
    int starsCounter = 0;
    while(rowsToPrint > 0)
    {
        starsCounter = 0;
        while(starsCounter < starsToPrint)
        {
            printf("*");
            starsCounter++;
            if(starsCounter != starsToPrint)
            {
                printf(" ");
            }
        }
        printf("\n");
        rowsToPrint--;
    }
    return 0;
}
Solo non capisco a cosa serva il printf(" ") se si puo usare già il printf("* ") per fare lo spazio dopo la stellina, per questo nel codice ho usato printf("*") e printf(" ")
Si puo ovviare togliendo l'if dentro al secondo while ed aggiungendo lo spazio dentro il printf("*") ma... non capisco xD
L'editor ha modificato la disposizione degli asterischi, il risultato è a mo di scacchiera, ecco del perchè.
 

ChryGigio

Utente Attivo
860
119
Hardware Utente
CPU
I5 3570K 4.1Ghz @ 1.15v
Scheda Madre
P67 Pro 3 SE
Hard Disk
M4 120GB + WD Green 1TB + WD Red 1TB
RAM
2x4GB Kingston HyperX 1600@1866 CL11 1.5V
Scheda Video
R9 290@Stock -0.25v + Arctic MX5
Scheda Audio
Xonar DGX
Monitor
G2460PF + Sconosciuto 22" 1080p @ 75Hz
Alimentatore
Thermaltake Smart SE 530W
Case
NZXT e Ventole PWM 120m + PWM 92m
Sistema Operativo
Windows 10
Ah ok! Quindi a righe alternate devono partire o con la * o con " ".
In effetti dovevo analizzare meglio il tuo codice.. mi sono basato prevalentemente sull'output .-.

Ho modificato leggermente il codice per fornire l'output

Codice:
#include <stdio.h>

int main()
{
    int starsToPrint = 8, rowsToPrint = 8;
    int starsCounter = 0, rowsCounter = 0;
    while(rowsCounter != rowsToPrint)
    {
        starsCounter = 0;
        while(starsCounter < starsToPrint)
        {
            printf("* ");
            starsCounter++;
        }
        printf("\n");
        rowsCounter++;
        if(rowsCounter % 2 == 1)
        {
           printf(" ");
        }
    }
    return 0;
}
 

DispatchCode

Utente Attivo
593
342
Hardware Utente
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Sistema Operativo
Windows 10 64bit
Mi unisco al party. :P

EDIT:

Codice:
#include<stdio.h>

#define   ROWS  8
#define   COLS  8

int main()
{
  int row = ROWS, col = COLS;
  
  while(row--)
  {
    while(col--)
    {
      printf("* ");
    }
    printf("\n");
    col ^= ~COLS;
    printf((row & 1) ? " " : "");
  }
  
  return 0;
}
 
Ultima modifica:

ChryGigio

Utente Attivo
860
119
Hardware Utente
CPU
I5 3570K 4.1Ghz @ 1.15v
Scheda Madre
P67 Pro 3 SE
Hard Disk
M4 120GB + WD Green 1TB + WD Red 1TB
RAM
2x4GB Kingston HyperX 1600@1866 CL11 1.5V
Scheda Video
R9 290@Stock -0.25v + Arctic MX5
Scheda Audio
Xonar DGX
Monitor
G2460PF + Sconosciuto 22" 1080p @ 75Hz
Alimentatore
Thermaltake Smart SE 530W
Case
NZXT e Ventole PWM 120m + PWM 92m
Sistema Operativo
Windows 10
@DispatchCode sei tutto un'altro livello :|
 

DispatchCode

Utente Attivo
593
342
Hardware Utente
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Sistema Operativo
Windows 10 64bit
Volentieri.
Visto che un valore uguale a 0 è falso, ho evitato la condizione (di fatto comunque è come se ci fosse row > 0 e col > 0); è abbastanza comune in C/C++.
Per quanto riguarda l'istruzione col ^= ~COLS avviene ciò:

Codice:
col = col ^ ~COLS;
Questa istruzione, ^, è lo XOR (OR-esclusivo) bit a bit. Ha la seguente tabella di verità:
Codice:
A  |  B  |  R
----------| ----
0  ^  0  |   0
0  ^  1  |   1
1  ^  0  |   1
1  ^  1  |   0
Detto in altri termini: restituisce 1 quando uno dei membri è esattamente 1, e zero in tutti gli altri casi.
Di solito lo XOR lo si utilizza spesso in assembly per azzerare una variabile, e tutt'ora è un'istruzione utilizzata dai compilatori quando è necessario settare a 0 il valore di una variabile (più sotto spiego meglio).

L'altra istruzione è NOT, e nega il valore del bit. Si tratta del complemento a 1 di un numero e consiste nell'invertire lo stato di ogni bit. Quindi da 0 passano ad 1 e viceversa.


Facendo un esempio pratico, la situazione era la seguente: la variabile COLS (che in pratica non è una variabile, ma è un valore costante ad essere precisi; il nome viene sostituito in fase di compilazione dal valore assegnatole) vale 8, e lo scopo era quello di assegnare a col il valore 8.
Visto che utilizzo l'operatore di post decremento su col, al termine del ciclo la variabile non è settata a 0, ma a -1. A causa di questo motivo ho due strade:

- o azzerare la variabile utilizzando "col ^ col",
- oppure negare il valore di COLS e d applicarlo con uno XOR.

Ecco un esempio pratico (uso 8 bit per comodità nel rappresentare i dati):
Codice:
COLS = 8; // 00001000b
cols    = -1: // 11111111b

~COLS da come risultato = 11110111b

Usando lo XOR, in accordo con la tabella mostrata sopra, si ha:
11111111
              ^
11110111
-------------
00001000
Il valore che otteniamo come risultato finale è proprio 8, e verrà quindi assegnato a col.

A titolo di curiosità, l'applicazione dello XOR sulla stessa variabile (assumiamo -1 di prima) darebbe questo risultato:
Codice:
11111111
              ^
11111111
------------
00000000
Con altri valori, come 185 (10111001b) ad esempio, otterremmo:

Codice:
10111001
               ^
10111001
-------------
00000000
Come azzera appunto i valori.

Non sapendo bene cosa spiegarti ho pensato fosse questa la parte più incomprensibile. Se hai domande più mirate però poni pure. ;)


PS: non ho detto una cosa, piccola chicca. In realtà il compilatore traduce questo mio codice in un altro modo: visto che la #define viene espansa e all'etichetta viene sostituito così il valore (8, in questo caso), il compilatore applica un XOR sul valore FFFFFFF7h (esadecimale) visto che "comprende" il significato del codice. In pratica fa un lavoro migliore del mio (a mia discolpa posso però dire che non avrei potuto diversamente, per evitare una costante che a vista potrebbe aver avuto poco significato :D).

Ecco che accade con un XOR su quel valore (uso sempre dati a 8bit al posto di 32).

Codice:
11111111
              ^
11110111
------------
00001000
che è appunto il solito valore di prima, 8.
 
Ultima modifica:
  • Mi piace
Reactions: Mursey

Entra

oppure Accedi utilizzando