Tại sao tôi không nên #include <bits / stdc ++. H>?

Aug 05 2015

Tôi đã đăng một câu hỏi với mã của mình có lệnh duy nhất #includenhư sau:

#include <bits/stdc++.h>

Giáo viên của tôi đã bảo tôi làm điều này, nhưng trong phần nhận xét, tôi được thông báo rằng tôi không nên.

Tại sao?

Trả lời

349 LightnessRacesinOrbit Aug 05 2015 at 00:57

Bao gồm <bits/stdc++.h>dường như ngày càng trở nên phổ biến trên Stack Overflow, có lẽ là thứ mới được thêm vào chương trình giảng dạy quốc gia trong năm học hiện tại.

Tôi tưởng tượng những lợi thế được đưa ra một cách mơ hồ như vậy:

  • Bạn chỉ cần viết một #includedòng
  • Bạn không cần phải tra cứu mọi thứ ở tiêu đề chuẩn nào

Thật không may, đây là một hack lười biếng, đặt tên một tiêu đề nội bộ GCC trực tiếp thay vì tiêu đề tiêu chuẩn cá nhân như <string>, <iostream><vector>. Nó làm hỏng tính di động và nuôi dưỡng những thói quen khủng khiếp.

Những bất lợi bao gồm:

  • Nó có thể sẽ chỉ hoạt động trên trình biên dịch đó
  • Bạn không biết nó sẽ làm gì khi bạn sử dụng, bởi vì nội dung của nó không được đặt ra bởi một tiêu chuẩn
  • Ngay cả khi chỉ nâng cấp trình biên dịch của bạn lên phiên bản tiếp theo của chính nó cũng có thể phá vỡ chương trình của bạn
  • Mỗi tiêu đề tiêu chuẩn phải được phân tích cú pháp và biên dịch cùng với mã nguồn của bạn, điều này rất chậm và dẫn đến tệp thực thi cồng kềnh trong một số cài đặt biên dịch nhất định

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


Thêm thông tin:

Ví dụ về lý do tại sao Quora tệ:

67 UnslanderMonica Aug 06 2015 at 23:50

Tại sao? Bởi vì nó được sử dụng như thể nó được cho là một tiêu đề chuẩn C ++, nhưng không có tiêu chuẩn nào đề cập đến nó. Vì vậy, mã của bạn là không di động theo cấu trúc. Bạn sẽ không tìm thấy bất kỳ tài liệu nào cho nó trên cppreference . Vì vậy, nó cũng có thể không tồn tại. Đó là một phần của trí tưởng tượng của ai đó :)

Tôi đã phát hiện ra - với sự kinh hoàng và không tin nổi của tôi - rằng có một trang web hướng dẫn nổi tiếng nơi mọi ví dụ C ++ dường như đều bao gồm tiêu đề này . Thế giới đang điên cuồng. Đó là bằng chứng.


Cho bất cứ ai viết "hướng dẫn" như vậy

Vui lòng ngừng sử dụng tiêu đề này. Quên nó đi. Đừng tuyên truyền điều điên rồ này. Nếu bạn không muốn hiểu tại sao làm điều này là Sai , hãy nghe lời tôi. Tôi không ổn khi bị coi là một nhân vật có thẩm quyền về bất cứ điều gì, và có lẽ tôi đã hoàn toàn làm việc đó trong nửa thời gian, nhưng tôi sẽ chỉ ngoại lệ trong trường hợp này. Tôi tuyên bố rằng tôi biết những gì tôi đang nói ở đây. Hãy nghe lời tôi. Tôi khẩn cầu bạn.

Tái bút Tôi có thể hình dung ra "tiêu chuẩn giảng dạy" đáng ghê tởm nơi mà ý tưởng xấu xa này có thể đã xảy ra, và hoàn cảnh dẫn đến nó. Chỉ vì nhu cầu thực tế dường như không khiến nó được chấp nhận - thậm chí không cần nhìn lại.

PPS Không, không có nhu cầu thực tế về nó. Không có nhiều tiêu đề chuẩn C ++ và chúng được ghi lại đầy đủ. Nếu bạn dạy, bạn đang làm cho học sinh của mình trở thành kẻ phá bĩnh bằng cách thêm vào những "phép thuật" như vậy. Tạo ra những lập trình viên có tư duy kỳ diệu là điều cuối cùng chúng tôi muốn. Nếu bạn cần cung cấp cho sinh viên một tập hợp con của C ++ để làm cho cuộc sống của họ dễ dàng hơn, chỉ cần tạo một tài liệu phát tay với danh sách ngắn các tiêu đề áp dụng cho khóa học bạn giảng dạy và với tài liệu ngắn gọn cho các cấu trúc thư viện mà bạn mong đợi sinh viên sử dụng.

