-4

In my following code:

main(){
    int c;
    char c1='0';
    int x=9-c1;
    int y='9'-c1;
}

Now in this program I'm getting value of x as some arbitrary value, but the value of y is 0, which is the value that I expect. Why this difference?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Aman Bisht
  • 91
  • 1
  • 2

4 Answers4

4

Here is a good explanation. Just compile it and run:

#include <stdio.h>
int main(){
    int c;
    char c1='0';
    int x=9-c1;
    int y='9'-c1;
    printf("--Code and Explanation--\n");
    printf("int c;\n");
    printf("char c1='0';\n");
    printf("int x=9-c1;\n");
    printf("int y='9'-c1;\n");
    printf("c1 as char '0' has decimal value: %d\n", c1);
    printf("decimal 9 - decimal %d or c1 = %d or x\n", c1, x);
    printf("char '9' has decimal value %d - decimal %d or c1 = %d\n", '9', c1, y);
    printf("Your Welcome :)\n");
    return 0;
}
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
  • I have a doubt in this question , how its is able to generate correct output, in array we are writing a[c-'0'], c is an int ? therfore it should be -ve #include /* count digits, white space, others */ main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); } – Aman Bisht Aug 08 '15 at 15:27
  • 2
    What is probably a better question is why are you asking about arrays when the original question doesn't contain them. –  Aug 08 '15 at 15:42
  • @AmanBisht put those codes into `backticks` to make it readable. If it isn't relevant to the question, ask it in another different question – phuclv Aug 11 '15 at 12:23
3

1st char are integers. 2nd chars might have a printable representation or output controlling function (like for ASCII: TAB, CR, LF, FF, BELL ...) depending on the character set in use.

For ASCII

char c = 'A';

is the same as

char c = 65;

is the same as

char c = 0x41;

Another character set widely in use for example is EBCDIC. It uses a different mapping of a character's integer value to its printable/controling representation.

Internally always the same integer value is used/stored.

The printable, often but not always ASCII representation of, for example 65 or 0x41, which is A, is only used when

  1. either printing out using the printf()-family along with the conversion specifiers %s or %c or puts()
  2. or scanning in using the scanf()-family along with the conversion specifiers %s or %c or fgets()
  3. or when coding literals like 'A' or "ABC".

On all other operation only the char's integer value is used.

alk
  • 69,737
  • 10
  • 105
  • 255
2

When you do calculations with chars, you have to keep in mind that to you it looks like a '0' or '9', but the compiler interprets is as its ASCII value, which is 48 for '0' and 57 for '9'.

So when you do:

int x=9-c1;

the result is 9 - 48 = -39. And for

int y='9'-c1;

the result is 57 - 48 = 9.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
  • Nitpicking: "*`c1` is cast to its ASCII value*" not quiet right, as a) there is no cast, b) `char`s **are** integers, so even if there were a cast it woudn't be necessary. The character literal `'9'` is stored as integer, also no cast here, nor necessary. – alk Aug 08 '15 at 13:53
  • Thanks - I meant 'cast' as seen from the programmer's point of view. 'Interpreted' is probably better. – Glorfindel Aug 08 '15 at 13:55
  • 2
    C does not mandate a specific encoding, nor does it even mention the word "ASCII" except in some excursive footnotes. – Kerrek SB Aug 08 '15 at 14:13
  • I have a doubt in follw. prog. , how its is able to generate correct output, in array we are writing a[c-'0'], c is an int ? therfore it should be -ve #include /* count digits, white space, others */ main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); } – Aman Bisht Aug 08 '15 at 15:31
  • 3
    @AmanBisht hard to say without formatting - and you should ask that in a new question. – Glorfindel Aug 08 '15 at 15:34
  • @KerrekSB you're right, but I think that introducing the notion of character sets will confuse the OP even more. – Glorfindel Aug 08 '15 at 15:36
  • @KerrekSB - Except for decimal digits, where 5.2.1 of the C Standard (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) states: "the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous". I only note this because it's applicable to the question, especially after the comments above. – Andrew Henle Aug 08 '15 at 15:37
  • @AndrewHenle: That's not "ASCII". That's just saying that numeral characters have to be consecutive. – Kerrek SB Aug 08 '15 at 21:34
1

According to the C Standard (5.2.1 Character sets)

  1. ...In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.

Thus expression '9' - '0' has the same value like 9 - 0 and is equal to 9 whether you are using for example the ASCII table of characters or the EBCDIC.

Expression 9 - '0' is implementation defined and depends on the coding table you are using. But in any case the value of the internal representation of character '0' is greater then 9. (9 is the value of the tab character representation '\t')

For example in the ASCII the value of the code of character '0' is equal to 48. In the EBCDIC the value of '0' is equal to 240.

So you will get that 9 - '0' is some negative number.

For example it is equal to -39 if the character representations are based on the ASCII table or -231 if the character representations are based on the EBCDIC table.

You can see this yourself running this simple program

#include <stdio.h>

int main( void )
{
    printf( "%d\n", 9 - '0' );
}

You could write the printf statement also in the following way;)

printf( "%d\n", '\t' - '0' );

because 9 as I mentioned is the value of the internal representation of the escape character '\t' (tab).

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335