Depends on what they're being used for. If it's for storing string data, there's none. If it's for maths, then there's quite a bit.
A char is 8 bits, this gives you 256 different values that it may have. Unsigned chars must be positive. In this case, these 256 different values get mapped from 0-255.
However, when using signed chars we can have both positive and negative numbers. Since we want to have as many positive values as negative ones, we 'shift' the range that's represented, such that it goes from -127..128.
Since your code is using it as a character string, you don't have to actually do anything to it - you just need to tell the compiler to treat it as unsigned.
From your question, it seems likely that you have something declared as being char*, while another part of the code needs/expects an unsigned char*
So, you could just cast the thing.
I.e
char *someText = "abcdefg1234567890\n\r";
printf("%s", (unsigned char*)someText);
Alternatively, you could just create a copy of the string, using either strdup or the 3 functions strlen/malloc/strcpy (which strdup does internally)
EDIT: Perhaps this code will help explain it a bit?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, n;
char someData[] = { -2, -1, 0, 1, 2};
n = 5;
printf("String: '%s'\n\n", someData);
for (i=0; i<n; i++)
printf("(int) %d\n", (int)someData[i]);
printf("\n");
for (i=0; i<n; i++)
printf("(unsigned int) %d\n", (unsigned char)someData[i]);
printf("\n");
for (i=0; i<n; i++)
printf("(char) %c\n", (char)someData[i]);
}
Output
String: '■ '
(int) -2
(int) -1
(int) 0
(int) 1
(int) 2
(unsigned int) 254
(unsigned int) 255
(unsigned int) 0
(unsigned int) 1
(unsigned int) 2
(char) ■
(char)
(char)
(char) ☺
(char) ☻