Search code examples
cascii

Comparing pointers


This code is to convert integer numbers to character numbers. I can not understand why the condition of this while loop: while(savestr < str) will be true until the end of that loop?!

 while (savestr < str) {
          temp = *str ;
          *str-- = *savestr ;
          *savestr++ = temp ;

In what aspect that constion works? ASCII value? So in aspect of ASCII value how the loop condition works?!

Here's the code:

#include <stdio.h>
#include <conio.h>
void int_to_ascii( int , char *);
int main()
{
    int number ;
    char s[10] ;
    clrscr();
    printf(" enter a number :");
    scanf("%d", &number) ;
    int_to_ascii(number, s) ;
    printf(" the string value is: %s ", s);
    getch();
    return 0;
}
//**********************************
void int_to_ascii(int value, char *str)
{
    int saveval = value ;
    char temp, *savestr = str ;
    if(value < 0)
    value *= -1 ;
    do{
    *str++ = (value % 10) + 48 ;
    value = value / 10 ;
    } while(value > 0);
    if (saveval < 0)
       *str++ = '-' ;
    *str-- = '\0' ;
    while(savestr < str) {
      temp = *str ;
      *str-- = *savestr ;
      *savestr++ = temp ;
    }
}

Solution

  • This loop:

        do {
            *str++ = (value % 10) + 48;
            value = value / 10;
        } while (value > 0);
    

    Converts value to a numeral by taking the last digit (value % 10), adding the ASCII code for the character “0” (48), and putting the sum in str (*str =). It also increments str to point to the next space in memory (*str++ =). Adding the code for “0” works because, in C, the codes for the digit characters “0” through “9” are consecutive (in ASCII: 48, 49, 50, 51, 52, 53, 54, 55, 56, 57). So, if the last digit of value (value % 10) is 5, adding 5 to 48 produces 53, which is the code for “5”.

    There is no reason to use 48 here. The code would be better written as *str++ = (value % 10) + '0';. This has two benefits: It makes it clear to a reader that we are adding the code for the character “0”; they do not need to remember or figure out what 48 is. And it removes the assumption that ASCII is in use; this code will work with other character code schemes.

    Then value = value / 10; removes the last digit, leaving the earlier digits of value, if any. And while (value > 0) continues the loop if there are any more digits.

    When this loop is done, the memory that str initially pointed to contains the characters of the numeral for value. However, they are backwards, because we wrote the last digit first and the first digit last. And str now points to the end of the characters (one position beyond the last one). The saved value in savestr points to the first position.

    This code:

        if (saveval < 0)
            *str++ = '-';
        *str-- = '\0';
    

    adds a minus sign if the value is negative and then adds a null character to mark the end of the string. It leaves str pointing to the last position before the null character.

    Since the digits were written in reverse order, we must reverse them. This loop does that:

        while (savestr < str) {
            temp = *str;
            *str-- = *savestr;
            *savestr++ = temp;
        }
    

    savestr < str is true as long as savestr points to an earlier place in the allocated memory than str does. When two pointers are compared, if they point to elements in the same array, one is less than the other if it points to an earlier element (one with a lower array index). Initially, savestr points to the first character in the string, and str points to the last character (before the terminating null character).

    Then:

    • temp = *str; remembers the character that str points to.
    • *str-- = *savestr; moves the character that savestr points to to the place that str points to, and, because of the --, it decrements str to point to earlier in memory.
    • *savestr++ = temp; puts the remembered character in the place savestr points to, and, because of the ++, it increments savestr to point to later in memory.

    Thus characters from earlier in the string are swapped with characters later in the string, and savestr is advanced to later in the string while str is moved to earlier in the string. Eventually, savestr and str meet or cross, and the while condition savestr < str becomes false, at which point the loop stops, and the string has been reversed.