Tôi muốn tăng hai biến trong for
điều kiện -loop thay vì một.
Vì vậy, một cái gì đó như:
for (int i = 0; i != 5; ++i and ++j)
do_something(i, j);
Cú pháp cho điều này là gì?
Tôi muốn tăng hai biến trong for
điều kiện -loop thay vì một.
Vì vậy, một cái gì đó như:
for (int i = 0; i != 5; ++i and ++j)
do_something(i, j);
Cú pháp cho điều này là gì?
Câu trả lời:
Một thành ngữ phổ biến là sử dụng toán tử dấu phẩy để đánh giá cả hai toán hạng và trả về toán hạng thứ hai. Như vậy:
for(int i = 0; i != 5; ++i,++j)
do_something(i,j);
Bây giờ sau khi viết điều đó, một người bình luận cho rằng nó thực sự là một số đường cú pháp đặc biệt trong câu lệnh for, và hoàn toàn không phải là một toán tử dấu phẩy. Tôi đã kiểm tra điều đó trong GCC như sau:
int i=0;
int a=5;
int x=0;
for(i; i<5; x=i++,a++){
printf("i=%d a=%d x=%d\n",i,a,x);
}
Tôi đã mong đợi x nhận giá trị ban đầu của a, vì vậy nó đáng lẽ phải hiển thị 5,6,7 .. cho x. Những gì tôi nhận được là cái này
i=0 a=5 x=0
i=1 a=6 x=0
i=2 a=7 x=1
i=3 a=8 x=2
i=4 a=9 x=3
Tuy nhiên, nếu tôi đặt dấu ngoặc nhọn cho biểu thức để buộc trình phân tích cú pháp thực sự nhìn thấy một toán tử dấu phẩy, tôi nhận được điều này
int main(){
int i=0;
int a=5;
int x=0;
for(i=0; i<5; x=(i++,a++)){
printf("i=%d a=%d x=%d\n",i,a,x);
}
}
i=0 a=5 x=0
i=1 a=6 x=5
i=2 a=7 x=6
i=3 a=8 x=7
i=4 a=9 x=8
Ban đầu, tôi nghĩ rằng điều này cho thấy nó không hoạt động như một toán tử dấu phẩy, nhưng hóa ra, đây chỉ đơn giản là một vấn đề ưu tiên - toán tử dấu phẩy có mức độ ưu tiên thấp nhất có thể , vì vậy biểu thức x = i ++, a ++ có hiệu quả được phân tích cú pháp là (x = i ++), a ++
Cảm ơn tất cả các ý kiến, đó là một trải nghiệm học tập thú vị và tôi đã sử dụng C trong nhiều năm!
Thử cái này
for(int i = 0; i != 5; ++i, ++j)
do_something(i,j);
for( ; ; ((++i), (++j)) )
for(int i = 0; i != 5; (++i)) {
Dấu ngoặc đơn bổ sung đánh lừa trình biên dịch nghĩ rằng nó không phải là một hoạt động "gia tăng" nữa.
Cố gắng đừng làm điều đó!
Từ http://www.research.att.com/~bs/JSF-AV-rules.pdf :
Quy tắc AV 199
Biểu thức gia tăng trong vòng lặp for sẽ không thực hiện hành động nào khác ngoài việc thay đổi một tham số vòng lặp đơn thành giá trị tiếp theo cho vòng lặp.Cơ sở lý luận: Tính dễ đọc.
Tôi đến đây để tự nhắc mình cách viết mã chỉ mục thứ hai vào mệnh đề gia tăng của vòng lặp FOR, điều mà tôi biết có thể được thực hiện chủ yếu bằng cách quan sát nó trong một mẫu mà tôi đã kết hợp vào một dự án khác, được viết bằng C ++.
Hôm nay, tôi đang làm việc trong C #, nhưng tôi cảm thấy chắc chắn rằng nó sẽ tuân theo các quy tắc tương tự về mặt này, vì câu lệnh FOR là một trong những cấu trúc điều khiển lâu đời nhất trong tất cả các lập trình. Rất may, gần đây tôi đã dành vài ngày để ghi lại chính xác hành vi của vòng lặp FOR trong một trong những chương trình C cũ của tôi và tôi nhanh chóng nhận ra rằng những nghiên cứu đó đã tổ chức các bài học áp dụng cho vấn đề C # ngày nay, đặc biệt là hành vi của biến chỉ mục thứ hai .
Đối với những người không cẩn thận, sau đây là tóm tắt những quan sát của tôi. Tất cả những gì tôi thấy đang xảy ra ngày hôm nay, bằng cách quan sát cẩn thận các biến trong cửa sổ Locals, đã xác nhận kỳ vọng của tôi rằng câu lệnh C # FOR hoạt động chính xác giống như câu lệnh C hoặc C ++ FOR.
Nếu một trong các biến chỉ mục của bạn vẫn còn trong phạm vi khi vòng lặp kết thúc, giá trị của chúng sẽ cao hơn một ngưỡng so với ngưỡng dừng vòng lặp, trong trường hợp là biến chỉ mục true. Tương tự như vậy, nếu, ví dụ: nếu biến thứ hai được khởi tạo bằng 0 trước khi vòng lặp được nhập, giá trị của nó ở cuối sẽ là số lần lặp, giả sử rằng đó là số tăng (++), không phải là giảm và không có gì trong phần thân của vòng lặp thay đổi giá trị của nó.
Tôi đồng ý với squelart. Việc tăng hai biến số rất dễ xảy ra lỗi, đặc biệt nếu bạn chỉ kiểm tra một trong số chúng.
Đây là cách dễ đọc để làm điều này:
int j = 0;
for(int i = 0; i < 5; ++i) {
do_something(i, j);
++j;
}
For
vòng lặp có nghĩa là cho các trường hợp vòng lặp của bạn chạy trên một biến tăng / giảm. Đối với bất kỳ biến nào khác, hãy thay đổi nó trong vòng lặp.
Nếu bạn cần j
được gắn với i
, tại sao không để nguyên biến ban đầu và thêm vào i
?
for(int i = 0; i < 5; ++i) {
do_something(i,a+i);
}
Nếu logic của bạn phức tạp hơn (ví dụ: bạn cần thực sự giám sát nhiều hơn một biến), tôi sẽ sử dụng một while
vòng lặp.
int main(){
int i=0;
int a=0;
for(i;i<5;i++,a++){
printf("%d %d\n",a,i);
}
}
i
và a
cục bộ với vòng lặp là gì?
Sử dụng Toán học. Nếu hai phép toán phụ thuộc toán học vào sự lặp lại của vòng lặp, tại sao không làm phép toán?
int i, j;//That have some meaningful values in them?
for( int counter = 0; counter < count_max; ++counter )
do_something (counter+i, counter+j);
Hoặc, cụ thể hơn là tham khảo ví dụ của OP:
for(int i = 0; i != 5; ++i)
do_something(i, j+i);
Đặc biệt nếu bạn đang chuyển vào một hàm theo giá trị, thì bạn sẽ nhận được thứ gì đó thực hiện chính xác những gì bạn muốn.