a

Câu hỏi Toán tử “->” trong C ++ là gì?


Sau khi đọc Các tính năng ẩn và các góc tối của C ++ / STL trên comp.lang.c++.moderated, Tôi đã hoàn toàn ngạc nhiên khi đoạn mã sau được biên dịch và làm việc trong cả Visual Studio 2008 và G ++ 4.4.

Đây là mã:

#include <stdio.h>
int main()
{
    int x = 10;
    while (x --> 0) // x goes to 0
    {
        printf("%d ", x);
    }
}

Tôi cho rằng đây là C, vì nó cũng hoạt động trong GCC. Điều này được xác định ở đâu trong tiêu chuẩn và nó đến từ đâu?


7782


gốc


Hoặc thậm chí chỉ là khoảng cách thích hợp ... Tôi không nghĩ mình từng thấy một khoảng trống giữa biến và ++ hoặc là -- trước... - Matthew Scharley
Toán tử "go to" này có thể được hoàn nguyên (0 <- x). Và cũng có một toán tử "chạy tới" (0 <---- x). Geez, điều hài hước nhất mà tôi từng nghe về cú pháp c ++ =) +1 cho câu hỏi. - SadSido
Funnily đủ, mặc dù việc giải thích là rất sai, nó mô tả những gì các mã không chính xác. :) - Noldorin
Hãy tưởng tượng khả năng cú pháp mới: #define upto ++<, #define downto -->. Nếu bạn cảm thấy xấu xa, bạn có thể làm #define for while( và #define do ) { (và #define done ;}) và viết for x downto 0 do printf("%d\n", x) done Oh nhân loại... - Chris Lutz
Mở ra khả năng của một cách thức mã hóa hoàn toàn mới, cũng đáng hy sinh một vài cảnh báo trình biên dịch cho: bool CheckNegative (int x) {return x <0? đúng sai ); } - ttt


Các câu trả lời:


--> không phải là một nhà điều hành. Trên thực tế, hai nhà khai thác riêng biệt, -- và >.

Các mã giảm giá có điều kiện x, trong khi trở về xGiá trị ban đầu (không được giảm dần), và sau đó so sánh giá trị ban đầu với 0 sử dụng > nhà điều hành.

Để hiểu rõ hơn, tuyên bố có thể được viết như sau:

while( (x--) > 0 )

7479



Sau đó, một lần nữa, nó trông giống như một số loại nhà điều hành phạm vi trong bối cảnh đó. - Charles Salvia
Nói rằng x là post-decremented và sau đó so sánh với 0 là giống như nói x được giảm đi sau khi được so sánh với 0 - Charles Salvia
Trong Java nó cũng biên dịch :) - Steven Devijver
Tên của nó, @Jay, là kiểu lập trình xấu :-) Điều này được chứng minh bằng thực tế câu hỏi đã được hỏi ngay từ đầu. Điều này có ý nghĩa hơn nhiều khi liên kết văn bản các toán tử với điều mà chúng đang hoạt động thay vì một cái gì đó không liên quan, vì vậy while (x-- > 0) sẽ thích hợp hơn. Nó cũng làm cho nó rõ ràng hơn những gì đang xảy ra (ít nhất là trong một trình soạn thảo phông chữ cố định) có nghĩa là các dấu ngoặc đơn trong câu trả lời này sẽ không cần thiết. - paxdiablo
Vì vậy, để giải thích toán tử "->", bạn phải sử dụng toán tử "((" và toán tử "-)>"? - Ira Baxter


Hoặc cho một cái gì đó hoàn toàn khác ... x slides đến 0

while (x --\
            \
             \
              \
               > 0)
     printf("%d ", x);

Không phải như vậy toán học, nhưng ... mỗi bức tranh sơn một ngàn chữ. ...


2382



Xin lỗi, tôi không lấy cái này. Cái này hoạt động ra sao? - mafu
@mafutrct - Khi tôi nhớ nó \ trong C chỉ cần nối thêm dòng tiếp theo như thể không có ngắt dòng. \ S ở đây về cơ bản không làm gì cả. - Hogan
IIRC, K & R C cho phép khoảng trống giữa '-'s trong toán tử giảm, trong trường hợp này bạn có thể có các dấu gạch chéo ngược ở giữa nó, trông sẽ mát hơn. :) - Jules
@ArnavBorborah đó là một ý nghĩa biểu hiện cũ why waste words when a picture does a better job , được sử dụng như một trò đùa trong bối cảnh này. (thực tế có 2 từ khóa while và printf ) - unsynchronized
À vâng, toán tử trượt tối nghĩa. Làm sao tôi có thể quên được! - demonkoryu


