Here we can get up-close to bits and nibbles - for data storage nitty-gritty.  Re-use of 'pgm24' code makes quick work.

 

(right-click to download) 

/* pgm26 source */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>        // for 'system()' to clear the terminal window
#include <ctype.h>

enum stateflags {LOOPSTOP, LOOP4EVER};

/* ALL these user-functions came from pgm24's source */
/* code... Only slight modifications were made, given */
/* the smaller # of bits and nibbles to display */
char *return_nibble(int);
void prnt_data(unsigned int, char *);
void construct_32_bits_string(unsigned int, char *);
int cvrt_hexval_char_to_int(int);

int main(void)   {
     int flag;
     int c;              // VOODOO 'scanf()' fix
     unsigned int vala;
     unsigned int valb;
     unsigned int outval;

     flag = LOOP4EVER;

     do {
          printf("\nEnter NUM <space> NUM  (not over 255), accept with <Enter>: ");
          scanf("%d %d", &vala, &valb);

          printf("\n");
          prnt_data(vala, "(L) "); prnt_data(valb, "(R) ");
          printf("\n\n");

          while ((c = getchar()) != '\n' && c != EOF );            // VOODOO 'scanf()' fix

          outval = vala & valb; prnt_data(outval, "bitwise AND -- left & right "); printf("\n");
          outval = vala | valb; prnt_data(outval, "bitwise OR -- left | right "); printf("\n");
          outval = vala ^ valb; prnt_data(outval, "bitwise XOR -- left ^ right "); printf("\n");
          outval = vala << valb; prnt_data(outval, "L left-shifted by R -- left << right"); printf("\n");
          outval = vala >> valb; prnt_data(outval, "L right-shifted by R -- left >> right"); printf("\n");

          printf("\nPress <c + Enter> to continue / <x + Enter> to exit: ");
          if (getchar() == 'x')
               flag = LOOPSTOP;
          else
               system("clear");
          } while (flag == LOOP4EVER);

     printf("\n");
     return(0);
     }

void prnt_data(unsigned int numval, char *prefix)   {
     char rbuffer[48];

     construct_32_bits_string(numval, rbuffer);
     if (strlen(prefix) > 0)
          printf("%s ", prefix);
     printf("%s %-8u ", rbuffer, numval);
     }

void construct_32_bits_string(unsigned int val, char *result_string)   {
     char all_nibbles[9];
     char rn0[5]; char rn1[5]; char rn2[5]; char rn3[5];
     int n0; int n1; int n2; int n3;

     snprintf(all_nibbles, 9, "%08x", val);

     n0 = cvrt_hexval_char_to_int(all_nibbles[7]);
     n1 = cvrt_hexval_char_to_int(all_nibbles[6]);
     n2 = cvrt_hexval_char_to_int(all_nibbles[5]);
     n3 = cvrt_hexval_char_to_int(all_nibbles[4]);

     strcpy(rn0, return_nibble(n0));
     strcpy(rn1, return_nibble(n1));
     strcpy(rn2, return_nibble(n2));
     strcpy(rn3, return_nibble(n3));

     snprintf(result_string, 48, "%s %s %s %s", rn3, rn2, rn1, rn0);
     }

char *return_nibble(int nibble_value)  {
     static char *bytestrs[17] = {
          "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
          "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111",
          "UNKN"
          };

     return(bytestrs[nibble_value]);
     }

int cvrt_hexval_char_to_int(int achar)  {
     int retval;

     retval = (isdigit(achar) != 0) ? achar - 48 : achar - 87;
     if ((retval >= 0) && (retval < 16))
          return(retval);
     else {
          printf("\n\nUnexpected error.\n\n");
          return(-1);
          }
     }