Từ khóa C auto được sử dụng ở đâu?


104

Trong những ngày học đại học, tôi đã đọc về autotừ khóa và trong thời gian đó, tôi thực sự quên mất nó là gì. Nó được định nghĩa là:

định nghĩa một biến cục bộ là có thời gian tồn tại cục bộ

Tôi không bao giờ thấy nó đang được sử dụng ở bất cứ đâu, nó có thực sự được sử dụng không và nếu có thì nó được sử dụng ở đâu và trong những trường hợp nào?

Câu trả lời:


90

autolà một bổ ngữ như static. Nó định nghĩa lớp lưu trữ của một biến. Tuy nhiên, vì giá trị mặc định cho các biến cục bộ là auto, bạn thường không cần chỉ định nó theo cách thủ công.

Trang này liệt kê các lớp lưu trữ khác nhau trong C.


13
Tôi chỉ xem lại điều này sau khi ai đó bỏ phiếu cho câu trả lời của tôi. Bạn nói rằng bạn "thường không cần chỉ định thủ công." Tôi chỉ cần hỏi: có thực sự là một trường hợp auto có thể được chỉ định nhưng sẽ không xảy ra theo mặc định không?
Jerry Coffin,

2
@JerryCoffin Không có trong C. Trong C ++ 11, nó được sử dụng lại và bạn có thể sử dụng nó để suy luận kiểu biến cục bộ một cách hiệu quả.
Mehrdad Afshari

2
Một cách sử dụng có thể sử dụng là khai báo chuyển tiếp các hàm lồng nhau trong GNU C - mặc dù đây là cách lấy cắp định nghĩa ban đầu của auto. tigcc.ticalc.org/doc/keywords.html#auto
josiah

2
Trang được liên kết đã lỗi thời. Kể từ C11, cũng có thông _Thread_localtin chi tiết: en.cppreference.com/w/c/language/storage_durationstackoverflow.com/a/14289720/6557621
MCCCS Ngày

132

Nếu bạn đọc danh sách IAQ (Các câu hỏi không thường gặp), bạn sẽ biết rằng ô tô chủ yếu hữu ích để xác định hoặc khai báo một phương tiện:

auto my_car;

Một chiếc xe thường xuyên đậu ngoài trời:

extern auto my_car;

Đối với những người không có khiếu hài hước và muốn "chỉ là sự thật, thưa bà": câu trả lời ngắn gọn là không bao giờ có bất kỳ lý do gì để sử dụng auto. Thời gian duy nhất bạn được phép sử dụng autolà với một biến đã có autolớp lưu trữ, vì vậy, bạn chỉ cần chỉ định điều gì đó sẽ xảy ra. Cố gắng sử dụng autobất kỳ biến nào chưa có autolớp lưu trữ sẽ dẫn đến việc trình biên dịch từ chối mã của bạn. Tôi cho rằng nếu bạn muốn có kỹ thuật, việc triển khai của bạn không cần phải là một trình biên dịch (nhưng đúng như vậy) và về mặt lý thuyết nó có thể tiếp tục biên dịch mã sau khi đưa ra chẩn đoán (nhưng sẽ không).

Phụ lục nhỏ của kaz :

Ngoài ra còn có:

static auto my_car;

yêu cầu chẩn đoán theo ISO C. Điều này đúng, vì nó tuyên bố rằng chiếc xe bị hỏng. Việc chẩn đoán là miễn phí, nhưng tắt đèn bảng điều khiển sẽ khiến bạn mất 80 đô la. (Hai mươi hoặc ít hơn, nếu bạn mua USB dongle của riêng mình để chẩn đoán trên bo mạch từ eBay).

Điều nói trên extern auto my_carcũng yêu cầu chẩn đoán, và vì lý do đó, nó không bao giờ được chạy qua trình biên dịch, ngoại trừ nhân viên thành phố có nhiệm vụ thực thi bãi đậu xe.

Nếu bạn thấy nhiều extern static auto ...mã trong bất kỳ cơ sở mã nào, bạn đang ở trong một vùng lân cận tồi tệ; tìm kiếm một công việc tốt hơn ngay lập tức, trước khi toàn bộ nơi này chuyển sang Rust.