Đó là một nhà điều hành rất phức tạp, vì vậy ngay cả ISO / IEC JTC1 (Ủy ban kỹ thuật chung 1) đặt mô tả của nó trong hai phần khác nhau của tiêu chuẩn C ++.

Nói đùa sang một bên, họ là hai nhà khai thác khác nhau: -- và > được mô tả tương ứng trong §5.2.6 / 2 và §5.9 của tiêu chuẩn C ++ 03.


2221





Nó tương đương với

while (x-- > 0)

1142



Mặc dù điều này có thể giúp nhiều người hiểu mã, nhưng một vài dòng để giải thích đúng cách sẽ hữu ích. - Dukeling
@Dukeling x-- là ký hiệu ngắn tay cho x-1 - Albert Renshaw
@AlbertRenshaw Tôi chắc chắn rằng lời bình luận cũ mà bạn đã trả lời có nghĩa là một lời giải thích về nó không phải là một nhà điều hành duy nhất, mà đúng hơn là hai nhà khai thác được đặt trong một thời trang nhầm lẫn sẽ hữu ích. - mah
@ mbomb007 Xin lỗi tôi muốn nói x- = 1 —— đã dậy trễ haha - Albert Renshaw
@AlbertRenshaw nhưng x -= 1 và x-- không giống nhau ... Nếu bạn muốn viết nó như thế thì nó sẽ phải là while (x >= 0) { x -= 1; } - Krzysztof Karski


x có thể đi đến số không nhanh hơn theo hướng ngược lại:

int x = 10;

while( 0 <---- x )
{
   printf("%d ", x);
}

8 6 4 2

Bạn có thể điều khiển tốc độ bằng mũi tên!

int x = 100;

while( 0 <-------------------- x )
{
   printf("%d ", x);
}

90 80 70 60 50 40 30 20 10

;)


861



mà hệ điều hành, loại đầu ra được tạo ra, tôi đang sử dụng một ubuntu 12.04 trong đó tôi đã có một thông báo lỗi - Bhuvanesh
Mặc dù nó nên được rõ ràng, cho tất cả mọi người mới để C + + đọc này: không làm điều đó. Chỉ cần sử dụng phân bổ tăng cường nếu bạn cần tăng / giảm nhiều hơn một. - Blimeo
Zero với "laser". trong khi (0> - - - - - - - - - - ---------- x) ... cùng một đầu ra. - Samuel Danielson
@ Bạn có chắc nó không biên dịch không? -> coliru.stacked-crooked.com/a/5aa89a65e3a86c98 - doc
@doc Nó biên dịch trong c + +, nhưng không phải trong c. - phord


nó là

#include <stdio.h>
int main(void){
     int x = 10;

     while( x-- > 0 ){ // x goes to 0

       printf("%d ", x);
     }

     return 0;
}

Chỉ là không gian làm cho mọi thứ trông vui nhộn, -- decrements và > so sánh.


498





Việc sử dụng --> có liên quan lịch sử. Giảm dần là (và vẫn còn trong một số trường hợp), nhanh hơn gia tăng trên kiến ​​trúc x86. Sử dụng --> gợi ý rằng x chuẩn bị 0và thu hút những người có nền tảng toán học.


372



