2012-07-24 31 views
7

Sau đây là mã để giảm số cho sẵn thành một chữ số bằng cách thêm các chữ số của số đệ quy.Tại sao tôi nhận được đầu ra chính xác mặc dù mã không chính xác về mặt logic

Ví dụ: nếu đầu vào là 845, đầu ra là 8. 8+4+5 = 17 -> 1+7 = 8 (đầu ra)

#include <stdio.h> 
#define TRUE 1 

int reduceToSingle(int numb); 

int main() 
{ 
    int numb; 
    scanf("%d",&numb); 
    printf("Original = %d Single digit = %d\n", numb, reduceToSingle(numb)); 

    return TRUE; 
} 

int reduceToSingle(int numb) 
{ 
    int sum = 0, digit = 0; 
    for (digit = numb % 10; numb != 0; numb = numb/10) 
    { 
     digit = numb % 10; 
     sum += digit; 
    } 

    if (sum > 9) 
     reduceToSingle(sum); 
    else 
     return sum; 
} 

Trong đoạn mã trên trong khối if (sum > 9) Tôi đã không trả lại giá trị hàm. Tôi chỉ gọi hàm thay vào đó. Về mặt logic, hàm này sẽ cung cấp một giá trị không chính xác. Nhưng khi tôi chạy chương trình trên trong hệ thống của tôi, tôi nhận được tổng số chữ số chính xác trong đầu ra. Tôi không thể hiểu được logic đằng sau hành vi này.

+0

Nếu bạn duyệt qua mã bằng trình gỡ rối, bạn sẽ thấy những gì đang xảy ra. –

+0

Không có logic đằng sau nó. Một chương trình có hành vi không xác định có thể có kết quả * any *, bao gồm cả kết quả bạn mong đợi. –

+0

Trong câu hỏi khác, chỉ 1 trong số 5 câu trả lời là "đúng" [Đầu ra không đúng từ hàm đệ quy để tính tổng các chữ số của một số] (http://stackoverflow.com/questions/7045189/incorrect-output-from- recursive-function-to-compute-sum-of-chữ số-of-a-number) –

Trả lời

7

Đó chỉ là hành vi không xác định và tôi chắc chắn bạn đã nhận được cảnh báo. Nó xảy ra để hoạt động - tinh chỉnh cài đặt trình biên dịch hoặc thay đổi trình biên dịch hoàn toàn và nó sẽ không còn nữa.

Trong trường hợp này, tôi nghi ngờ eax không bị ghi đè để bạn nhận được giá trị kỳ vọng, tức là giá trị cuối cùng return được chỉnh sửa bởi bất kỳ cuộc gọi nào. Vì vậy, khi bạn gọi reduceToSingle, nó cuối cùng sẽ đạt đến return (khi sum <= 9). Từ đó, giá trị của eax sẽ giảm xuống cho người gọi ban đầu.

+0

có, khi tôi biên dịch nó với tùy chọn -Wall kích hoạt tôi đã được ném cảnh báo cảnh báo sau đây: kiểm soát đạt kết thúc của chức năng không void [- Wreturn-type] Ngoài ra bạn có thể vui lòng cho tôi biết làm thế nào để tinh chỉnh trình biên dịch inorder để thoát khỏi hành vi không xác định như vậy? – svKris

+0

@svKris Không, bạn không thể làm điều đó. Tuy nhiên, bạn không thể viết nó ngay từ đầu. – cnicutar

+0

bạn có thể thay đổi cảnh báo đó thành lỗi trên gcc 4.4+ –

1

Đây là những gì tôi đã nhận

815 
Original = 815 Single digit = 2009291924 

trong reduceToSingle mã của bạn (tê) không trả lại bất kỳ giá trị trong code để nó là một cái gì đó giống như

printf("%d %d",12); 

do đó, một giá trị rác được in ra cho định dạng thông số khác

+1

đối với tôi đó là đưa ra 5 (giá trị chính xác) –

Các vấn đề liên quan