Roozbeh G
Roozbeh G

Reputation: 557

whats the difference for indexing of signed and unsigned char in array?

I have to following code, which doesn't generate my expected results. Adding unsigned char would make it work. ( I realized it is not working by having another function doing the reverse, but not getting the reverse effect!) Can someone explain a bit to me.

The code is to substitute a 8 char string to some random chars.

My current code :

char subs[8][256];

void perfSubs(char* input){
for (int i = 0; i < 8; i++)
    input[i] = subs[i][input[i]];
}

I should change it to

input[i] = subs[i][(unsigned char)input[i]];

Upvotes: 2

Views: 1626

Answers (3)

chux
chux

Reputation: 153547

As mentioned by others and is well known that C has unsigned char, signed char and char types.
char has the same range as either unsigned char, signed char but is still a different type.

subs[i][input[i]]; may involve a negative index into subs[i][some_negative_value] casuing the problem.

input[i] = subs[i][(unsigned char)input[i]]; folds the negative values into positive ones that may come out of input[i], but that is implementation defined behavior as to how.

A simple solution can be had just using char.


To avoid a negative index, subtract the minimum char value, CHAR_MIN, whenever code uses char as an index. A typical value for CHAR_MIN is 0 or -128.

Also avoid the magic number 256 and use an array size based on char.

char subs[8][CHAR_MAX + 1 - CHAR_MIN];

input[i] = subs[i][input[i] - CHAR_MIN];

Depending on if char is signed or not, the location of using index 'A' may result in a different index, though consistent within a given compilation.

subs[0]['A' - CHAR_MIN] = 'x';

Upvotes: 2

R Sahu
R Sahu

Reputation: 206627

The standard does not dictate whether char is a signed type or an unsigned type. It can be signed type in one platform and unsigned type in another platform. If you want your code to be portable, pick a type that you can depend on.

In your case, you should use:

void perfSubs(unsigned char* input){
for (int i = 0; i < 8; i++)
    input[i] = subs[i][input[i]];
}

This makes sure that you get an unsigned char* to the function and not have to rely on whether the char type is a signed type or an unsigned type.

Upvotes: 1

Jean-Bernard Pellerin
Jean-Bernard Pellerin

Reputation: 12670

A signed char can hold values from -128 to 127. Since you're using the byte to store values from 0 to 255, you need an unsigned char.

Upvotes: 0

Related Questions