Không chính xác. Giảm và tăng thêm một lượng thời gian tương tự, lợi ích của việc này là so sánh với số không là rất nhanh so với so sánh so với một biến. Điều này đúng với nhiều kiến ​​trúc, không chỉ x86. Bất cứ điều gì với một lệnh JZ (nhảy nếu không). Poking xung quanh bạn có thể tìm thấy nhiều "cho" vòng được viết ngược để tiết kiệm chu kỳ trên so sánh. Điều này đặc biệt nhanh trên x86 khi hành động giảm biến được đặt cờ zero một cách thích hợp, vì vậy bạn có thể phân nhánh mà không cần phải so sánh một cách rõ ràng biến. - burito
Vâng, giảm về 0 có nghĩa là bạn chỉ phải so sánh với 0 cho mỗi vòng lặp lặp lại, trong khi lặp về phía n có nghĩa là so sánh với n mỗi lần lặp. Trước đây có xu hướng dễ dàng hơn (và trên một số kiến ​​trúc, được tự động kiểm tra sau mỗi thao tác đăng ký dữ liệu). - Joey Adams
@ burrito Mặc dù tôi không đồng ý, các vòng lặp có điều kiện về các giá trị khác không thường được dự đoán gần như hoàn hảo. - Duncan
Tăng và giảm đều nhanh, có thể trên tất cả các nền tảng (chắc chắn trên x86). Sự khác biệt là trong việc kiểm tra điều kiện kết thúc vòng lặp. Để xem liệu bộ đếm đã đạt đến 0 hay không thì thực tế là miễn phí - khi bạn giảm giá trị, cờ 0 được đặt trong bộ xử lý và để phát hiện tình trạng kết thúc, bạn chỉ cần kiểm tra cờ đó trong khi bạn tăng hoạt động so sánh trước khi kết thúc có thể đươc tìm thấy. - lego
Tất nhiên, tất cả điều này là tranh luận những ngày này, kể từ khi trình biên dịch hiện đại có thể vectorize và đảo ngược vòng tự động. - Lambda Fairy


while( x-- > 0 )

là cách phân tích cú pháp.


324





Hoàn toàn geek, nhưng tôi sẽ sử dụng điều này:

#define as ;while

int main(int argc, char* argv[])
{
    int n = atoi(argv[1]);
    do printf("n is %d\n", n) as ( n --> 0);
    return 0;
}

292



Tôi hy vọng tôi không bao giờ gặp bất kỳ mã nguồn nào của bạn ... - mk12
@ Mk12 Đó không phải là mã nguồn ... nó là chữ tượng hình :-) - raffian
@SAFX - Nó sẽ là chữ tượng hình hoàn hảo với egyptian chân đế - mouviciel
Điều này không biên dịch. C không phải là Pascal, nơi nội thất của do ... while là một danh sách tuyên bố. Trong C nó là một khối, vì vậy nó phải được do { ... } while. - user207421
@EJP nó biên dịch. Cú pháp là do statement while ( expression ) ;. Có nói rằng, tôi hy vọng nó được hiểu tôi có nghĩa là ví dụ như một trò đùa. - Escualo


Một cuốn sách tôi đọc (Tôi không nhớ chính xác cuốn sách nào) đã nêu: Trình biên dịch cố gắng phân tích các biểu thức thành mã thông báo lớn nhất bằng cách sử dụng quy tắc bên trái.

Trong trường hợp này, biểu thức:

x-->0

Phân tích cú pháp to lớn nhất:

token 1: x
token 2: --
token 3: >
token 4: 0
conclude: x-- > 0

Quy tắc tương tự áp dụng cho biểu thức này:

a-----b

Sau khi phân tích cú pháp:

token 1: a
token 2: --
token 3: --
token 4: -
token 5: b
conclude: (a--)-- - b

Tôi hy vọng điều này sẽ giúp hiểu được biểu hiện phức tạp ^^


283



Lời giải thích thứ hai của bạn là không chính xác. Trình biên dịch sẽ thấy a-----b và suy nghĩ (a--)-- - b, không biên dịch vì a-- không trả lại một giá trị. - Tim Leaf
Ngoài ra, x và -- là hai thẻ riêng biệt. - Roland Illig
Điều này được gọi là Munch tối đa. - RJFalconer
@DoctorT: nó vượt qua lexer. chỉ có ngữ nghĩa vượt qua là có khả năng emmiting rằng lỗi. do đó, lời giải thích của ông là chính xác. - v.oddou
Miễn là bạn nghĩ --> là một toán tử (điều được ngụ ý bằng câu hỏi đã được hỏi), câu trả lời này không hữu ích chút nào - bạn sẽ nghĩ mã thông báo 2 là -->, không chỉ --. Nếu bạn biết điều đó --> không phải là một nhà điều hành, có thể bạn không gặp vấn đề khi hiểu mã trong câu hỏi, vì vậy, trừ khi bạn có một câu hỏi hoàn toàn khác, tôi không thực sự chắc chắn điều này có thể hữu ích như thế nào. - Dukeling