What is the difference between signed int or signed char and only int or char?

Debojit Acharjee 435 Reputation points

I want to know what is the difference between declaring a variable as signed int or signed char instead of only int or char?

I have also declared a variable as unsigned integer in the following program, but why it still stores a signed integer?

#include <stdio.h>

int main()
  unsigned int a;

  a = -100;

  printf("%d", a);

  return 0;



Visual Studio
Visual Studio
A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.
4,853 questions
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,602 questions
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,625 questions
0 comments No comments
{count} votes

5 answers

Sort by: Most helpful
  1. David Lowndes 4,711 Reputation points

    No difference unless you're using some compiler option to alter the default behaviour.
    The output is determined by your use of %d. Use %u if you want unsigned.

  2. Bruce (SqlWork.com) 60,866 Reputation points

    The main difference is the overflow behavior with arithmetic operations. The languages defines the overflow behavior for unsigned, but not signed. the behavior of signed depends on whether the hardware arithmetic is one’s or two's complement. Most hardware today uses twos complement.


    during assignment, it just a copy of the bits. if the copy is to a larger size, say int to char, then sign extension is used if 2's complement. if down sized then masked.

    // lets use char an its a know 8 bit size and we don't need to 
    // worry about bitness (little vs big endian) (00-ff hex)
    // unsigned is 0 - 255 
    // signed is -128 - 127 
    char a = 255;          //ff hex, all bits so overflow signed bit set
    unsigned char b = 255; //ff hex, no overflow
    int b = a;       // = -1 due to sign extension
    int d = c;       // = 255 as no sign extension
    int e = 256;     //0100 hex
    char f = e;      // e & ff == 0
    0 comments No comments

  3. Barry Schwarz 2,506 Reputation points

    Declaring a variable as an int is equivalent to declaring it as a signed int.

    When you declare a variable as a char, the system determines if it is a signed char or an unsigned char. Most Windows systems default to signed. Other systems (such as IBM mainframes) default to unsigned.

  4. didier bagarry 160 Reputation points

    You use tag C# and C++, but your code is in C language! I answer for C and C++.

    Difference between signed int and int : none, signed int and int are synonyms.

    Difference between signed char and char : Depends whether the char is signed or unsigned (it's a compiler option), if char is signed, signed char is then totally equivalent to char. In C we can say it's the same type. Note that it's not the case in C++, signed char, unsigned char and char are 3 different types but 2 shared exactly the same limits (at least from -127 to 127).

    The unsigned in the code (a synonym of unsigned int), in printf() the format %d must be associated with an int value, the format for unsigned int is %u. The choice of signed or not is in the %d or %u.

    Notice that it's possible to write (in C and in C++):

    int  x = -100;
    unsigned  y = x;
    int  z = y;
    printf( "z is %d", z );   // int then unsigned then int
    // but the value in y is only valid if the initial content of x was in common area between int and unsigned so between 0 and INT_MAX
    printf( "y is %u\n", y );
    0 comments No comments

  5. Darran Rowe 561 Reputation points

    A bit late to this party, but there is a difference in the relationship between char, signed char and unsigned char when compared to int, signed int and unsigned int.

    The following shows some differences in how the compiler handles these.

    void my_fun(char c)
    	printf("In char\n");
    void my_fun(signed char c)
    	printf("In signed char\n");
    void my_fun(unsigned char c)
    	printf("In unsigned char\n");

    The above compiles fine.

    void my_fun(int i)
    	printf("In int\n");
    void my_fun(signed int i)
    	printf("In signed int\n");
    void my_fun(unsigned int i)
    	printf("In unsigned int\n");

    The above emits a compiler error stating that void my_fun(int) already has a function body.

    There are other differences in the handling.

    std::is_same_v<int, signed int>; //this is true
    std::is_same_v<int, unsigned int>; //this is false
    std::is_same_v<char, signed char>; //this is FALSE!!
    std::is_same_v<char, unsigned char>; //this is false
    char c1 = 'c';
    //this assigned the value due to integral conversions
    //it is why you can do the same thing with int, i.e.
    //int i = 'c';
    signed char c2 = 'c';
    auto fmt_str1 = std::format("{}", c1); //fmt_str1 contains "c"
    auto fmt_str2 = std::format("{}", c2); //fmt_str2 contains "99"

    So, for char, it is better to see the type without anything else as a character type, but when it has signed or unsigned then you should see it as an 8 bit integral type. Or, better yet, only ever use char and when you want to work with numbers, use int8_t and uint8_t defined in stdint.h.

    0 comments No comments