@self .: ISO dường như không biết về "ISO 2011". Bạn tin rằng nó có thể tiêu chuẩn hóa điều gì?
Jerry Coffin

6
Thật tốt khi tôi không có cà phê, cola, bia đen hoặc một số chất lỏng màu sẫm khác trong miệng. Bạn sẽ nợ tôi một màn hình máy tính, @JerryCoffin, chính là trường hợp đó. CÂU TRẢ LỜI HAY NHẤT ĐẾN NAY!
David Hammen

2
@Dan: Thành thật mà nói, bạn đã mất khá nhiều thời gian để đọc 5 dòng văn bản và nhận được phần có nội dung: "câu trả lời ngắn gọn là không bao giờ có lý do gì để sử dụng tự động cả"? Nghiêm túc? Đưa ra nhận xét ngay trước nhận xét của bạn, có vẻ như ít nhất một vài người thấy đó là một đóng góp tích cực.
Jerry Coffin

@JerryCoffin Tôi đã giải thích điều đó rồi, hãy đọc lại bình luận của tôi. Nhận thức muộn là 20/20.
Dan Bechard

2
Gần đây tôi đã vượt qua một vụ tai nạn nghiêm trọng (đóng hai làn đường) cho thấy cần phảichar auto my_car;
stark

46

Các autotừ khóa là vô dụng trong ngôn ngữ C. Nó ở đó vì trước ngôn ngữ C đã tồn tại một ngôn ngữ B trong đó từ khóa đó là cần thiết để khai báo các biến cục bộ. (B được phát triển thành NB, trở thành C).

Đây là sổ tay hướng dẫn cho B .

Như bạn có thể thấy, sách hướng dẫn có rất nhiều ví dụ autođược sử dụng. Điều này là như vậy bởi vì không có inttừ khóa. Một số loại từ khóa là cần thiết để nói rằng "đây là một khai báo của một biến", và từ khóa đó cũng cho biết liệu nó là một biến cục bộ hay bên ngoài ( autoso với extrn). Nếu bạn không sử dụng cái này hoặc cái kia, bạn có lỗi cú pháp. Điều đó có nghĩa là, x, y;không phải là một tuyên bố của chính nó, nhưng auto x, y;là.

Vì các cơ sở mã được viết bằng B phải được chuyển sang NB và sang C khi ngôn ngữ này được phát triển, các phiên bản mới hơn của ngôn ngữ mang một số hành lý để cải thiện khả năng tương thích ngược giúp dịch ít công việc hơn. Trong trường hợp của auto, các lập trình viên không phải tìm kiếm mọi lần xuất hiện autovà loại bỏ nó.

Rõ ràng là từ hướng dẫn sử dụng, chữ "int ngầm" trong C (có thể viết main() { ... }mà không cần viết intphía trước) cũng xuất phát từ B. Đó là một tính năng tương thích ngược khác để hỗ trợ mã B. Các hàm không có kiểu trả về được chỉ định trong B vì không có kiểu. Mọi thứ đều là một từ, giống như trong nhiều ngôn ngữ lắp ráp.

Lưu ý cách một hàm có thể được khai báo extrn putcharvà điều duy nhất khiến nó trở thành một hàm sử dụng mã định danh : nó được sử dụng trong một biểu thức gọi hàm như thế nào putchar(x), và đó là điều yêu cầu trình biên dịch coi từ không đánh máy đó như một con trỏ hàm.


24

Trong C autolà một từ khóa chỉ ra một biến là cục bộ của một khối. Vì đó là mặc định cho các biến phạm vi khối, nó không cần thiết và rất hiếm khi được sử dụng (tôi không nghĩ rằng tôi đã từng thấy nó được sử dụng bên ngoài các ví dụ trong các văn bản thảo luận về từ khóa). Tôi muốn quan tâm nếu ai đó có thể chỉ ra một trường hợp mà việc sử dụng autolà bắt buộc để có được phân tích cú pháp hoặc hành vi chính xác.

Tuy nhiên, trong tiêu chuẩn C ++ 11, autotừ khóa đã bị 'tấn công' để hỗ trợ suy luận kiểu, trong đó kiểu của một biến có thể được lấy từ kiểu của bộ khởi tạo của nó:

auto someVariable = 1.5;   // someVariable will have type double