45 RedGreenCode Apr 23 2019 at 08:09

Có một trang web Stack Exchange có tên là Lập trình Câu đố & Code Golf . Các câu đố lập trình trên trang web đó phù hợp với định nghĩa câu đố này :

một món đồ chơi, vấn đề hoặc sự liên quan khác được thiết kế để giải trí bằng cách trình bày những khó khăn cần giải quyết bằng sự khéo léo hoặc nỗ lực kiên nhẫn.

Chúng được thiết kế để giải trí chứ không phải theo cách mà một lập trình viên đang làm việc có thể thích thú với một vấn đề trong thế giới thực gặp phải trong công việc hàng ngày của họ.

Code Golf là "một loại cuộc thi lập trình máy tính giải trí trong đó những người tham gia cố gắng đạt được mã nguồn ngắn nhất có thể thực hiện một thuật toán nhất định." Trong các câu trả lời trên trang web PP&CG, bạn sẽ thấy mọi người chỉ định số byte trong câu trả lời của họ. Khi họ tìm ra cách để loại bỏ một vài byte, họ sẽ gạch ra số ban đầu và ghi lại số mới.

Như bạn có thể mong đợi, chơi gôn mã thưởng cho việc lạm dụng ngôn ngữ lập trình quá mức. Tên biến một chữ cái. Không có khoảng trắng. Sử dụng sáng tạo các chức năng của thư viện. Các tính năng không có giấy tờ. Thực hành lập trình phi tiêu chuẩn. Hack kinh khủng.

Nếu một lập trình viên gửi yêu cầu kéo tại nơi làm việc có chứa mã kiểu chơi gôn, nó sẽ bị từ chối. Đồng nghiệp của họ sẽ cười nhạo họ. Người quản lý của họ sẽ ghé qua bàn của họ để trò chuyện. Mặc dù vậy, các lập trình viên tự giải trí bằng cách gửi câu trả lời cho PP&CG.

Điều này có liên quan gì stdc++.h? Như những người khác đã chỉ ra, sử dụng nó là lười biếng. Nó không di động, vì vậy bạn không biết liệu nó sẽ hoạt động trên trình biên dịch của bạn hay phiên bản tiếp theo của trình biên dịch của bạn. Nó nuôi dưỡng những thói quen xấu. Nó không chuẩn, vì vậy hành vi của chương trình của bạn có thể khác với những gì bạn mong đợi. Nó có thể làm tăng thời gian biên dịch và kích thước thực thi.

Đây đều là những phản đối xác đáng và đúng đắn. Vậy tại sao mọi người lại sử dụng sự quái dị này?

Nó chỉ ra rằng một số người thích lập trình câu đố mà không có mã golf . Họ gặp nhau và cạnh tranh tại các sự kiện như ACM-ICPC, Google Code Jam và Facebook Hacker Cup hoặc trên các trang web như Topcoder và Codeforces. Xếp hạng của họ dựa trên tính đúng đắn của chương trình, tốc độ thực thi và tốc độ họ gửi giải pháp. Để tối đa hóa tốc độ thực thi, nhiều người tham gia sử dụng C ++. Để tối đa hóa tốc độ mã hóa, một số người trong số họ sử dụng stdc++.h.

Đây có phải là một ý tưởng tốt? Hãy kiểm tra danh sách các nhược điểm. Tính di động? Không thành vấn đề vì các sự kiện mã hóa này sử dụng một phiên bản trình biên dịch cụ thể mà các thí sinh biết trước. Tuân thủ tiêu chuẩn? Không phù hợp với khối mã có thời gian sử dụng hữu ích dưới một giờ. Thời gian biên dịch và kích thước thực thi? Đây không phải là một phần của phiếu chấm điểm của cuộc thi.

Vì vậy, chúng ta bị bỏ lại với những thói quen xấu. Đây là một phản đối hợp lệ. Bằng cách sử dụng tệp tiêu đề này, người dự thi sẽ tránh được cơ hội tìm hiểu tệp tiêu đề chuẩn nào xác định chức năng họ đang sử dụng trong chương trình của họ. Khi họ đang viết mã trong thế giới thực (và không sử dụng stdc++.h), họ sẽ phải dành thời gian tìm kiếm thông tin này, có nghĩa là họ sẽ kém năng suất hơn. Đó là mặt trái của việc luyện tập với stdc++.h.

