2010-02-23 30 views
6

Bản sao có thể xảy ra:
printf(“%d %d %d\n”,++a, a++,a) output problem
Parameter evaluation order before a function calling in Cprintf và ++ hành

#include<stdio.h> 
main() 
{ 
    int a=10; 
    printf("\n %d %d", a, a++); //11 10 
    a=10; 
    printf("\n %d %d", a++, a); //10 11 
    a=10; 
    printf("\n %d %d %d ", a, a++,++a); //12 11 12 
} 

sau khi chạy này, tôi có đầu ra được đưa ra trong ý kiến. theo như tôi biết đầu ra đầu tiên được mong đợi bởi vì việc thực thi printf đi từ phải sang trái nhưng không thể hiểu được thứ hai và thứ ba

+0

trùng lặp: http://stackoverflow.com/questions/1270370/printfd-ddnaaa-output-problem – Vladimir

+0

+1 cho câu hỏi hay .. Tôi không biết nó hoạt động theo cách đó – Earlz

+0

Tính toán đối số cho * printf * không phải là một phần của việc thực hiện * printf *. Các đối số phải được tính toán trước khi * printf * bắt đầu thực hiện. –

Trả lời

3

Không có đầu ra nào thực sự có thể đủ điều kiện là không mong muốn. Tất cả các đối số cho một hàm được đánh giá trước khi nhập vào chính hàm đó - nhưng thứ tự đánh giá của chúng liên quan đến nhau không được chỉ định, vì vậy tất cả các kết quả này được cho phép. Chính thức, cuối cùng của bạn một (có hai trường hợp tăng riêng biệt a) có hành vi không xác định, do đó, nó không phải làm bất cứ điều gì hợp lý cả.

+0

Nếu có một điểm chuỗi giữa việc đánh giá từng đối số, tại sao điểm cuối cùng cụ thể lại sai nhiều hơn các đối số khác? – UncleBens

+0

Điều cuối cùng là "sai nhiều hơn" bởi vì nó sửa đổi 'a' hai lần mà không có điểm chuỗi xen kẽ. Phần còn lại chỉ sửa đổi 'a' một lần. –

+0

@UncleBens: không có điểm chuỗi giữa việc đánh giá từng đối số. Có một cuộc gọi tuần tự sau khi các toán hạng đã được đánh giá và trước khi hàm được gọi, nhưng không có các điểm tuần tự (trong exmple) trong khi các đối số đang được đánh giá. –

3

Bạn đang gọi hành vi undefined bằng cách tham khảo cả 'a' và 'một ++' trong danh sách đối số.

Nó không được xác định thứ tự các đối số được đánh giá. Các trình biên dịch khác nhau có thể chọn các đơn đặt hàng khác nhau. Một trình biên dịch có thể chọn các đơn đặt hàng khác nhau vào các thời điểm khác nhau.

Đừng làm điều đó!

8

Không có gì "từ phải sang trái" trong đánh giá đối số chức năng. Khi các đối số hàm được đánh giá, thứ tự đánh giá không được chỉ định và không có điểm chuỗi giữa việc đánh giá các đối số riêng biệt. Điều này có nghĩa rằng hoàn toàn không có trật tự thời gian trong quá trình này. Các đối số có thể được đánh giá theo bất kỳ thứ tự nào và quá trình đánh giá của chúng có thể được kết hợp với nhau theo bất kỳ cách nào.

Tuy nhiên, mã của bạn bị các vấn đề còn tệ hơn nữa. Tất cả ba câu lệnh gọi printf tạo ra hành vi không xác định (UB) vì chúng cố gắng sửa đổi cùng một đối tượng (a) hai lần mà không có một điểm chuỗi giữa các sửa đổi (cuộc gọi thứ ba), hoặc chúng cố sửa đổi một đối tượng và đọc nó cho một mục đích độc lập (cuộc gọi đầu tiên và thứ hai). Vì vậy, còn quá sớm để đề cập đến thứ tự đánh giá. Hành vi của mã của bạn chưa được xác định.

0

++ một phương tiện tăng giá trị đầu tiên, sau đó trả về đánh giá biểu thức. (một thay đổi và biểu thức đánh giá dưới dạng +1)

a ++ có nghĩa là đánh giá (do đó, erm, a) và sau đó tăng nó. Vì vậy, một được thông qua, nhưng giá trị của a là sau đó (tức là sau đó) đã thay đổi thành + 1.

+0

Mặc dù những người khác nói rằng không có thứ tự đánh giá nào cũng đúng - tôi vừa cố giải thích các toán tử tố tố và tiền tố ... –