wykorzystanie uni do wypisania bitów składowych

wykorzystanie uni do wypisania bitów składowych
Mateusz Janiak
  • Rejestracja:około 6 lat
  • Ostatnio:około 5 lat
  • Postów:24
0

muszę wykorzystując unie wypisać osiem bitów z bajta w tym celu zrobiłem coś takiego:

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

union bit_set
{
    unsigned char Char;
    unsigned char x:1; //wersja 2
    bool one_bit[8]; //wesja 1
};

int main()
{

    union bit_set myUnion;
    union bit_set *p_to_union = &myUnion;
    printf("Podaj liczbe: ");
    int check = scanf("%c", &(p_to_union->Char));
    while (check!=1)
    {
        printf("Incorrect input\n");
        return 1;
    }

//wersja 1
    for(int i = 0; i<8; i++)
    {
        printf("%d ", (unsigned char)*(p_to_union->one_bit+i));
    }

    printf("\n");

//wersja 2
    for(int i = 0; i<8; i++)
    {
        printf("%d ", (unsigned char)(p_to_union->x+i));
    }

    printf("\n");

    return 0;
}

jednak żaden z moich pomysłów nie zadziałał i nie wiem czemu. Proszę o wyjaśnienie błędów a nie tylko odpowiedź.

AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
0

Dodawanie adresów +1 NIE DOTYCZY pól bitowych. Dobre książki to podkreślają.
Odwołam się do programistycznej wyobraźni: jaki by to adres miał być, jeśli adres x:1 jest 0x123456,(choć już tu nic nie wiadomo o położeniu tego bitu w bajcie / słowie -> to tymbardziej wynik jest nieosiągalny)


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 1x, ostatnio: AnyKtokolwiek
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Na 99% Twój bool jest tak naprawdę intem, a nie typem o szerokości jednego bitu.

https://stackoverflow.com/questions/3497345/is-there-a-way-to-access-individual-bits-with-a-union


kq
BOOL w WINAPI jest intem, w C _Bool (czyli bool z stdbool.h) jest zdefiniowany jako integer mogący przechowywać wartości 0 i 1, i ma rank niższy niż wszystkie inne integery (w tym char). Więc raczej spodziewałbym się że jest 1-bajtowy.
Patryk27
Thanx, good to know - orientujesz się przy okazji czy któryś z kompilatorów potrafi przeprowadzać optymalizacje na tablicach booli (zamieniając je na bitset)? Coś w stylu specjalnego przypadku std::vector<bool> z C++.
kq
TL;DR: Nie słyszałem o tym. Jak tablica jest widoczna na zewnątrz (otrzymana w funkcji jako global/param, lub przekazana dalej), to kompilator nie może tego zrobić, bo nie może zmienić ABI, a to nakazuje aby każdy obiekt poza bitfieldami w strukturach miał własny unikalny wskaźnik i był adresowalny. Jeśli masz taką tablicę wewnątrz funkcji i ona nigdzie nie ucieka to na pewno może tak zrobić z powodu as-if rule, ale trzeba by się było postarać o ciekawy przykład, gdzie taka optymalizacja ma sens.
Mateusz Janiak
  • Rejestracja:około 6 lat
  • Ostatnio:około 5 lat
  • Postów:24
0

A macie jakieś pomysły dzięki którym będę w stanie osiągnąć efekt?
Patryk27, dzięki za linka ale nie mogę używać operatorów bitowych a w całym programie może być jeden if

edytowany 1x, ostatnio: Mateusz Janiak
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

nie mogę używać operatorów bitowych a w całym programie może być jeden if

Pierwsza (najwyżej punktowana) odpowiedź w zalinkowanym przeze mnie wątku wykorzystuje unię, zawiera zero operatorów bitowych oraz zero instrukcji warunkowych.


edytowany 2x, ostatnio: Patryk27
Mateusz Janiak
  • Rejestracja:około 6 lat
  • Ostatnio:około 5 lat
  • Postów:24
0

tak wiem już ogarnąłem on tam później pokazywał przykład po prostu, przepraszam.
jest jakiś sposób na zautomatyzowanie tego? Wiem że z zapisem x:1 nie można użyć tablic(w zadaniu też mam punkt że nie mogę ich wykorzystywać). Chodzi mi o jakieś przejście w pętli.

Kopiuj
union bit_set
{
    unsigned char Char;
    struct
    {
        unsigned char bit1 : 1;
        unsigned char bit2 : 1;
        unsigned char bit3 : 1;
        unsigned char bit4 : 1;
        unsigned char bit5 : 1;
        unsigned char bit6 : 1;
        unsigned char bit7 : 1;
        unsigned char bit8 : 1;
    }u;
};

int main()
{

    union bit_set myUnion;
    union bit_set *p_to_union = &myUnion;
    printf("Podaj liczbe: ");
    int check = scanf("%c", &(p_to_union->Char));
    while (check!=1)
    {
        printf("Incorrect input\n");
        return 1;
    }

    p_to_union->Char -= '0';

    printf("%d ", (p_to_union->u.bit8));
    printf("%d ", (p_to_union->u.bit7));
    printf("%d ", (p_to_union->u.bit6));
    printf("%d ", (p_to_union->u.bit5));
    printf("%d ", (p_to_union->u.bit4));
    printf("%d ", (p_to_union->u.bit3));
    printf("%d ", (p_to_union->u.bit2));
    printf("%d ", (p_to_union->u.bit1));

    printf("\n");

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.