Suy luận kiểu đang được thêm vào chủ yếu để hỗ trợ khai báo các biến trong các mẫu hoặc trả về từ các hàm khuôn mẫu trong đó các kiểu dựa trên tham số khuôn mẫu (hoặc được trình biên dịch suy ra khi một mẫu được khởi tạo) thường có thể khá khó khăn khi khai báo theo cách thủ công.


1
"Biến là cục bộ của một khối" - điều đó hoàn toàn không đúng. Tất cả các biến được khai báo trong một khối là cục bộ của khối đó (đối với phạm vi). Chúng có thể được liên kết với các biến khác trong chương trình, nhưng phần khai báo chỉ hiển thị trong khối đó. autolà về lớp lưu trữ không liên quan gì đến khả năng hiển thị.
fuz

12

Với trình biên dịch Aztec C cũ, có thể chuyển tất cả các biến tự động thành biến tĩnh (để tăng tốc độ định địa chỉ) bằng cách sử dụng công tắc dòng lệnh.

Nhưng các biến được khai báo rõ ràng với autovẫn được giữ nguyên trong trường hợp đó. (A phải cho các hàm đệ quy nếu không sẽ không hoạt động bình thường!)


7

Các autotừ khóa tương tự như sự bao gồm của dấu chấm phẩy trong Python, nó được yêu cầu của một ngôn ngữ trước đó ( B) nhưng các nhà phát triển nhận ra đó là không cần thiết vì hầu hết mọi thứ auto.

Tôi nghi ngờ rằng nó được để lại để giúp chuyển đổi từ B sang C. Tóm lại, một mục đích sử dụng là khả năng tương thích ngôn ngữ B.

Ví dụ trong B và 80s C:

/* The following function will print a non-negative number, n, to
   the base b, where 2<=b<=10.  This routine uses the fact that
   in the ASCII character set, the digits 0 to 9 have sequential
   code values.  */

printn(n, b) {
        extrn putchar;
        auto a;

        if (a = n / b)        /* assignment, not test for equality */
                printn(a, b); /* recursive */
        putchar(n % b + '0');
}

1

Từ khóa tự động là một lớp lưu trữ (một số loại kỹ thuật quyết định thời gian tồn tại của biến và nơi lưu trữ). Nó có một hành vi mà biến được tạo bởi Trợ giúp của từ khóa đó có tuổi thọ (thời gian tồn tại) chỉ nằm trong dấu ngoặc nhọn

{
    auto int x=8;        
    printf("%d",x);  // here x is 8

    { 
        auto int x=3;
        printf("%d",x);  // here x is 3
    }              

    printf("%d",x);  // here x is 8
}          

0

autochỉ có thể được sử dụng cho các biến phạm vi khối. extern auto intlà rác rưởi vì trình biên dịch không thể xác định liệu điều này có sử dụng định nghĩa bên ngoài hay không hay có ghi đè extern bằng định nghĩa tự động hay không (auto và extern hoàn toàn khác nhau về thời lượng lưu trữ, chẳng hạn như static auto inthiển nhiên cũng là rác). Nó luôn có thể chọn giải thích nó theo một cách nhưng thay vào đó chọn coi nó như một lỗi.

Có một tính năng autocung cấp và đó là kích hoạt quy tắc 'mọi thứ đều là int' bên trong một hàm. Không giống như bên ngoài một hàm, nơi a=3được hiểu là một định nghĩa int a =3vì các phép gán không tồn tại trong phạm vi tệp, a=3là một lỗi bên trong một hàm vì rõ ràng trình biên dịch luôn hiểu nó là một phép gán cho một biến bên ngoài chứ không phải là một định nghĩa (ngay cả khi có không có extern int atờ khai chuyển tiếp trong hàm hoặc trong phạm vi tập tin), nhưng một specifier như static, const, volatilehoặc autocó ngụ ý rằng nó là một định nghĩa và trình biên dịch mất nó như là một định nghĩa, ngoại trừ autokhông có các tác dụng phụ của specifiers khác. auto a=3do đó là ngầm định auto int a = 3. Phải thừa nhận rằng,signed a = 3có cùng tác dụng và unsigned a = 3luôn là một int không dấu.

