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 ;
}
}
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.