Q:

Most efficient way to find the index of the only '1' bit in a char variable (in C)

This is an interview question:
You are given a char variable named ch, when you know that it represents a number that in its binary form, only one of its eight bits will be equal to '1'. I.E. , the only possible values for ch are: 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80.
Given the variable ch, I need to write the most efficient code to get the index of that '1' bit. For example: if ch == 0x1 -> result is 0. if ch == 0x4 -> result is 2.          
The obvious way is to use switch-case, but I need something more efficient.
Is there any bit manipulation you can do here for efficient implementation?

A:

An unsigned char variable is supposedly only 8 bit wide. In order to encode the position of the bit we need only 3 bits. That means that we can build a 24-bit "table" that contains all 8 of possible 3-bit answers in their natural order
111 110 101 100 011 010 001 000 =

0xFAC688

If your variable ch is known to contain only one 1 bit, then it is a power of 2. Dividing something by ch will right-shift the original value by the index of your 1 bit. So, if we divide the above "table" by your ch three times the answer will get shifted to the lowest 3 bits of the result
unsigned position = (0xFAC688 / ch / ch / ch) & 0x7;

End of story. The above could probably be rewritten more efficiently, while preserving the general principle.

Note, that this is basically the same principle that's used in the approaches based on De Bruijn sequences. However, the purpose of De Bruijn sequence is to pack the index table in situations when the original "unpacked" table (like my table above) does not fit into an integer. As an "unpleasant" side effect, De Bruijn sequence reorders the index table, breaking the original natural sequence of indices. This requires extra re-mapping efforts to extract the proper result from the De Bruijn sequence.
With only 24 bits we don't have this problem here, which means that there's no need to involve De Bruijn and its accompanying tricks.
On the other hand, a packed table requires a shorter shift, which will simplify (and thus optimize) the calculation of the divisor to achieve the desired shift's length. In case of De Bruijn sequence, there's no need to calculate the divisor at all - your ch is already it. So, De Bruijn sequence might easily end up being more efficient.

A:

The type char may be either signed or unsigned (implementation-defined behavior). In order to safely operate on the value 0x80 we should operate explicitly with unsigned char data.
I assume that there are no special functions available that give us the bit position more or less directly, such as ffs() (find first set), clz() (count leading zeros), or popcount() (population count), and that we are to determine the bit position using just standard ISO C.
One approach is to spread each bit position in ch to a separate nibble (a four-bit group), then perform an in-register table lookup, where each table element comprises one nibble in a 32-bit int. 
The expansion can be accomplished by squaring the input twice, which moves bit [i] to bit [4*i]. Code below then uses a special trick to allow extraction of the table element with a multiply and a right shift, where the multiply moves the desired table entry into bits [31:28] of the intermediate result. Note that the table is specified in a readable way and equates to the constant0x01234567, a substitution every reasonable compiler will make.
Compiler Explorer (Godbolt) shows that most of the execution time cost of uchar_bitpos() is three dependent integer multiplies plus a couple of other instructions.
This code assumes 8-bit char and 32-bit int. For better portability unsigned char variables could be turned into uint8_t variables and unsigned int variables could be turned into uint32_t variables. 
#include <stdio.h>
#include <stdlib.h>

int uchar_bitpos (unsigned char ch)
{
    unsigned int ch_pow2, ch_pow4;
    const unsigned int table =
        ((0 << 28) | (1 << 24) | (2 << 20) | (3 << 16) | 
         (4 << 12) | (5 <<  8) | (6 <<  4) | (7 <<  0));
    ch_pow2 = ch * ch;
    ch_pow4 = ch_pow2 * ch_pow2;
    return (ch_pow4 * table) >> 28;
}

int main (void)
{
    unsigned char a = 0x80;
    do {
        printf ("a = %2x   bitpos=%d\n", a, uchar_bitpos (a));
        a = a / 2;
    } while (a);
    return EXIT_SUCCESS;
}

The output of the above program should look as follows:
a = 80   bitpos=7
a = 40   bitpos=6
a = 20   bitpos=5
a = 10   bitpos=4
a =  8   bitpos=3
a =  4   bitpos=2
a =  2   bitpos=1
a =  1   bitpos=0