Cũng lưu ý ' autokhông ảnh hưởng đến việc một đối tượng sẽ được cấp phát cho một thanh ghi hay không (trừ khi một số trình biên dịch cụ thể chú ý đến nó, nhưng điều đó dường như không thể xảy ra)'


-1

Tôi chắc rằng bạn đã quen thuộc với các mã định nghĩa lớp lưu trữ trong C là "extern", "static", "register" và "auto". Định nghĩa của "auto" được đưa ra khá nhiều trong các câu trả lời khác nhưng đây là cách sử dụng từ khóa "auto" mà tôi không chắc chắn, nhưng tôi nghĩ nó phụ thuộc vào trình biên dịch. Bạn thấy đấy, đối với các chỉ định lớp lưu trữ, có một quy tắc. Chúng tôi không thể sử dụng nhiều mã định nghĩa lớp lưu trữ cho một biến. Đó là lý do tại sao các biến toàn cục tĩnh không thể bị loại bỏ. Do đó, họ chỉ được biết đến với tệp của họ. Khi bạn chuyển đến cài đặt trình biên dịch của mình, bạn có thể bật cờ tối ưu hóa cho tốc độ. một trong những cách tối ưu hóa trình biên dịch là nó tìm kiếm các biến không có chỉ định lớp lưu trữ và sau đó đưa ra đánh giá dựa trên tính khả dụng của bộ nhớ đệm và một số yếu tố khác để xem liệu nó có xử lý biến đó bằng cách sử dụng chỉ định thanh ghi hay không. Bây giờ, điều gì sẽ xảy ra nếu chúng ta muốn tối ưu hóa mã của mình về tốc độ trong khi biết rằng một biến cụ thể trong chương trình của chúng ta không quan trọng lắm và chúng ta không muốn trình biên dịch thậm chí coi nó như một thanh ghi. Tôi mặc dù bằng cách đặt auto, trình biên dịch sẽ không thể thêm chỉ định đăng ký vào một biến vì gõ "register auto int a;" HOẶC "đăng ký tự động int a;" làm tăng lỗi của việc sử dụng nhiều bộ chỉ định lớp lưu trữ. Tóm lại, tôi nghĩ auto có thể cấm trình biên dịch coi một biến là thanh ghi thông qua tối ưu hóa. Điều gì sẽ xảy ra nếu chúng ta muốn tối ưu hóa mã của mình cho tốc độ trong khi biết rằng một biến cụ thể trong chương trình của chúng ta không quan trọng lắm và chúng ta không muốn trình biên dịch thậm chí coi nó như một thanh ghi. Tôi mặc dù bằng cách đặt auto, trình biên dịch sẽ không thể thêm chỉ định đăng ký vào một biến vì gõ "register auto int a;" HOẶC "đăng ký tự động int a;" làm tăng lỗi của việc sử dụng nhiều bộ chỉ định lớp lưu trữ. Tóm lại, tôi nghĩ auto có thể cấm trình biên dịch coi một biến là thanh ghi thông qua tối ưu hóa. Điều gì sẽ xảy ra nếu chúng ta muốn tối ưu hóa mã của mình cho tốc độ trong khi biết rằng một biến cụ thể trong chương trình của chúng ta không quan trọng lắm và chúng ta không muốn trình biên dịch thậm chí coi nó như một thanh ghi. Tôi mặc dù bằng cách đặt auto, trình biên dịch sẽ không thể thêm chỉ định đăng ký vào một biến vì gõ "register auto int a;" HOẶC "đăng ký tự động int a;" làm tăng lỗi của việc sử dụng nhiều bộ chỉ định lớp lưu trữ. Tóm lại, tôi nghĩ auto có thể cấm trình biên dịch coi một biến là thanh ghi thông qua tối ưu hóa. làm tăng lỗi của việc sử dụng nhiều bộ chỉ định lớp lưu trữ. Tóm lại, tôi nghĩ auto có thể cấm trình biên dịch coi một biến là thanh ghi thông qua tối ưu hóa. làm tăng lỗi của việc sử dụng nhiều bộ chỉ định lớp lưu trữ. Tóm lại, tôi nghĩ auto có thể cấm trình biên dịch coi một biến là thanh ghi thông qua tối ưu hóa.

Lý thuyết này không hoạt động đối với trình biên dịch GCC tuy nhiên tôi chưa thử các trình biên dịch khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.