Esercizio 1
[Liv.1] Scrivere una function C char low_up(char ch) che cambia il carattere in input da minuscolo a maiuscolo e viceversa automaticamente
#include <stdio.h>
#include <stdlib.h>
low_upp(char ch);
char main() int {
X;
char printf("Dammi carattere ");
scanf("%c", &X);
printf("Il carattere ‘%c’ è stato trasformato in ‘%c’", X, low_upp(X));
return 0;
}
/* Input: Carattere da convertire in minuscolo o maiuscolo in base ai casi
Output: Carattere convertito
Descrizione: Cambia il carattere in minuscolo a maiuscolo e viceversa */
low_upp(char ch) char {
/* Per convertire un carattere da maiuscolo a minuscolo e viceversa, basta fare un xor col 6º bit (32).
ESEMPIO: 'A' = 65 01000001 x-or 00100000 (32) dato che il 6º bit è diverso, viene commutato e si avrà 01100001 ossia 'a' (97)
Invece 'a' = 97 01100001 x-or 00100000 (32) Dato che il 6º bit è uguale, verrà posto 0 da ottenere 01000001, ossia 'A' */
if(ch >= 65 && ch <= 122) ch^32; return ch;
else return ch;
}
OUTPUT: Giuseppe Accardo - Programmazione II
Esercizio 2
[Liv.1] Scrivere una function C char rotate(char ch, char n_bit) per ruotare di n bit (n_bit), verso sinistra o verso destra (rispettivamente per n_bit<0 e per n_bit>0), il contenuto di una variabile char mediante gli operatori bitwise
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
rotate(unsigned ch, n_bit); unsigned char char char
visualbit(unsigned ch); void char
main() int {
/* Unsigned char, per non avere il complemento a 2 */
X, X_ruotato;
unsigned char n_bit;
short printf("Inserisci un carattere\n");
scanf("%c", &X);
printf("\nCarattere inserito:");
fflush(stdin);
visualbit(X);
printf("\nInserisci n bit da shiftare\n-n bit<0 shifta sinistra\n-n bit>0 shifta a destra\n\n");
scanf("%hd", &n_bit);
fflush(stdin);
X_ruotato = rotate(X, n_bit);
printf("\nIl bit ruotato è:");
visualbit(X_ruotato);
return 0;
}
/*------------------ ROTATE ---------------------------
Scopo: Ruotare i bit di un char dato di n bit
Input: ch = char da ruotare, n_bit = bit da shiftare
Output: Bit del char ruotati
Descrizione: La funzione ruota i bit del char mediante 2 shift.
Prima di scoprire se lo shift dovrà essere effettuato a destra o a sinistra,
salviamo ch in una variabile temporanea tmp: in ch faremo lo shift originale o principale,
mentre in tmp shiftiamo in opposto i valori da "salvare" ad 8-n bit.
Infine uniamo e restituiamo al programma chiamante.
Es. 01000001 e n_bit = -2 (shift a sinistra)
Allora ch = 00000100 (shiftiamo a sinistra) e tmp = 00000001(ultimi 2 bit saranno i primi). return 00000101 */
rotate(unsigned ch, n_bit) unsigned char char char {
tmp = ch;
/* ch: conterrà lo shift principale
unsigned char tmp: shiftiamo in tal modo da ottenere i bit ruotati o "salvati" */
//Shift destra
if(n_bit > 0) {
ch = ch >> n_bit; //lo shift principale
tmp = tmp << (sizeof(ch) * 8 - n_bit); //otterremo il "salvataggio" degli ultimi n_bit
//sizeof(ch)=1*8 bit
ch | tmp; //Uniamo le 2 porzioni
return ch;
}
//Shift sinistra
else if(n_bit < 0) {
//n_bit negativo indica la direzione, ma il suo modulo n_shift
n_bit = -n_bit;
//Processo analogo e inverso
ch = ch << n_bit;
tmp = tmp >> (sizeof(ch) * 8 - n_bit);
ch | tmp;
return ch;
}
}
/* per visualizzare gli 8 bit di una variabile char.
Data una stringa di un byte, la spezzetta in 4 bit: sfrutto l'esadecimale per risalire ai 4 bit. */
visualbit(unsigned ch) void char {
/* 16 stringhe possibili, lunghe 5 (0010+\0) */
bit[16][5] = {"0000","0001","0010","0011",unsigned char "0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
C, dx, sx;
unsigned char C = ch;
sx = C >> 4;
dx = C << 4; dx = dx >> 4;
printf("\nchar = %c\t dec = %d\t \n", C, C);
printf("hex = %x\t bin = %s %s \n", C, bit[sx], bit[dx]); //indirizzo base
}
OUTPUT: Giuseppe Accardo - Programmazione II
Esercizio 3
[Liv.1] Scrivere una function C che, dopo aver estratto i bit da una variabile intera X (tipo char, short o long), ne calcola il relativo valore dalla formula: Val_X = b[n-1]2^(n-1)+...+b[2]2^2+b[1]2^1+b[0]2^0 dove b è l’array dei bit di X. Confrontare il risultato con il valore della variabile X dichiarata una volta signed ed un’altra unsigned.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_LEN 32
estrai_bit(int len, ch[], bit[]); void char char
Visualizza_bit(char bit[], len); void int
main() int {
/* Potenza shift contiene le potenza di 2 */
scelta, i, Potenza_Shift;
int bit[MAX_LEN]; //array bit
char /* Possibili risultati signed ed unsigned
Se inserisco un unsigned char, non posso visualizzare ad esempio valori > 255 */ u_ch = 0;
unsigned char u_lo = 0;
unsigned long u_sh = 0;
unsigned short ch = 0;
char lo = 0;
long sh = 0;
short /* 3 tipi diversi che condividono la stessa area di memoria */ word32bitunion {
l;
long s[2];
short c[4];
char
} word;
puts("Che tipo di dato vuoi inserire?:\n");
puts("1 - intero char");
puts("2 - intero short");
puts("3 - intero long");
scanf("%d", &scelta);
(scelta) switch {
/*TIPO CHAR: Ha a disposizione 1 byte (8 bit). E' possibile rappresentare 256 valori differenti.
Signed char possono rappresentare numeri compresi tra [-128,+127].
Unsigned char possono rappresentare numeri compresi tra [0,255].
ATTENZIONE: nella variabile signed, un valore > 127 e < 255 verrà il complemento a 2 del numero su 8 bit.
In un UNSIGNED inserendo 256 ad esempio, verrà preso come 0, cioè ricomincia un nuovo intervallo.*/
case 1: //IMMISSIONE DI UN CHAR
printf("\nImmettere un intero di tipo char (1 byte): ");
fflush(stdin); //legge un char
scanf("%d", &(word.c[0]));
estrai_bit(sizeof(char), word.c, bit); //estrae i bit dal char inserito
/* Calcolo del valore intero partendo dalla stringa binaria della variabile di input, mediante la formula data.
Viene eseguito un ciclo per 8 volte effettuando la somma tra le potenze di 2 successive */
/* inserisce il risultato in una variabile SIGNED char */
for (i = 0, Potenza_Shift = 1; i < sizeof(char)*8; i++) {
ch += bit[i]*Potenza_Shift; //ch += (bit[i]*pow(2,i));
Potenza_Shift = Potenza_Shift << 1; //Aumenta di 1 l'esponente della potenza
}
//Val_X = Val_X + bit[i] * potenza del 2
/* inserisce il risultato in una variabile UNSIGNED char */
for (i = 0, Potenza_Shift = 1; i < sizeof(char)*8; i++) {
u_ch += bit[i]*Potenza_Shift; //ch += (bit[i]*pow(2,i));
Potenza_Shift = Potenza_Shift << 1; //Aumenta di 1 l'esponente della potenza
}
printf("\nStringa binaria: ");
Visualizza_bit(bit, sizeof(char));
printf("\nValore binario con signed char: %d", ch);
printf("\nValore binario con unsigned char: %d", u_ch);
break;
/*TIPO SHORT: Ha a disposizione 2 byte (16 bit). E' possibile rappresentare 65536 valori.
Con i signed short si possono rappresentare numeri compresi tra [+32767,-32768]
Anche qui vale il complemento a 2, se si mette [+65535], ossia 16 '1', si avrà -32168 (2^n-x=-|y|).
Con gli unsigned short si possono rappresentare i numeri fra [0,65536]. */
case 2: //IMMISSIONE DI UNO SHORT
printf("\nImmettere un intero short: ");
fflush(stdin);
scanf("%hd", &(word.s[0]));
estrai_bit(sizeof(short), word.c, bit); //estrae i bit dal char inserito
/* Calcolo del valore intero partendo dalla stringa binaria della variabile di input, mediante la formula data.
Viene eseguito un ciclo per 16 volte effettuando la somma tra le potenze di 2 successive */
/* inserisce il risultato in una variabile SIGNED char */
for (i = 0, Potenza_Shift = 1; i < sizeof(short)*8; i++) {
sh += bit[i]*Potenza_Shift; //ch += (bit[i]*pow(2,i));
Potenza_Shift = Potenza_Shift << 1; //Aumenta di 1 l'esponente della potenza
}
//Val_X = Val_X + bit[i] * potenza del 2
/* inserisce il risultato in una variabile UNSIGNED char */
for (i = 0, Potenza_Shift = 1; i < sizeof(short)*8; i++) {
u_sh += bit[i]*Potenza_Shift; //ch += (bit[i]*pow(2,i));
Potenza_Shift = Potenza_Shift << 1; //Aumenta di 1 l'esponente della potenza
}
printf("Stringa binaria: ");
Visualizza_bit(bit, sizeof(short));
printf("\nValore binario con signed short: %d", sh);
printf("\nValore binario con unsigned short: %d", u_sh);
break;
/*TIPO LONG: Ha a disposizione 4 byte (32 bit) quindi può rappresentare 2^32 (4 294 967 296) valori.
Signed long si possono rappresentare numeri tra [(+2^31)-1,-2^31].
Unsigned short si possono rappresentare tra [0,2^32 - 1] valori */
case 3: //IMMISSIONE DI UN LONG
printf("\nImmettere un valore intero long: ");
scanf("%ld", &(word.l)); fflush(stdin);
estrai_bit(sizeof(long), word.c, bit);
/* Calcolo del valore intero partendo dalla stringa binaria della variabile di input, mediante la formula data.
Viene eseguito un ciclo per 8 volte effettuando la somma tra le potenze di 2 successive */
/* inserisce il risultato in una variabile SIGNED char */
for (i = 0, Potenza_Shift = 1; i < sizeof(long)*8; i++) {
lo += bit[i]*Potenza_Shift; //ch += (bit[i]*pow(2,i));
Potenza_Shift = Potenza_Shift << 1; //Aumenta di 1 l'esponente della potenza
}
//Val_X = Val_X + bit[i] * potenza del 2
/* inserisce il risultato in una variabile UNSIGNED char */
for (i = 0, Potenza_Shift = 1; i < sizeof(long)*8; i++) {
u_lo += bit[i]*Potenza_Shift; //ch += (bit[i]*pow(2,i));
Potenza_Shift = Potenza_Shift << 1; //Aumenta di 1 l'esponente della potenza
}
printf("Stringa binaria: ");
Visualizza_bit(bit, sizeof(long));
printf("\nValore binario con signed long: %d", lo);
printf("\nValore binario con unsigned long: %d", u_lo);
break;
default: break;
}
return 0;
}
/* Dal valore long, short o char si passa ad una stringa di bit */
estrai_bit(int len, ch[], bit[]) void char char {
j, jc;
short int c;
char j < MAX_LEN; j++) for (j = 0; bit[j] = 0;
//Scorri i byte della parola
jc < len; jc++) for (jc = 0;
//memorizza l'informazione individuata dal jc-esimo byte
{
c = ch[jc]; //Ricava ciò che trovi al byte jc
//scorri i bit del byte preso in esame
j < 8; j++) for (j = 0;
{
bit[j + 8 * jc] = c & 1; //individuando byte e bit, inserisce il valore del primo bit
c = c >> 1; //sposta di un posto per controllare il bit successivo
}
}
}
/* visualizza di una stringa di bit costruita */
Visualizza_bit(char bit[], len) void int {
j;
int for (j = len * 8 - 1; j >= 0; j--) {
printf("%d", bit[j]);
//Arrivato ad ogni 8 bit, prenditi uno spazio
if (j % 8 == 0) printf(" ");
}
}
OUTPUT: NB: 10000000000001 è in decimale! Giuseppe Accardo - Programmazione II
Esercizio 4
[Liv.1] Scrivere una function C per estrarre dalla variabile intera X i k bit più significativi o meno significativi, dove X e k sono i parametri di input, usando: 1) Una maschera. 2) L’operatore di shift (>> o <<). 3) Il prodotto o la divisione per potenza 2.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define len 8
Maschera(unsigned x, scelta, k); unsigned char char int int
Shift(unsigned x, scelta, k); unsigned char char int int
Prodotto_divisione(unsigned x, scelta, k); unsigned char char int int
bit_show(unsigned n); void char
main() int {
scelta, k; // k = n_bit maschera
int x, Mask_estratta, Shift_estratto, Pro_div_2_estratto;
unsigned char
//Input numero x
printf("Inserire un numero: ");
scanf("%d", &x);
bit_show(x);
//Meno o più significativi?
printf("\n\nVuoi estrarre i bit:\n[1] Più significativi\n[2] Meno significativi\n");
scanf("%d", &scelta);
//Quanti bit?
printf("Quanti bit estrarre?\n");
scanf("%d", &k);
/* estrai i bit in vari modi */
Mask_estratta = Maschera(x, scelta, k);
Shift_estratto = Shift(x, scelta, k);
Pro_div_2_estratto = Prodotto_divisione(x, scelta, k);
/* Stampa risultati*/
printf("\nValore iniziale: %d = ", x); bit_show(x);
printf("\n\nValore Estratto con la maschera : %d = ", Mask_estratta); bit_show(Mask_estratta);
printf("\n\nValore Estratto con i due shift : %d = ", Shift_estratto); bit_show(Shift_estratto);
printf("\n\nValore Estratto con i prodotti/rapporto : %d = ", Pro_div_2_estratto); bit_show(Pro_div_2_estratto);
printf("\n");
return 0;
}
Maschera(unsigned x, scelta, k) unsigned char char int int {
/* PREPARIAMO LA MASCHERA DI 32 bit */
/* unsigned, perché 2^32-1 mi darebbe un valore negativo complementato a 2. Con unsigned ho il controllo totale dei 32 bit */
Mask = 0, i;
unsigned char /* Sfruttando le POTENZE di 2 o lo shift, andiamo a "coprire" i k bit da estrarre */
//Avrei potuto fare anche Mask =(pow(2,k)-1
for (i = 1; i <= k; i++) Mask = Mask << 1 | 1;
//------- Estrarre bit --------
/* Per gli MSB SHIFTIAMO la MASK sinistra di 32-k e giungiamo mask con x */
if (scelta == 1) x & (Mask << (sizeof(unsigned return char) * 8 - k));
/* Per gli LSB non c’è bisogno di shiftare a destra, giungiamo la mask ottenuta */
else if (scelta == 2) x & Mask;
return x;
}
Shift(unsigned x, scelta, k) unsigned char char int int {
Bit_tot = unsigned short sizeof(unsigned char) * 8;
/* Estrarre i più significativi */
if (scelta == 1) {
x = x >> (Bit_tot - k); //shifta a destra MAX_BIT-k per cancellare i meno significativi
x = x << (Bit_tot - k); //shifta a sinistra MAX_BIT-k per l'astrazione
}
/* Estrarre i meno significativi */
else if (scelta == 2) {
x = x << (Bit_tot - k); //shifta a sinistra MAX_BIT-k per cancellare i meno significativi
x = x >> (Bit_tot - k); //shifta a destra MAX_BIT-k per l'astrazione
}
return x;
}
Prodotto_divisione(unsigned x, scelta, k) unsigned char char int int {
Bit_tot = unsigned short sizeof(unsigned char) * 8;
/* Il ragionamento è totalmente uguale a Shift()
Dato che >>1 corrisponde ad una divisione per 2^(1) e <<1 un prodotto per 2^(1),
Sostituiamo lo shift con le corrispondenti operazioni
Es. 12>>2 si ha 0011, cioè 12/2^(2) */
/* Estrarre i più significativi */
if (scelta == 1) {
x = x / pow(2, Bit_tot - k); //shifta a destra = divisione per una potenza di 2
x = x * pow(2, Bit_tot - k); //shifta a sinistra = prodotto per una potenza di 2
}
/* Estrarre i meno significativi */
else if (scelta == 2) {
x = x * pow(2, Bit_tot - k); //shifta a sinistra = prodotto per una potenza di 2
x = x / pow(2, Bit_tot - k); //shifta a sinistra = prodotto per una potenza di 2
}
return x;
}
bit_show(unsigned x) void char {
j;
short bit[len];
int bit[0] = 0; j = len - 1;
do {
bit[j] = x & 1; //prendi il primo bit e mettilo alla len-1 pos (stampa avverrà al contrario)
--j;
x = x >> 1; //sposta di 1 a destra per considerare i prossimi bit
} while (n != 0 && j >= 0);
//Finché il numero non è 0 e non ho completato tutti i len bit
//nel caso j non sia 0 gli altri bit della variabile vengono posti a 0
if (j > 0) {
do {
bit[j] = 0;
--j;
} while (j >= 0);
}
for (j = 0; j < len; j++) {
(j % 4 == 0) ? printf(" %d", bit[j]) : printf("%d", bit[j]); //stampa i bit della variabile
}
}
OUTPUT: Giuseppe Accardo - Programmazione II
Esercizio 5
[Liv.1] Scrivere due function C di conversione di un intero positivo (int) da base 10 a base 2 mediante l’algoritmo delle divisioni successive realizzato rispettivamente: - Usando gli operatori di quoziente e resto della divisione intera; - Usando gli operatori bitwise.
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEN 16
Conv_Quoz(unsigned X, Bit[]); void short unsigned short
Conv_Wise(unsigned X, Bit[]); void short unsigned short
Stampa_Bit(short Bit[]); void
main() int {
X;
unsigned short Bit[MAX_LEN]; //Per la visualizzazione binaria
unsigned short
printf("Inserire l'intero da trasformare in binario:\n");
scanf("%hd", &X);
/* Conversione effettuate mediante quoziente */
printf("Conversione effettuate mediante il quoziente:\n");
Conv_Quoz(X, Bit);
Stampa_Bit(Bit);
/* Conversione effettuate mediante i bitwise */
printf("\nConversione effettuate mediante i bitwise:\n");
Conv_Wise(X, Bit);
Stampa_Bit(Bit);
return 0;
}
/* Il valore di X diventerà il quoziente stesso.
Il vettore Bit[] conterrà bit con ordine MSB al più LSB (Bit[0] = LSB) */
Conv_Quoz(unsigned X, Bit[]) void short unsigned short {
R; //Definiamo resto e quoziente
unsigned short i = 0; short
/* Il ciclo si interrompe se il */
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
-
Appunti Informatica
-
Appunti Fondamenti di informatica
-
Appunti Fondamenti di informatica
-
Appunti Fondamenti di Informatica