2014-03-04 159 views
0

我希望有人能解釋爲什麼這個程序的作品。我是C的初學者。 程序返回用戶輸入的號碼(例如1234 = 4321)。如果反轉初始化爲零,那麼爲什麼第7行有意義?對不起,關於標題,不知道該怎麼問。這個循環爲什麼起作用?

int n, reverse=0, rem; 
printf("Enter an integer: "); 
scanf("%d", &n); 
while(n!=0) 
{ 
rem=n%10; 
reverse=reverse*10+rem; 
n/=10; 
} 
+0

http://stackoverflow.com/questions/20477728/understanding-number-reversing-using-loop?rq = 1 這個答案是我能找到的最接近的,但是在使用printfs看看發生了什麼之後,我不確定爲什麼reverse會有一個值。 – mungostrap

+3

'reverse = reverse * 10 + rem;'由於'reverse * 10 == 0',第一次反轉設置爲'rem'。在後續運行中,反向> 0,因此該線路按預期工作。 – ChicagoRedSox

+1

爲什麼將零乘以零是有意義的? –

回答

4

代碼正在使用整數運算符%的方式利用和/ *到:

  • 得到一個數字的最右邊的十進制數字:1234 % 10 == 4
  • 刪除了一些最右邊的小數位數:1234/10 == 123
  • 一個數字增加了許多的右側:123 * 10 + 4 == 1234

使用那些它重複讀取數字關閉n和將它們推送到reverse

123 0 
12 3 
1 32 
0 321 

手工操作代碼,它應該是有意義的。取一個初始值n ==「123」。

Is n zero? No, so go into the loop. 
rem = n%10 == 123 % 10 == 3 
reverse = reverse * 10 + rem == 0 * 10 + 3 == 3 
n = n/10 == 123/10 == 12 

Is n zero? No, so loop around. 
rem = n%10 == 12 % 10 = 2 
reverse = reverse * 10 + rem == 3 * 10 + 2 == 32 
n = n/10 == 12/10 = 1 

Is n zero? No, so loop around.. 
rem = n%10 == 1 % 10 = 1 
reverse = reverse * 10 + rem == 32 * 10 + 1 == 321 
n = n/10 == 1/10 = 0 

Is n zero? Yes, so leave the loop. 
reverse == 321 

或者爲零輸入重新開始:

Is n zero? Yes, so leave the loop. 
reverse == 0 

這個程序是相當無意義的,但它是值得意識到,同樣的原則等基礎工作,如16(十六進制)和2 (二進制) - 如果你最終做某種編程,那將是有用的。

+0

所有的答案都很棒,但是你付出的努力確實幫助我理解了它,所以我會選擇這個答案作爲答案!謝謝! – mungostrap

1

如果反轉爲零,則「reverse * 10 + rem」的值僅爲「rem」。

1

其餘n%10總是n的最後十進制數,而使用就行n/=10(同n = n/10整數除法最後一個小數位被有效地丟棄。因此rem將依次變爲n的每個十進制數字,從最低有效位數開始。通過始終將數字添加到末尾(+rem),同時將先前添加的數字移到左側(reverse*10)的一個位置來構建反向。前導零(如初始值reverse)不起作用(0*10 == 0)。

至於爲什麼reverse被初始化:未初始化的變量的初始值在C中是未定義的,因此在第一個reverse*10之後可能會產生任何結果。另外,如果用戶輸入0作爲數字,則循環條件爲false,循環體從不運行,但0的反向則正確(0)。

2

讓我們一步一步來。

  1. rem=n%10;需要的rem除以10在1234的情況下的餘數,這意味着1234 % 10是4.
  2. reverse=reverse*10+rem; 10(變速值的左邊,如果你願意)倍數其值,然後增加了rem。因爲,在循環的第一圈,其值是10,我們只需添加4中,出於4.
  3. n/=10;結果是整數除以10。這意味着,1234/10 = 123(任何小數丟失)。
  4. 新一輪的循環!現在,第一行是rem= 123 % 10;或3
  5. reverse=reverse*10+rem;現在reverse=4*10+3;或43(在此注意的圖案的開始?)
  6. n/=10;所以現在n = 12;

重複步驟4至6 n = 12直到n = 0。我將把它作爲練習給讀者。

1
int n, reverse=0, rem; 
printf("Enter an integer: "); 
scanf("%d", &n); //read in a number 
while(n!=0) //while that number has digits to process 
{ 
rem=n%10; //find out what's in the 1s place 
reverse=(reverse * 10) + //move our current answer up a position 
      rem;   //and then add in the last digit. 
          // if it's 0 that's the digit we want 
          //so leaving it as is will be fine. 
n/=10; //chop one digit off. Since integer division 
     //truncates this will drop the last digit rather 
     //than leave a fraction and always rounds toward 0 
} 
1

通過每個循環迭代作爲變量值將被如圖所示,

rem = 4 
reverse = 0 + 4 = 4 
n = 123 

rem = 3 
reverse = 40 + 3 = 43 
n = 12 

rem = 2 
reverse = 430 + 2 = 432 
n = 1 

rem = 1 
reverse = 4320 + 1 = 4321 
n = 0 

雖然在端部作爲n循環退出變得0

1

通過此步進與調試器或使用printf()小號會回答你的問題,但它是一個足夠簡單的程序,所以你可以用筆和紙(或數字筆和紙)做到這一點

printf("Enter an integer: "); 
scanf("%d", &n); // so say the number is 103 
while(n!=0)  // n=103 so we enter the loop 
{ 
rem=n%10;    // rem = 3 
reverse=reverse*10+rem; // reverse = 0*10 + 3 = 0 + 3 = 3 
n/=10;     // n = 103/10 = 10 
} 

n/=10發揮作用是因爲integer division
rem=n%10發揮作用是因爲modulus operator行線。
這一行:reverse=reverse*10+rem因爲Operator precedence工作,乘法(*)比加法(+)具有更高的優先級,所以它將首先完成。這不是C特定的,它在basic mathematics中是相同的。

所以現在n==10reverse==3,10仍然不爲0,因此繼續循環:

rem=n%10;    // rem = 0 
reverse=reverse*10+rem; // reverse = 3*10 + 0 = 30 + 0 = 30 
n/=10;     // n = 10/10 = 1 

所以現在n==1reverse==30,1仍然不爲0,因此繼續循環:

rem=n%10;    // rem = 1 
reverse=reverse*10+rem; // reverse = 30*10 + 1 = 300 + 1 = 301 
n/=10;     // n = 1/10 = 0 

所以現在循環停止,因爲n==0和反向有301這是給定輸入的反向103