Škôlka jazyka C

Fórum o programovaní v jazyku C založené 3. januára 2012

Aktuálny čas je 21 Jan 2021, 22:24

Všetky časy sú v GMT + 1 hodina




Fórum je zamknuté Táto téma je zamknutá, nemôžete posielať nové príspevky alebo odpovedať na staršie.  [ Príspevok: 1 ] 
Autor Správa
PoslaťNapísal: 27 Jan 2013, 11:09 
Offline
Stredoškolák
Stredoškolák
Obrázok užívateľa

Registrovaný: 06 Jan 2012, 19:26
Príspevky: 458
Bydlisko: pod Pátrovom
Udelené body: 228 bodov
Získané body: 21 bodov
1. Napíš funkciu int dlzka_int(void), ktorá vráti dĺžku premennej typu int v bitoch.
Zabezpeč, aby funkcia pracovala správne na ľubovoľnom type počítača. Vyskúšaj v programe.
Spoiler:
Kód:
/**********************************
 * 1.c    v.1.0
 *
 * Zistenie dlzky typu int v bitoch
 * ================================
 *
 **********************************/

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

#define VELKOST_INT (sizeof(int) * 8) // pocet bitov v int, v mojom pripade 32

/* uplne funkcne prototypy funkcii */
char* des_dvoj_kr(unsigned int desiatkove);
int dlzka_int(void);

/* funkcia main() */
int main(void)
{
  printf("\nDlzka cisla typu int je %d bitov.\n", dlzka_int());

  return 0;
}

/* zjisti dlzku int v bitoch */
int dlzka_int(void)
{
    unsigned int x, i = 0;

    /* mozne definicie maximalneho cisla unsigned int,
        vsetky si ich mozte vyskusat */
    //x = ~0;
    //x &= ~0;
    //x &= ~0xF;
    //x = 0xFFFFFFFF;
    //x = 0xffffffff;
    //x = 42949672945;
    //x = UINT_MAX;
    x = -1;

    printf("maximalne unsigned cislo je %u\n\n", x);

    /* Vypocet poctu bytov za pomoci bitoveho posunu doprava
       z maximalneho cisla unsignad int sa budeme postupne posuvat
       do prava po jednom bite az po nulu, teda bity sa posuvaju
       a zlava stracaju, menia sa na nuly a vlastne dekadicke cisla
       sa postupne znizuju delenim dvomi */
    printf("%2d. bit ->\tdec: %10u\t bin: %32s\n", i, x, des_dvoj_kr(x));
    while ((x >>= 1) != 0) { // bitovy posun do prava
        i++;
        printf("%2d. bit ->\tdec: %10u\t bin: %32s\n", i, x, des_dvoj_kr(x));
    }
    i += 1;
    printf("%2d. bit ->\tdec: %10u\t bin: %32s\n", i, x, des_dvoj_kr(x));
    return (i);
}

/* pomocna fánkcia na vypis binarneho cisla
   prevod z desiatkoveho na dvojkove, vystup dvojkove (retazec) */
