2015-06-13 15 views
13

Comma khai thác có độ ưu tiên thấp nhất và associativity trái sang phải, vì vậy điều này đảm bảo trật tự như:Dấu phân cách bằng dấu phẩy trong định nghĩa loại trong C có đảm bảo thứ tự không?

i = ++j, j = i++; 

i sẽ là 2, và sau đó j sẽ 1 sau tuyên bố này nếu ij cả hai đều là 0 lúc đầu.

Tuy nhiên, không có dấu phẩy dấu tách trong định nghĩa loại trong C cũng đảm bảo thứ tự? Chẳng hạn như

int i = 1, j = ++i; 

Trả lời

20

dụ của bạn với toán tử dấu phẩy, i = ++j, j = i++;, được xác định rõ vì các nhà điều hành dấu phẩy là một điểm chuỗi.

Ưu tiên/liên kết là không đủ để đảm bảo điều này - chúng khác với thứ tự đánh giá và điểm chuỗi. Ví dụ: i * 2 + i++ * 3 không được xác định vì không có điểm chuỗi.


Dấu phẩy tách giữa declarators, ví dụ int i = 1, j = i++;, cũng là một điểm chuỗi. Đây được bao phủ bởi C11 6.7.6/3, C99 6.7.5/3:

Một đầy đủ declarator là một declarator đó không phải là một phần của declarator khác. Sự kết thúc của một người khai báo đầy đủ là một điểm chuỗi.

Vì vậy, có một điểm chuỗi sau i = 1 và mã này được xác định rõ.


Tuy nhiên, dấu phẩy giữa các đối số hàm f(i, i++) không phải là điểm chuỗi; để mã đó gây ra hành vi không xác định.


Lưu ý: Trong C11, thuật ngữ chuỗi điểm được chủ yếu là thay thế bằng quan hệ trình tự phức tạp hơn để xác định rõ ràng một mô hình luồng, nhưng điều đó không ảnh hưởng đến các cuộc thảo luận ở trên.

+0

Tôi không chắc chắn liệu C89 có đảm bảo thứ tự khai báo –

+1

Bạn nói, * Dấu phân tách dấu phẩy khác với toán tử dấu phẩy. * Nhưng phần còn lại của câu trả lời không đề cập đến toán tử dấu phẩy. Đó có phải là sự giám sát không? –

+0

@DavidHeffernan no, câu hỏi là "Tuy nhiên, không dấu phẩy ** tách ** trong định nghĩa loại trong C cũng đảm bảo trật tự?" . Câu mở đầu của tôi chỉ làm rõ rằng tôi không nói về toán tử dấu phẩy (đặc biệt là đối với những độc giả khác không nhận ra có sự khác biệt) –

-2

Giả sử C hoạt động giống như C# theo khía cạnh này, các giá trị được phân cách bằng dấu phẩy (int i = 0, j = 0;) phải theo thứ tự.

Sự khác biệt về i ++ vs ++ i là thời gian xác nhận:

int i = 0; 

bool iGTZ = i++ > 0;//false 

i = 0; iGTZ = ++i > 0;//true 

Một ít hơn những gì bạn hỏi nhưng thứ tự khai được đảm bảo. Và nếu bạn hoặc ai đó đọc điều này không biết rằng hy vọng nó sẽ giúp. :)

+1

Câu hỏi đặt ra là liệu có đánh giá từ trái sang phải xung quanh dấu phân cách bằng dấu phẩy hay không; không phải những gì '++' không –

+1

@MattMcNabb Nếu bạn đọc câu trả lời của tôi, tôi đã giải quyết câu hỏi đó và thêm thông tin bổ sung khác nhau, vào các khu vực khác của mã được cung cấp trong phạm vi thời gian. – CalebB

+6

Bạn chỉ cần nói "giả sử C hoạt động giống như C#" mà không có bất kỳ lý do nào để đưa ra giả định đó. C không hoạt động giống như C# trong các lĩnh vực khác (ví dụ: 'f (i, i ++)') –

-1

Có, và đây là lý do. Hãy suy nghĩ về những gì dấu phẩy đang nói. Tất cả những gì nó nói là "này, tôi có một điều tôi muốn làm ở phía bên tay trái của dấu phẩy này, một khi bạn làm điều đó đi đến điều bên phải và làm điều đó là tốt.Bạn cũng có thể nghĩ về nó như một cách ngắn hơn để làm điều này

int i = 1; 
int j = i++; 

tôi đã được phân bổ ở đâu đó trong bộ nhớ để tất cả những gì xảy ra với j là phải mất rằng giá trị được lưu trữ trong i, increments nó, và đặt nó bằng đến j.

Vì vậy, trong trường hợp của

int i = 1, j = ++i; 

Tất cả các bạn đang nói là tạo ra một số nguyên, thiết lập nó bằng một, bây giờ chuyển sang lệnh tiếp theo, đó sẽ là một int gọi là j, và đặt nó bằng bất cứ điều gì tôi là khi nó được tăng lên.

Vì vậy, để trả lời đầy đủ câu hỏi của bạn, có, nó đảm bảo thứ tự bởi vì trình biên dịch sẽ thực thi mọi thứ trên xuống, từ trái sang phải trừ khi được nói khác đi.

+2

Điều này không chính xác gợi ý rằng 'f (i, i + +)' có hành vi được xác định rõ. –

+0

Đó không phải là những gì anh ta hỏi. Anh ta hỏi rằng dấu phẩy có đảm bảo thứ tự trong ví dụ int i = 1, j = ++ i; Anh ta không hỏi về các đối số hàm. –

+0

Vấn đề là lập luận vẫy tay này dẫn đến kết luận sai lầm, vì vậy không thể chính xác được. –

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