Điều này đặt ra câu hỏi tại sao lại đáng tham gia vào lập trình cạnh tranh nếu nó khuyến khích những thói quen xấu như sử dụng stdc++.hvà vi phạm các tiêu chuẩn mã hóa khác. Một câu trả lời là mọi người làm điều đó vì lý do họ đăng các chương trình lên PP&CG: một số lập trình viên cảm thấy thú vị khi sử dụng các kỹ năng viết mã của họ trong bối cảnh giống như trò chơi.

Vì vậy, câu hỏi về việc có nên sử dụng stdc++.hhay không phụ thuộc vào việc liệu tốc độ viết mã có lợi trong một cuộc thi lập trình có lớn hơn những thói quen xấu mà một người có thể phát triển khi sử dụng nó hay không.

Câu hỏi này hỏi: "Tại sao tôi không nên #include <bits/stdc++.h>?" Tôi nhận thấy rằng nó được hỏi và trả lời để đưa ra một quan điểm, và câu trả lời được chấp nhận nhằm mục đích là một câu trả lời đúng cho câu hỏi này. Nhưng câu hỏi không phải là "Tại sao tôi không nên # bao gồm <bits/stdc++.h>trong mã sản xuất?" Do đó, tôi nghĩ là hợp lý khi xem xét các tình huống khác mà câu trả lời có thể khác.

12 Bulletmagnet Nov 03 2019 at 18:39

Từ N4606, Bản thảo làm việc, Tiêu chuẩn cho ngôn ngữ lập trình C ++:

17.6.1.2 Tiêu đề [headers]

  1. Mỗi phần tử của thư viện chuẩn C ++ được khai báo hoặc xác định (nếu thích hợp) trong một tiêu đề.

  2. Thư viện chuẩn C ++ cung cấp 61 tiêu đề thư viện C ++, như thể hiện trong Bảng 14.

Bảng 14 - Tiêu đề thư viện C ++

<algorithm> <future> <numeric> <strstream>
<any> <initializer_list> <optional> <system_error>
<array> <iomanip> <ostream> <thread>
<atomic> <ios> <queue> <tuple>
<bitset> <iosfwd> <random> <type_traits>
<chrono> <iostream> <ratio> <typeindex>
<codecvt> <istream> <regex> <typeinfo>
<complex> <iterator> <scoped_allocator> <unordered_map>
<condition_variable> <limits> <set> <unordered_set>
<deque> <list> <shared_mutex> <utility>
<exception> <locale> <sstream> <valarray>
<execution> <map> <stack> <variant>
<filesystem> <memory> <stdexcept> <vector>
<forward_list> <memory_resorce> <streambuf>
<fstream> <mutex> <string>
<functional> <new> <string_view>

Không có <bits / stdc ++. H> ở đó. Điều này không có gì đáng ngạc nhiên, vì các tiêu đề <bits / ...> là chi tiết triển khai và thường mang một cảnh báo:

*  This is an internal header file, included by other library headers.
*  Do not attempt to use it directly. 

<bits / stdc ++. h> cũng mang một cảnh báo:

*  This is an implementation file for a precompiled header.
2 YunfeiChen Jul 08 2020 at 07:20

Lý do chúng tôi không sử dụng:

#include <bits/stdc++.h>

là vì hiệu quả. Hãy để tôi làm một phép tương tự: Đối với những người bạn biết Java: Nếu bạn hỏi người hướng dẫn của mình rằng điều sau có phải là một ý kiến ​​hay không, trừ khi họ là một người hướng dẫn tồi, họ sẽ nói không:

import java.*.*

Điều #include ... về cơ bản cũng hoạt động tương tự ... Đó không phải là lý do duy nhất để không sử dụng nó, nhưng nó là một trong những lý do chính để không sử dụng nó. Đối với một sự tương tự trong cuộc sống thực: Hãy tưởng tượng bạn có một thư viện và bạn muốn mượn một vài cuốn sách từ thư viện, liệu bạn có di dời toàn bộ thư viện cạnh nhà của bạn không ?? Nó sẽ tốn kém và không hiệu quả. Nếu bạn chỉ cần 5 cuốn sách, thì chỉ lấy ra 5 cuốn ... Không phải cả thư viện .....

#include <bits/stdc++.h>

Có vẻ phù hợp với giao diện chương trình, tôi chỉ cần gõ một câu lệnh include và nó hoạt động, điều tương tự với việc di chuyển toàn bộ thư viện, hãy xem tôi chỉ cần di chuyển toàn bộ thư viện thay vì 5 cuốn sách, từng cuốn sách. Có vẻ thuyết phục bạn đó là, đối với người thực sự phải di chuyển ?? Không quá nhiều, và đoán xem trong C ++ người thực hiện di chuyển sẽ là máy tính của bạn ... Máy tính sẽ không thích di chuyển toàn bộ thư viện cho mọi tệp nguồn bạn viết:) .....