char* des_dvoj_kr(unsigned int desiatkove)
{
    int i = 0, j, k = -1;
    char *p_pom, *p_pom1, *p_dvojkove;

    /* dynamicka alokacia s kontrolou volnej pamati */
    if ((p_pom = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }
    if ((p_pom1 = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }
    if ((p_dvojkove = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }

    /* vypocet dvojkoveho cisla, prevod na retazec, jeho otocenie od zadu,
       doplnenie nul do celej dlzky dvojkoveho cisla */
    while (desiatkove != 0) { // cyklus kym nebude 0
        p_pom[i] = (desiatkove % 2) + 48; //zvysok po deleni 2 zmeneny na znak
        desiatkove /= 2;
        i++; // pom[i] sa zvacsuje s kazdym cyklom
    }
    p_pom[i] = '\0'; // ukoncenie retazca
    for (j = i; j >= 0; j--)
        p_pom1[j] = p_pom[k++]; // prepis od zadu
    p_pom1[i + 1] = '\0'; // ukoncenie retazca
    for (j = 0; j < VELKOST_INT - strlen(p_pom1); j++) // doplnenie nul do velkosti
        p_dvojkove[j] = '0';                           // int minus velkost p_pom1
    strcat(p_dvojkove, p_pom1); //spojenie retacov do jedneho bin cisla

    return (p_dvojkove);
}

2. Napíš funkciu unsigned rotuj_doprava(unsignet x, int n), ktorá spôsobí rotáciu
(nie posun) čísla o n bitov doprava. Vyskúšaj v programe.
Spoiler:
Kód:
/***************************
 * 2.c    v.1.0
 *
 * Rotacia bitov doprava
 * =========================
 *
 * bity sa posuvaju do prava
 * a nulty bit sa presuva
 * na najvyssi bit
 *
 ***************************/

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

#define VELKOST_INT (sizeof(int) * 8) // pocet bitov v int, v mojom pripade 32

/* uplne funkcne prototypy funkcii */
unsigned rotuj_doprava(unsigned int x, int n);
char* des_dvoj_kr(unsigned int desiatkove);

/* funkcia main */
int main(void)
{
    unsigned cislo, i = 0;

    cislo = 2147483648;

    /********************************************************************
     * vyskusaj si aj zadavanie cisiel, odkomentuj nasledujuce dva riadky
     * a zakomentuj riadok: cislo = 2147483648;
     ********************************************************************/
    //printf("Zadaj kladne cislo. ktore chces rotovat do prava: ");
    //scanf("%u", &cislo);

    printf("%u(d) %0*x(h) %32s(b)\n\n", cislo, sizeof(int) * 2, rotuj_doprava(cislo, i),
            des_dvoj_kr(rotuj_doprava(cislo, i)));
    /* vypise o kolko bitov je rotacia, dec cislo, hex cislo a bin cislo */
    for (i = 0;  i <= sizeof(int) * 8;  i++) {
        printf("rotacia %2d bit: %10u(d) %0*x(h) %32s(b)\n", i,
                rotuj_doprava(cislo, i), sizeof(int) * 2, rotuj_doprava(cislo, i),
                des_dvoj_kr(rotuj_doprava(cislo, i)));
    }

    return 0;
}

/* rotuje bity doprava */
unsigned rotuj_doprava(unsigned int x, int n)
{
    unsigned int i, k;

    /* priprava jednotky v najvyssom bite */
    /* do unsigned k vlozime same jednotky (negacia nuly) */
    k = ~0;  /* 4294967295(d) ffffffff(h) 11111111111111111111111111111111(b) */
    /* na najvyssí bit dame nulu (posun doprava o jeden bit) */
    k >>= 1; /* 2147483647(d) 7fffffff(h) 01111111111111111111111111111111(b) */
    /* spravime negaciu, teda na najvyssom bite bude jednotka a dalej nuly */
    k = ~k;  /* 2147483648(d) 80000000(h) 10000000000000000000000000000000(b) */

    while (n-- != 0) {
        i = x & 1;
        x >>= 1;
        x |= (i == 1)  ?  k  :  0;
    }

    return x;
}

/* pomocna fánkcia na vypis binarneho cisla
   prevod z desiatkoveho na dvojkove, vystup dvojkove (retazec) */
char* des_dvoj_kr(unsigned int desiatkove)
{
    int i = 0, j, k = -1;
    char *p_pom, *p_pom1, *p_dvojkove;

    /* dynamicka alokacia s kontrolou volnej pamati */
    if ((p_pom = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }
    if ((p_pom1 = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }
    if ((p_dvojkove = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }

    /* vypocet dvojkoveho cisla, prevod na retazec, jeho otocenie od zadu,
       doplnenie nul do celej dlzky dvojkoveho cisla */
    while (desiatkove != 0) { // cyklus kym nebude 0
        p_pom[i] = (desiatkove % 2) + 48; //zvysok po deleni 2 zmeneny na znak
        desiatkove /= 2;
        i++; // pom[i] sa zvacsuje s kazdym cyklom
    }
    p_pom[i] = '\0'; // ukoncenie retazca
    for (j = i; j >= 0; j--)
        p_pom1[j] = p_pom[k++]; // prepis od zadu
    p_pom1[i + 1] = '\0'; // ukoncenie retazca
    for (j = 0; j < VELKOST_INT - strlen(p_pom1); j++) // doplnenie nul do velkosti
        p_dvojkove[j] = '0';                           // int minus velkost p_pom1
    strcat(p_dvojkove, p_pom1); //spojenie retacov do jedneho bin cisla

    return (p_dvojkove);
}

3. Napíš funkciu unsigned invert(unsigned x, int p, int n), ktorá invertuje
(zmení 1 za 0 a naopak) n bitov premennej x počnúc od pozície p vrátane.
Ostatné bity ostanú nezmenené. Vyskúšaj v programe.
Spoiler:
Kód:
/************************
 * 3.c    v.1.0
 *
 * Inverzia skupiny bitov
 * ======================
 *
 ************************/

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

#define VELKOST_INT (sizeof(int) * 8) // pocet bitov v int, v mojom pripade 32

/* uplne funkcne prototypy funkcii */
unsigned invert(unsigned int x, int p, int n);
char* des_dvoj_kr(unsigned int desiatkove);

/* funkcia main */
int main(void)
{
    unsigned int cislo, i, j;

    /* zadanie vstupnych dat */
    printf("Zadaj unsigned int cislo: ");
    scanf("%u", &cislo);
    printf("Zadaj od ktorej pozicie sa maju bity invertovat: ");
    scanf("%u", &i);
    printf("Zadaj kolko bitov sa ma invertovat: ");
    scanf("%u", &j);
    /* vypis vystupov */
    printf("\n%s\n", des_dvoj_kr(cislo)); // zadane cislo binarne
    printf("%s\n", des_dvoj_kr(invert(cislo, i, j))); // invert coslo binarne

  return 0;
}

/* invertuje skupinu zadanu bitov p = pozicia od, n = pocet invertovanych bitov */
unsigned invert(unsigned int x, int p, int n)
{
    unsigned int i, k = x, j = p, l, m;

    m = VELKOST_INT;

    if (n <= m) { // aby pocet invertovanych bitov nebol vacsi ako velkost int
        if (n <= j) { // ak pocet bitov neprekroci pravy posledny bit
            i = j - n; // posledny bit na inverziu vpravo od pozicie
            while (j > i) { // od pozicie po posldeny bit na inverziu vravo
                k ^= (1 << j - 1); // negacia vyclenenych bitov
                j--; // krok
            }
        }
        else {
            while (j > 0) { // od pozicie po posldny bit vpravo (0)
                k ^= (1 << j - 1); // negacia vyclenenych bitov
                j--; // krok
            }
            l = m - (n - p); /* poradove cislo bitu potrebne pri prekroceni
                                prveho praveho bitu a presunu na prvy lavy bit
                                aby sme vedeli az pokial sa budu bity invertovat*/

            while (m > l) { // od 1. bitu vlavo po l
                k ^= (1 << m - 1); // negacia vyclenenych bitov
                m--; // krok
            }
        }
    }
    else
    printf("Pocet invertovanych bitov mimo rozsah! Neinvertujem!\n");

    return k;
}

/* pomocna fánkcia na vypis binarneho cisla
   prevod z desiatkoveho na dvojkove, vystup dvojkove (retazec) */
char* des_dvoj_kr(unsigned int desiatkove)
{
    int i = 0, j, k = -1;
    char *p_pom, *p_pom1, *p_dvojkove;

    /* dynamicka alokacia s kontrolou volnej pamati */
    if ((p_pom = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }
    if ((p_pom1 = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }
    if ((p_dvojkove = (char *) malloc(35)) == NULL) {
        printf("Malo pamati!");
        return;
    }

    /* vypocet dvojkoveho cisla, prevod na retazec, jeho otocenie od zadu,
       doplnenie nul do celej dlzky dvojkoveho cisla */
    while (desiatkove != 0) { // cyklus kym nebude 0
        p_pom[i] = (desiatkove % 2) + 48; //zvysok po deleni 2 zmeneny na znak
        desiatkove /= 2;
        i++; // pom[i] sa zvacsuje s kazdym cyklom
    }
    p_pom[i] = '\0'; // ukoncenie retazca
    for (j = i; j >= 0; j--)
        p_pom1[j] = p_pom[k++]; // prepis od zadu
    p_pom1[i + 1] = '\0'; // ukoncenie retazca
    for (j = 0; j < VELKOST_INT - strlen(p_pom1); j++) // doplnenie nul do velkosti
        p_dvojkove[j] = '0';                           // int minus velkost p_pom1
    strcat(p_dvojkove, p_pom1); //spojenie retacov do jedneho bin cisla

    return (p_dvojkove);
}

4. Napíš program, ktorý bude využívať bitové pole na úschovu dátumu. Položky poľa budú:

bity 15 - 9 : rok, ku ktorému sa pripočíta konštanta 1980
teda 22 znamená v skutočnosti rok 2002
bity 8 - 5 : mesiac
bity 4 - 0 : deň

Program vyskúšaj tak, že načítaš z klávesnice dátum, uložíš ho do bitového poľa, to vytlačíš
ako typ unsigned a potom dátum vytlačí ako naozajstný dátum. Na vytlačenie premennej
ako unsigned použi union.
Spoiler:
Kód:
/******************************************************
 * 4.c    v.1.0
 *
 * Bitove pole - pouzitie pro ulozenie zhusteneho cisla
 * ====================================================
 *
 ******************************************************/

#include <stdio.h>

typedef struct {
  unsigned den    : 5;   // bity 0 -  4
  unsigned mesiac  : 4;  // bity 5 -  8
  unsigned rok    : 7;   // bity 9 - 15
} DATUM;

typedef union {
  DATUM         datum;   // deklarovana premenna typu DATUM
  unsigned int  cislo;   // deklarovana premenna typu unsigned int
} BITY; // deklarovany union typ

int main(void)
{
    BITY dnes; // deklarovana premenna typu BITY
    unsigned int den, mesiac, rok;

    printf("Zadaj dnesni datum [dd.mm.rrrr]: ");
    scanf("%d.%d.%d", &den, &mesiac, &rok);
    dnes.datum.den = den;
    dnes.datum.mesiac = mesiac;
    dnes.datum.rok = rok - 2000; // rok dnesneho datumu je nad 2000
    //printf("Premenna ako unsigned int je %u\t%s\n", dnes, des_dvoj_kr((unsigned int) dnes));
    printf("Premenna ako unsigned int je %u\n\n", dnes);
    printf("Dnesny datum je %2u.%2u.%4u\n\n", dnes.datum.den, dnes.datum.mesiac, dnes.datum.rok + 2000);

    printf("Vysvetlenie na datume 23.1.2013:\n"
           "Premenna 3077839415(d) je 111111111111101 0001101 0001 10111(b)\n"
           "pricom bity:\n"
           "0 -  4 (10111)   obsahuju cislo 23\n"
           "5 -  8 (0001)    obsahuju cislo 1\n"
           "9 - 15 (0001101) obsahuju cislo 13, teda 2013 - 2000.\n\n");


    return 0;
}

_________________
kódy píšem na platforme: linux Ubuntu 12.04 (Geany, Code::Blocks), WinXP (Code::Blocks, PsPad editor),
Skype: libcokamo, ICQ: 56312279
Ak treba, napíš mi na libcosenior@gmail.com. To mám v mobile a stále po ruke.


Detaily príspevku Upozorniť užívateľa
Hore
 Profil  
 
Zobraziť príspevky z predchádzajúceho:  Zoradiť podľa  
Fórum je zamknuté Táto téma je zamknutá, nemôžete posielať nové príspevky alebo odpovedať na staršie.  [ Príspevok: 1 ] 

Všetky časy sú v GMT + 1 hodina


Kto je on-line

Užívatelia prezerajúci fórum: Žiadny registrovaný užívateľ nie je prítomný a 1 hosť


Rýchla úprava:
Nemôžete zakladať nové témy v tomto fóre
Nemôžete odpovedať na témy v tomto fóre
Nemôžete upravovať svoje príspevky v tomto fóre
Nemôžete mazať svoje príspevky v tomto fóre
Nemôžete zasielať súbory v tomto fóre

Hľadať:
Skočiť na:  
cron
Powered by phpBB® Forum Software © phpBB Group

Hosted by FreeSpace SK