Điều gì làm cho C trở nên phổ biến trong thời đại OOP? [đóng cửa]


91

Tôi viết mã rất nhiều trong cả C và C ++, nhưng không hy vọng C là ngôn ngữ phổ biến thứ hai, chỉ sau Java một chút.

Chỉ số cộng đồng lập trình TIOBE

Tôi tò mò tại sao, trong thời đại OOP này, C vẫn còn phổ biến như vậy? Lưu ý rằng 4 trong số 5 ngôn ngữ lập trình phổ biến hàng đầu là "ngôn ngữ hiện đại", có khả năng hướng đối tượng.

Bây giờ, tôi đồng ý rằng bạn có thể sử dụng OOP trong C ở một mức độ nào đó, nhưng nó khá đau đớn và không phù hợp (ít nhất là so với C ++ tôi đoán). Vậy, điều gì làm cho C trở nên phổ biến? Là nó hiệu quả; cấp thấp; đại đa số các thư viện đã tồn tại hay cái gì khác?


18
trò chơi điện tử, hệ thống nhúng, lập trình phần cứng (phần sụn), hệ điều hành, v.v.

25
Lưu ý rằng bạn chỉ nhận được những gì bạn đo lường - trong trường hợp TIOBE, số lần truy cập cho +"<language> programming"các công cụ tìm kiếm phổ biến. Một bài đăng trên blog "Tại sao không ai lập trình C nữa" được tính cho C trong chỉ mục này. Heck, thậm chí câu hỏi này có thể làm ngay khi google chọn nó.

40
Tuổi của OOP? đó là một tuyên bố khá táo bạo.
Mahmoud Hossam

57
Bạn có ảo tưởng rằng OOP là một viên đạn bạc, bạn sẽ mất nó nhanh chóng, không có gì đặc biệt hay "tốt" về OOP, đó chỉ là một trong nhiều chiến lược tổ chức mã.
Raynos

23
@DeadMG: Nồi, gặp ấm đun nước. Dữ liệu của TIOBE có thể không đáng tin cậy, nhưng khẳng định hói của bạn rằng "nó không phổ biến" không có nguồn hoặc trích dẫn nào. Nếu bạn sẽ thách thức giả định đằng sau câu hỏi, ít nhất hãy cung cấp một số bằng chứng để sao lưu nó.
Daniel Pryden

Câu trả lời:


142

Một vài yếu tố góp phần:

  • C có mặt khắp nơi. Dù nền tảng là gì, C có thể có sẵn.
  • C là hàng xách tay. Viết một đoạn C sạch và nó biên dịch với các sửa đổi tối thiểu trên các nền tảng khác - đôi khi nó thậm chí còn hoạt động vượt trội.
  • C đã được khoảng một thời gian. Quay trở lại những ngày mà UNIX chinh phục thế giới, C (ngôn ngữ lập trình UNIX được lựa chọn) đã chia sẻ sự thống trị thế giới của nó và trở thành ngôn ngữ chung của thế giới lập trình. Bất kỳ lập trình viên nghiêm trọng có thể được dự kiến sẽ ít nhất làm cho một số ý nghĩa của một đoạn của C; điều tương tự không thể nói về hầu hết các ngôn ngữ khác.
  • C vẫn là ngôn ngữ mặc định cho các hệ thống có hương vị UNIX và UNIX. Nếu bạn muốn một thư viện thành công ở vùng đất nguồn mở, bạn cần những lý do khá chính đáng để không sử dụng C. Điều này một phần là do truyền thống, nhưng hơn nữa vì C là ngôn ngữ duy nhất bạn có thể cho rằng được hỗ trợ một cách an toàn trên mọi thứ giống như UNIX hệ thống. Viết thư viện của bạn bằng C có nghĩa là bạn có thể giảm thiểu phụ thuộc.
  • C là đơn giản. Nó thiếu tính biểu cảm của OOP tinh vi hoặc các ngôn ngữ chức năng, nhưng sự đơn giản của nó có nghĩa là nó có thể được chọn một cách nhanh chóng.
  • C là đa năng. Nó phù hợp với các hệ thống nhúng, trình điều khiển thiết bị, nhân hệ điều hành, tiện ích dòng lệnh nhỏ, ứng dụng máy tính để bàn lớn, DBMS, thực hiện các ngôn ngữ lập trình khác và nhiều thứ khác bạn có thể nghĩ tới.
  • C là nhanh. Hầu hết các cài đặt C biên dịch trực tiếp vào mã máy và lập trình viên có toàn quyền đối với những gì xảy ra ở cấp độ máy. Không có trình thông dịch, không có trình biên dịch JIT, không có VM hoặc thời gian chạy - chỉ có mã, trình biên dịch, trình liên kết và kim loại trần.
  • C là 'miễn phí' (theo cả nghĩa bia và ý nghĩa lời nói). Không có công ty duy nhất sở hữu và kiểm soát tiêu chuẩn, có một số triển khai để lựa chọn, không có vấn đề về bản quyền, bằng sáng chế hoặc nhãn hiệu để sử dụng C và một số triển khai tốt nhất là nguồn mở.
  • C có rất nhiều động lực đi. Ngôn ngữ này đã trở nên phổ biến trong nhiều thập kỷ, vì vậy có một lượng lớn ứng dụng, thư viện, công cụ và hầu hết tất cả các cộng đồng để hỗ trợ ngôn ngữ này.
  • C là người trưởng thành. Tiêu chuẩn cuối cùng đưa ra những thay đổi lớn là C99 và nó hầu như tương thích ngược với các tiêu chuẩn trước đó. Không giống như các ngôn ngữ mới hơn (giả sử, Python), bạn không phải lo lắng về việc phá vỡ các thay đổi bất cứ lúc nào sớm.
  • C tương thích. Hầu hết các ngôn ngữ đều có ràng buộc để nói chuyện với C. Điều này có nghĩa là người ta có thể phát triển thư viện bằng C bằng cách sử dụng các quy ước gọi tiêu chuẩn và cảm thấy tự tin rằng hầu hết mọi ngôn ngữ khác có thể liên kết với thư viện đó. Để đặt tên cho một vài ngôn ngữ phổ biến được sử dụng rộng rãi: C #, Java, Perl, Python, PHP đều có thể liên kết với các thư viện C mà không gặp nhiều rắc rối.
  • C là mạnh mẽ: nếu ngôn ngữ không thể làm một cái gì đó, tất cả các trình biên dịch phổ biến cho phép nhúng mã trình biên dịch mã có thể làm bất cứ điều gì mà phần cứng có thể làm. Kết hợp quá mức với điểm trên về khả năng tương thích, điều này có nghĩa là C có thể hoạt động như một liên lạc giữa các ngôn ngữ cấp cao hơn và "kim loại trần" của lắp ráp.

9
Tôi nghĩ rằng không phải tất cả các lập luận của bạn là chính xác. 1) C có mặt khắp nơi. C ++ là ubiquitos như C, vì có trình biên dịch C ++ đến C. 2) C là xách tay. Tương tự với C ++. 3). C đã được khoảng một thời gian. Tương tự với C ++. 4). C là đa năng. Tương tự với C ++. 5) C nhanh. Tương tự với C ++. 6). C là 'miễn phí'. Tương tự với C ++. 7). C có rất nhiều động lực đi. Tương tự với C ++ một lần nữa. 8) C trưởng thành. Tương tự với C ++. Vì vậy, bạn thực sự không trả lời câu hỏi.
Konstantin Solomatov

19
C11 là tiêu chuẩn mới nhất, không phải C99. Không phải là nó thực sự quan trọng vì mọi người đều sử dụng '89.
Pubby

53
@KonstantinSolomatov: Nếu bạn đang viết một thư viện sẽ bị người khác sử dụng, xin hãy ủng hộ thế giới và viết nó bằng C thay vì C ++. Nếu bạn không thể làm điều đó, ít nhất hãy viết API C. Mọi thứ trong vũ trụ có thể liên kết với mã C theo cách này hay cách khác, thường là với nỗ lực tối thiểu. Ngược lại, bạn sẽ thường xuyên gặp sự cố ABI lớn khi cố gắng gọi mã C ++ từ C ++ khác , chứ đừng nói đến các ngôn ngữ khác.
Daniel Pryden

37
@KonstantinSolomatov - thực tế là cần có một trình biên dịch C ++ sang C chứng minh rằng C là một thứ phổ biến.
gièm pha

11
@KonstantinSolomatov: Hãy ngừng nghĩ rằng C là C ++. C không có đóng cửa. Một số phần mở rộng của C thực hiện (chẳng hạn như phần mở rộng được thực hiện bởi họ trình biên dịch gcc) nhưng bản thân C thì không (nghĩa là nó không có trong thông số K & R gốc hoặc bất kỳ tiêu chuẩn C đã hoàn thành nào).
Nghiên cứu sinh

88

Tôi luôn có xu hướng đổ lỗi cho sự phổ biến của C về sự cần thiết của một ngôn ngữ lắp ráp phổ quát. Sự kết hợp của tính đặc hiệu ở cấp độ máy, tiêu chuẩn hóa và tính di động cực cao cho phép C hoạt động như ngôn ngữ lắp ráp phổ biến trên thực tế và vì lý do đó tôi nghi ngờ vai trò của nó sẽ tiếp tục vô tận.

Tôi nên đề cập rằng tôi luôn có một chút ngạc nhiên khi OOP được trình bày trong các khóa học lập trình như một "mô hình cuối cùng", đó là điểm cuối duy nhất có thể để lập trình tốt. Giống như nhiều khía cạnh khác của lập trình, giá trị của OOP là sự thỏa hiệp giữa nhiều yếu tố cạnh tranh, bao gồm cách bộ não của con người tổ chức thông tin, cách các nhóm xã hội hỗ trợ phần mềm trong thời gian dài và trong trường hợp lập trình hướng đối tượng, một số khía cạnh khá sâu sắc về cách thức vũ trụ hoạt động.

Và điểm cuối cùng đó đáng để rèn một chút. Đọc thêm nếu bạn quan tâm đến một khám phá ở cấp độ vật lý về lý do tại sao các kiểu lập trình nhất định tồn tại, cách chúng hoạt động cùng nhau và nơi thế giới có thể hướng tới trong tương lai khi chúng ta mở rộng hơn nữa về các khái niệm đó ...

Một đối tượng trong vật lý là bất cứ điều gì duy trì sự gắn kết dễ nhận biết theo thời gian. Điều đó đến lượt nó cho phép các sinh vật đơn giản như chúng ta thoát khỏi việc đại diện cho vật thể chỉ bằng một số bit nhỏ, mà không gây nguy hiểm cho sự sống sót của chúng ta quá nặng. Nhưng về mặt vật lý nói chung, số lượng những thứ bạn phải có chính xác để làm cho loại đơn giản hóa đó trở nên dễ dàng và phổ biến là rất lớn. Là con người chúng ta không nghĩ về tất cả những điều đó bởi vì thật lòng mà nói, chúng ta sẽ không ở đây nếu điều đó không đúng.

Nghe có vẻ quá trừu tượng? Nó thực sự không. Ví dụ, hãy tưởng tượng bạn đang cố gắng điều hướng con đường đến nhà của bạn mình nếu thay vì những chiếc xe bạn gặp phải trường plasma dao động nhanh và sự ngưng tụ nhất thời của vật chất chuyển động với một phạm vi vận tốc khổng lồ. Một kịch bản như vậy có thể cắt giảm sâu vào các cơ hội xã hội hóa, phải không? Chúng ta cần đồ vật, chúng ta các đối tượng và sự tồn tại của các đối tượng cung cấp cho chúng ta một mức độ đơn giản hóa cực kỳ quan trọng và cực kỳ quan trọng của môi trường xung quanh chúng ta.

Vì vậy, hãy kéo tất cả những thứ đó trở lại với phần mềm. Các đối tượng trong thế giới thực nói gì về các đối tượng về mặt lập trình?

Chà, đối với một điều, điều đó có nghĩa là những gì định nghĩa một đối tượng "tốt" trong phần mềm phải thực sự là liệu loại dữ liệu bạn đang xử lý có hỗ trợ ý tưởng về sự bền bỉ dễ nhận biết theo thời gian hay không .

Với định nghĩa, các dạng OOP dễ nhất rất dễ nhận ra. Họ là những người đối phó một chút bằng cách chỉ sử dụng dữ liệu đã được "đính kèm" hoặc được xác định bởi một số đối tượng thực tế, thực sự như một người, nhà hoặc xe hơi. Ngay cả ngày nay, đây vẫn là quá thường xuyên định nghĩa duy nhất về các đối tượng mà mọi người có được trong các khóa học phần mềm. Điều đó thật tệ, bởi vì ngay cả các chương trình hướng đối tượng tầm thường cũng cần một định nghĩa rộng hơn thế.

Loại đối tượng thứ hai và thú vị hơn bao gồm những thứ tôi sẽ gọi là sự kiện trong thế giới thực bất tử . Bằng cách "bất tử", ý tôi là những thứ ít nhất tồn tại trong một thời gian ngắn như một thực thể hoặc bộ sưu tập được xác định rõ trong thế giới thực, nhưng sau đó phân tán và ngừng tồn tại như những bộ sưu tập có ý nghĩa vật lý. Một hội nghị chuyên đề là một ví dụ tuyệt vời: Hội thảo chuyên đề tồn tại trong một thời gian ngắn như là một bộ sưu tập các địa điểm và con người được xác định rõ ràng. Nhưng than ôi, ngay cả những hội nghị tốt nhất cũng phải kết thúc, và những phần riêng lẻ đã khiến họ chuyển sang các hoạt động khác.

Nhưng bằng cách sử dụng máy tính và mạng, chúng ta có thể làm cho một hội nghị chuyên đề thoáng qua như vậy có vẻ như một đối tượng lâu dài bằng cách bắt và duy trì một ký ức về nó như là một đối tượng phần mềm. Rất nhiều điều chúng ta làm với máy tính và cơ sở dữ liệu tương đương với sự bất tử của các sự kiện thoáng qua, trong đó chúng ta thực sự cố gắng làm cho vũ trụ thực sự của chúng ta trở nên giàu có hơn bằng cách nắm bắt và mở rộng nó theo những cách không thể tồn tại về mặt vật lý. Ví dụ, bạn đã thấy một Pandora thực sự gần đây? Việc chụp và mở rộng các mảnh trong thế giới thực như vậy giúp làm phong phú và mở rộng cuộc sống, nền kinh tế và lựa chọn của chúng ta theo những cách đáng chú ý. Đối với tôi đây là trung tâm của lập trình hướng đối tượng, nơi mà nó đã có và tiếp tục có những tác động đáng chú ý nhất.

Danh mục cuối cùng của OOP bao gồm các đối tượng không có kết nối chặt chẽ với các sự kiện bên ngoài, nhưng thay vào đó là cơ sở hạ tầngcần thiết để hỗ trợ chúng tôi tiếp tục mở rộng thực tế bằng cách sử dụng các vật thể bất tử từ thế giới thực. Đây là nơi bạn có thể hạ xuống toàn bộ kim loại (bán) của máy tính, tạo ra những mảnh thực tế dai dẳng giống như các yếu tố hóa học của thế giới thực có thể được kết hợp nhanh chóng và theo những cách thú vị để xây dựng thế giới nội tâm mới. Điện toán di động đã giúp thúc đẩy sự phát triển của loại phương pháp tái tổ hợp cao này, một lần nữa theo nhiều cách bắt chước các tính năng tái tổ hợp của thế giới vật lý. Nó cũng khó: Những gì có vẻ như là một lựa chọn tốt có thể chứng minh theo thời gian là một điều xấu bất ngờ, thường là vì nó kết thúc việc ngăn chặn sự đa dạng và mở rộng thay vì hỗ trợ nó.

Danh mục cuối cùng này cũng chỉ ra những rủi ro khi chỉ sử dụng một mô hình để lập trình, vì giống như thế giới thực, thế giới được lập trình cũng cần các quy trình khôngtương ứng tốt với các đối tượng tương đối không thay đổi. Trái đất có rất nhiều vật thể, nhưng mặt trời chứa đầy các dòng năng lượng rất năng động mà cuối cùng là cần thiết để "lái" các vật thể và hoạt động trên trái đất có năng lượng thấp hơn. Tương tự như vậy, trong việc tạo ra thế giới điện toán, có những trường hợp bạn phải đối phó với các luồng và biến đổi và bối cảnh thay đổi nhanh chóng, mặc dù bản thân chúng không giống đối tượng, nhưng lại cực kỳ quan trọng để cho phép các đối tượng đơn giản hơn, thân thiện với con người hơn được sử dụng ở cấp độ cao hơn . Không phải ngẫu nhiên mà phần lớn các chương trình được thực hiện ở cấp hạt nhân không giống như đối tượng, hoặc nó có xu hướng phụ thuộc nhiều vào các ngôn ngữ như C được định hướng xử lý nhiều hơn. Đây là những miền sâu hơn bổ sung cho sự đa dạng hấp dẫn mà chúng ta thấy cao hơn trong thế giới do máy tính tạo ra.

Một lĩnh vực khác mà OOP có thể trở nên tồi tệ là tập trung quá nhiều vào các khái niệm đối tượng .

Các vật thể trong thế giới thực, và đặc biệt là các vật thể sống , có một mức độ hoàn toàn đáng kinh ngạc về khả năng tương tác với môi trường của chúng theo những cách phức tạp và tinh tế. Các vật dụng có thể kết hợp nhìn nhau, thực hiện một số kiểm tra tính tương thích và độ tỉnh táo và thậm chí có thể tìm ra một số cách mới để tương tác gần với khái niệm sinh học trong thế giới thực hơn là các khung đơn giản và các kế hoạch thừa kế đơn giản mà chúng ta có xu hướng để tập trung vào (thường là do sự cần thiết!) ở cấp mã. Đây là một trong những lĩnh vực tăng trưởng cho các đối tượng trong thế giới mạng, các cách tiếp cận "giống như tác nhân" hơn trong đó phản ứng với môi trường là tiêu chuẩn ngay cả trong chính chương trình.

Và rất nhiều cho "phê bình" của tôi về OOP! Tuy nhiên, tuy nhiên, tôi hy vọng tôi đã chỉ ra lý do tại sao tạo ra một thế giới mạng phong phú hơn có nghĩa là bao gồm sự đa dạng của các phong cách lập trình, thay vì cho rằng "chỉ một" là tất cả những gì cần thiết. Cảm giác của tôi là những thứ thực sự thú vị vẫn chưa đến, bất kể những gì chúng ta làm bây giờ là trần tục!


18
Tôi chắc chắn có khá nhiều người đã bỏ học tại phần "Chỉ đọc thêm nếu bạn quan tâm đến phần khám phá ở cấp độ vật lý". Tôi vui vì tôi đã không làm thế. Đây là loại suy nghĩ làm lung lay nền tảng của sự hiểu biết của chúng ta, và có lẽ là cách duy nhất chúng ta sẽ đạt được tiến bộ đáng chú ý. Cảm ơn đã đọc tuyệt vời.
Matt Esch

@Raynos, $ MattEsch, cảm ơn cả hai bạn vì những lời nói tử tế, và tôi rất vui vì bạn thấy nó thú vị!
Terry Bollinger

1
Đăng ký vào trang web chỉ để có thể bình chọn - câu trả lời tuyệt vời, sâu sắc này. =)
sgorozco

2
Theo đúng suy nghĩ của bạn, tôi đã lập trình khá lâu và trở thành một người nhiệt tình OOP, vì tôi thực sự thấy kỹ năng mã hóa của mình cải thiện đáng kể khi tôi áp dụng nó. Tuy nhiên kinh nghiệm đã cho tôi thấy rằng việc ép buộc mọi thứ trở thành một đối tượng thực sự có thể gây bất lợi. Bây giờ tôi chùn bước trước các công cụ ánh xạ đối tượng (một mớ hỗn độn) hoặc các sơ đồ tuần tự hóa biểu đồ đối tượng đầy đủ tiêu thụ 1000% băng thông so với một giao thức nhị phân đơn giản chỉ cần gửi qua dây đúng số lượng dữ liệu nhị phân cần thiết tại khoảnh khắc. Cảm ơn đã đọc tuyệt vời.
sgorozco

2
Câu trả lời này cũng là câu trả lời tại sao chúng ta vẫn cần SQL!
HLGEM

25

Đầu tiên, bạn không cần OOP cho tất cả mọi thứ, mặc dù bất kỳ giáo điều nào liên quan đến việc này đã được phổ biến. Không giống như Java, C cho phép các con trỏ hàm và thậm chí đóng để mở ra cánh cửa cho lập trình hàm và giải quyết khá nhiều phần xử lý không gian OOP, bởi vì nó cung cấp các phương thức tiêm phụ thuộc. Việc sử dụng macro thận trọng cũng thực sự có thể tạo ra một số thứ rất hay, như sglib chứng minh.

Theo một cách kỳ lạ, người ta có thể thấy C là một sự thỏa hiệp tốt giữa Java và C ++. Xin lưu ý tôi không nói rằng C là một sự pha trộn của cả hai. Nhưng trái ngược với Java, nó là ngôn ngữ khá mạnh mẽ trong khi trái ngược với C ++, nó có độ phức tạp có thể quản lý được.

Đó là một ngôn ngữ cũ, đã phát triển đáng tin cậy và nhất quán, trong khi không thực sự phát triển phức tạp hơn. Và tất cả những thứ đó, nó có một hệ sinh thái khổng lồ và nó chỉ đơn giản là chạy khắp nơi.


11
Lập trình chức năng là tuyệt vời, không phản đối về điều đó. Nhưng C là một ngôn ngữ khá tệ cho lập trình chức năng. Đóng / khối là các hack không di động và đi kèm với cú pháp xấu xí (cũng như gotchas, tôi đặt cược). Ngay cả khi bỏ qua tất cả, bạn vẫn phải quan tâm đến việc quản lý bộ nhớ. C là một ngôn ngữ hữu ích, nhưng giống như với bất kỳ ngôn ngữ nào, bạn chỉ khiến cuộc sống của mình trở nên khó khăn hơn nếu bạn lạm dụng nó để sử dụng một mô hình mà nó không được tạo ra. Bạn cũng có thể mô phỏng lập trình chức năng trong Java (xem Guava ), nhưng nó cũng không hay.

7
Rất khó để lập trình theo kiểu chức năng mà không có trình thu gom rác.
Konstantin Solomatov

@KonstantinSolomatov: Thứ nhất, điều đó rất chủ quan. Thứ hai, bạn có thể thêm bộ sưu tập rác vào C nếu cần.
back2dos

Nếu bạn muốn thỏa hiệp giữa Java và C ++, hãy thử Obj-C :) Chắc chắn là thứ mà mọi lập trình viên C / C ++ nên thử.
Sulthan

21

C có ABI (Giao diện nhị phân ứng dụng) C ++ không. Điều này làm cho C hữu ích hơn C ++ trong một số trường hợp nhất định. Nếu tôi định viết thư viện và có thể gửi các tệp nhị phân cho người khác, thì C ++ là công cụ sai cho công việc. Nếu tôi sẽ viết các thư viện sẽ được sử dụng bởi một số ngôn ngữ khác thì C là công cụ phù hợp cho công việc. Tôi chưa bao giờ nghe thấy một ngôn ngữ không hỗ trợ FFI (giao diện Hàm ngoài) cho C, mặt khác, C ++ sẽ không hoạt động với các thư viện được viết bằng C ++ nếu các trình biên dịch khác nhau được sử dụng.

Về cơ bản, nó tập trung vào C để lấp đầy một vai trò mà C ++ không phù hợp.


2
Mmm .. một cuộn C, cà chua và phô mai!
DeadMG

3
Chà, C ++ không có ABI. Chỉ là C ABI rắn chắc như đá trong khi C ++ thay đổi quá thường xuyên. Ngoài ra, rất nhiều C ++ là các mẫu được biên dịch vào ứng dụng, vì vậy bạn không thể cập nhật nó. Khi tất cả các chức năng bị ẩn sau các lệnh gọi chức năng, có thể sửa thư viện và giữ cho ứng dụng hoạt động.
Jan Hudec

12

Một lợi thế của việc sử dụng C so với các ngôn ngữ như C ++ hoặc Java là không có nhiều phép thuật xảy ra dưới mui xe. Không có hàm tạo nào được chạy khi các mục được phân bổ và không có hàm hủy nào được chạy khi các đối tượng nằm ngoài phạm vi. Không có tên xáo trộn và không có vtables. Hiệu suất dễ dự đoán hơn; bạn không phải lo lắng về việc một người thu gom rác làm gián đoạn một thói quen và bỏ qua thời gian của nó.

Trình xây dựng, hàm hủy, xáo trộn tên, vtables, bộ thu gom rác, v.v., có thể giảm bớt một số sự phức tạp trong mã mà bạn tạo ra, nhưng sau đó sự phức tạp đó trở thành một phần của ngôn ngữ, nơi bạn có ít quyền kiểm soát nó . Bạn có thể kết thúc với thời gian xây dựng lâu hơn (gây phiền nhiễu, nhưng có thể chịu đựng được), dung lượng bộ nhớ thời gian chạy lớn hơn (có thể hoặc không thể chấp nhận được) hoặc hiệu suất chậm hơn. Với C, bạn có thể giảm bớt một số sự phức tạp đó cho đến khi bạn rời khỏi chức năng bạn cần .

Ví dụ, C ++ stringkiểu dữ liệu là năm ánh sáng dễ dàng hơn để làm việc với hơn chuỗi C-phong cách, nhưng đó là một mảnh khá nặng mã, và cho biết thêm một số trọng lượng kích thước hình ảnh của bạn. Tôi hiếm khi thấy ai sử dụng hết stringkhả năng của mình trong bất kỳ chương trình nào. Các chuỗi kiểu C, trong khi khó xử lý hơn, áp dụng hình phạt ít hơn về thời gian chạy và kích thước hình ảnh, và đối với một vấn đề cụ thể có thể hấp dẫn hơn vì lý do đó.


2
Hình phạt của thời gian chạy là vô nghĩa. Chuỗi C (kết thúc null) kém hiệu quả hơn chuỗi C ++. Ngoài ra, một lớp chuỗi có thể nhỏ gọn như C, miễn là bạn không kéo toàn bộ stdvào.
Pubby

1
Một chuỗi công cụ không loại bỏ các chức năng không được sử dụng trong stringđó không được sử dụng nếu bạn liên kết tĩnh CRT là một chuỗi công cụ không đáng giá.
Billy ONeal

10
Điều ngớ ngẩn là, tôi làm việc với một thư viện std::stringkhông đủ tinh vi . Nếu bạn thực sự nghiêm túc về các chuỗi, cả về hiệu suất và khả năng, bạn sẽ quay lại sử dụng C và tự mình làm lại, mặc dù không sử dụng char*s cũ đơn giản để đảm bảo. (Chuỗi rất phức tạp một cách đáng ngạc nhiên, ngay cả khi bạn đang mong đợi chúng phức tạp.)
Donal Fellows

1
@DonalFellow Thú vị. Đây chính xác là lý do tại sao tiêu chuẩn C luôn bỏ qua những thứ như chuỗi và bảng băm, đôi khi sự vắng mặt của chúng làm tôi khó chịu.
Kỹ sư

@ArcaneEngineer: Kiểu dữ liệu bị thiếu cơ bản trong C là kiểu "lát T []" kết hợp T * và size_t, có thể được lập chỉ mục như một mảng, có thể phân tách thành T * và có thể được chuyển đổi hoàn toàn từ T * bất kỳ loại T [n] (với kích thước được trình biên dịch tự động cung cấp). Một loại như vậy có thể cho phép kiểm tra giới hạn tự động trong nhiều trường hợp nếu không thể, trong khi làm cho nhiều loại mã sạch hơn và dễ đọc hơn.
supercat

11

Các hệ thống và trình điều khiển nhúng thường được lập trình trong C. Bên cạnh đó, có hàng tấn hệ thống C kế thừa vẫn còn được duy trì và mở rộng.


2
Có, C chạy trên tất cả mọi thứ. Và đó là một ngôn ngữ khá dễ học (so với c ++).
BenjaminB

10

Điều tương tự làm cho búa thủ công trở nên phổ biến trong thời đại búa khí nén (búa không khí): C vẫn là công cụ phù hợp cho một số công việc nhất định.


6

Đơn giản, nhất quán và chính xác.

Rất đơn giản - bạn không cần một môi trường phát triển phức tạp, thư viện rộng lớn hoặc máy ảo.

Nó phù hợp - hầu hết C được viết 10 năm trước có thể biên dịch ngày hôm nay.

Chính xác - cho phép bạn xuống cấp độ của máy, biết các vị trí bộ nhớ khi cần. Điều này là tuyệt vời cho hiệu suất và phần cứng nhúng.

Nó không dành cho tất cả mọi thứ, bit vẫn là một công cụ hữu ích.


5
Tốt hơn nữa, có một cơ hội công bằng rằng mã được biên dịch 10 năm trước có thể thực thi ngày hôm nay.
Donal Fellows

@DonalFellows: Và, đối với các ứng dụng sử dụng trình cắm, có một cơ hội công bằng rằng một ứng dụng được viết, xây dựng và phát hành (ở dạng thực thi) ngày nay sẽ có thể sử dụng các trình cắm được biên dịch bằng các công cụ xây dựng thậm chí chưa được được thiết kế chưa.
supercat

6

Tôi trích dẫn hai điểm từ một câu trả lời khác, bởi vì họ thỉnh thoảng nắm bắt chính xác lý do tại sao tôi vẫn sử dụng C (đây không phải là ngôn ngữ chính của tôi):

  • C là đơn giản. Nó thiếu tính biểu cảm của OOP tinh vi hoặc các ngôn ngữ chức năng, nhưng sự đơn giản của nó có nghĩa là nó có thể được chọn một cách nhanh chóng.
  • C là người trưởng thành. Tiêu chuẩn cuối cùng đưa ra những thay đổi lớn là C99 và nó hầu như tương thích ngược với các tiêu chuẩn trước đó. Không giống như các ngôn ngữ mới hơn (giả sử là Python), bạn không phải lo lắng về việc phá vỡ các thay đổi bất kỳ lúc nào.

Tôi nghĩ điều này rất đúng. Tôi đã học C trong những đêm đầu tiên: nó đơn giản, ít từ khóa và cấu trúc, hầu hết các công việc được thực hiện bởi các thư viện. Sau đó tôi đã không sử dụng C trong một vài năm. Khoảng năm 2002 tôi cần triển khai nhanh thuật toán, tôi đã cài đặt trình biên dịch C và thực hiện nó. Tôi biết ngôn ngữ, tôi biết nó tốt cho cái gì, nó không tốt cho cái gì (tôi sẽ không bao giờ triển khai một ứng dụng web trong C!), Và nó chỉ ở đó khi tôi cần. Không có bất ngờ.

Với C ++ tôi đã có một trải nghiệm khác. Tôi đã học nó vào khoảng năm 1995 và nó có nghĩa là một sự chuyển đổi mô hình lớn từ mệnh lệnh sang OOP. Tuyệt quá! Tôi đã sử dụng nó cho một số dự án cho đến năm 1999. Trong một vài năm tôi đã không sử dụng C ++ và khi tôi chọn lại nó (2008) tôi đã tìm thấy rất nhiều tính năng mới đã có trong ngôn ngữ và thậm chí còn được lên kế hoạch (trong khi được giới thiệu trong C ++ 11). Tôi có cảm giác tôi phải học ngôn ngữ một lần nữa.

Là một nhà phát triển, tôi thích ngôn ngữ trưởng thành, ổn định. Tôi thích học một ngôn ngữ một lần, để hiểu các nguyên tắc thiết kế của nó, nó tốt cho cái gì và sử dụng nó khi tôi nghĩ nó là công cụ phù hợp cho công việc. Tôi cũng thích học các ngôn ngữ khác nhau và chọn ngôn ngữ phù hợp với nhu cầu của tôi (C, C ++, Java, Scala, Haskell, v.v.). Điều tôi không thích là phải học cùng một ngôn ngữ bởi vì nó được phát triển ngày càng xa hơn và không bao giờ đạt đến độ chín.

IMHO, một ngôn ngữ lập trình nên có thiết kế rõ ràng, mạch lạc và ổn định. Tôi thích cách tiếp cận của các nhà thiết kế như Niklaus Wirth: mỗi khi anh ta cảm thấy cần một ngôn ngữ khác, anh ta đã thiết kế một ngôn ngữ mới (Pascal, Modula-2, Modula-3, Oberon). Tôi không thích những ngôn ngữ trải qua những thay đổi quan trọng cứ sau 5-10 năm: chúng giống như những mục tiêu di chuyển và tôi không bao giờ cảm thấy đáng để đầu tư thời gian của mình để học chúng một cách sâu sắc, bởi vì phiên bản tôi đang học bây giờ có thể sẽ bị lỗi thời năm nào cũng được.

Theo nghĩa này, C là IMO một người chiến thắng: nó tốt cho một số ứng dụng nhất định và ít phù hợp hơn với các ứng dụng khác, nhưng nó có ưu điểm là nó đơn giản và tương đối ổn định.


4

Tôi ngạc nhiên khi chưa có ai nhắc đến Worse Is Better . Nó đã hơn 20 tuổi vào thời điểm này, nhưng vẫn rất đáng đọc. Mặc dù đôi lúc hơi tặc lưỡi, nhưng nó rất tốt trong việc phác thảo cách thức và lý do tại sao người viễn chinh thường chiến thắng lý tưởng, sử dụng C (đọ sức với LISP) làm một trong những ví dụ trung tâm.


Những thứ mà tôi đặt trong danh mục 'tệ hơn nhưng tốt hơn': tiếng Anh, PHP, Windows. .. Có lẽ McDonald. Mặc dù tôi vẫn ghen tị / thích nấu ăn Tây Ban Nha, Python, Linux và Nghệ nhân Pháp; càng nhiều càng tốt, nếu không thường xuyên có thể.
ThorSummoner

1

Có lẽ bạn muốn hỏi tại sao mọi người sử dụng C thay vì C ++ mặc dù thực tế là khi bạn có trình biên dịch C, bạn cũng thường có trình biên dịch C ++.

  • Ngôn ngữ C đơn giản hơn nhiều so với C ++. Tôi không biết bất kỳ công ty nào sử dụng tiêu chuẩn C ++ hoàn chỉnh trong quy ước mã hóa của họ. Hãy xem phong cách mã C ++ của Google làm ví dụ: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
  • C nhanh hơn nhiều để biên dịch. Nhờ thiếu các cấu trúc khó biên dịch.

Liên kết này bị hỏng.
ar2015

0

Không có gì. TIOBE là một chỉ số vô giá trị. Nếu bạn thực sự nhìn vào số đo của họ, đó là một phỏng đoán tuyệt đối - tốt nhất.


10
Việc TIOBE vô dụng không có nghĩa là C không phổ biến
Raynos

Tuy nhiên, nó chắc chắn đánh bại đối số được trình bày trong OP- rằng C là phổ biến và do đó nó phải có một số sử dụng.
DeadMG

2
Một thước đo tốt hơn về mức độ phổ biến của C là hầu hết mọi nền tảng đều có trình biên dịch C
Raynos

@Raynos: Đó hoàn toàn không phải là phép đo. Điều duy nhất có nghĩa là nó dễ thực hiện. Nó không nói bất cứ điều gì về số lượng người sử dụng nó, hoặc tại sao.
DeadMG

2
Không hoàn toàn, tôi vui vẻ chấp nhận quan điểm đối lập. Câu trả lời một dòng của bạn dường như có ít suy nghĩ được áp dụng, và bạn đang tranh luận và không có kết cấu với câu trả lời của bạn.
mattnz

0

Rất nhiều phần mềm kế thừa

Nhiều công ty không thể thay đổi, ngay lập tức tất cả mã của họ thành C ++ hoặc tương tự.

Nhiều công ty không thể đủ khả năng để thay đổi mã của họ.

Nhiều công ty có thể đủ khả năng để thay đổi mã của họ, nhưng không quan tâm, hoặc là "giá rẻ".

Nhiều công ty đang trong quá trình di chuyển, nhưng, chưa hoàn thành.

Định hướng đối tượng ẩn

(Không hướng đối tượng) Mã nguồn C được thiết kế dưới dạng mã nguồn C hướng đối tượng, các ứng dụng được mô hình hóa với Định hướng đối tượng và được mã hóa bằng "thuần C" hoặc các công cụ dịch từ "C ++" hoặc các chương trình OO khác. lang vào C.

Tôi nghe nói rằng một số trò chơi video được thực hiện theo cách đó. Một số công cụ đa nền tảng cũng và thư viện giao diện trực quan GTK (GObject, GL Library) cho các bản phân phối hệ điều hành Linux của GNome.


3
Nửa sau của câu trả lời này cần phải được khử.
aramis

@aris. Phần thứ hai có nghĩa là: Nhiều mã dường như là donde trực tiếp trong "C", nhưng, thực ra bằng ngôn ngữ khác, và được đặt thành "C"
umlcat

0

Tôi thấy một số người trả lời đưa ra lý do tại sao C là phổ biến nhất, nó đã xuất hiện từ lâu, nó có sẵn trong hầu hết các nền tảng, miễn phí, v.v.

Nhưng điều tương tự cũng có thể nói về các ngôn ngữ khác, ví dụ Pascal miễn phí - nó miễn phí và được hỗ trợ cho tất cả các nền tảng.

Pascal được phát minh vào khoảng năm 1970, C được phát minh vào khoảng năm 1972, vì vậy tôi nghĩ Pascal đã tồn tại chừng nào C.

Cá nhân tôi nghĩ rằng C là ngôn ngữ phổ biến nhất vì có sẵn mã nguồn mở hơn để mọi người sử dụng lại. Và vâng, nó ở cấp độ thấp hơn Pascal, vì vậy nó tiến gần đến lắp ráp nhưng nó dễ đọc hơn nhiều so với lắp ráp.

Tôi nghĩ có quá nhiều ngôn ngữ lập trình ngoài kia. Là lập trình viên, chúng ta phải biết hầu hết những người quan trọng, nhưng cuối cùng không cần điều đó. Một ngôn ngữ lập trình có thể được thực hiện để làm tất cả từ xây dựng trang web đến trò chơi máy tính iOS.

C dường như là ngôn ngữ toàn cầu, nhưng tôi ước nó sẽ giống như Object Pascal. Tại sao Object Pascal, đó là ngôn ngữ lập trình dễ đọc hơn, mã OOP có xu hướng dễ sử dụng lại và ít bị lỗi hơn (theo ý kiến ​​của tôi) so với C.

Các ứng dụng rất lớn dễ quản lý với Object Pascal hơn C / C ++.

Như có một ngôn ngữ lập trình đã là một số từ năm 70, và không thích các ngôn ngữ thay đổi cứ sau 5 hoặc 10 năm. Khi thời gian tiến bộ công nghệ và phương pháp lập trình được cải thiện. Nếu một ngôn ngữ thay đổi mạnh mẽ cứ sau vài năm thì có lẽ nó không được nhà thiết kế của nó nghĩ ra. Nhưng 1970 đến 2012 là gần nửa thế kỷ, bạn có thể thay đổi ngôn ngữ trong thời gian đó để kết hợp những tiến bộ được sử dụng trong phát triển Phần mềm.

Bản thân C đã được sửa đổi nhiều lần. Vì vậy, nó không tốt hơn các ngôn ngữ khác hình thành quan điểm đó.


3
Một vấn đề với Pascal là phiên bản "chính thức" của ngôn ngữ đã bỏ qua một số tính năng rất cần thiết. Trong một lúc, cả PC và Macintosh đều có trình biên dịch Pascal có thể sử dụng nhiều hơn bất kỳ trình biên dịch C nào tồn tại vào thời điểm đó, nhưng các trình biên dịch đó đã thêm các phần mở rộng ngôn ngữ không được hỗ trợ bởi bất kỳ tiêu chuẩn "chính thức" nào. Tôi nghĩ rằng nếu đã có một nỗ lực để tạo ra một tiêu chuẩn chính thức mã hóa các phần mở rộng như vậy, Pascal có thể đã thay thế việc hack ngôn ngữ được gọi là "C".
supercat

0

Vì C có lượng người dùng rất lớn. Vâng, đó là một chút của một Catch-22, nhưng khi tôi hỏi một câu hỏi về C trên StackOverflow, tôi nhận được câu trả lời gần như ngay lập tức. Câu hỏi tương tự về Python có thể mất hàng giờ để được trả lời.

Đối với C ++, IMO phức tạp hơn để tìm hiểu. Hơn nữa, sau khi đã thử OOP được 10 năm, tôi thấy nó không phải lúc nào cũng hữu ích và thường thì việc sử dụng lập trình thủ tục sẽ dễ dàng hơn.


bạn đã so sánh việc đặt câu hỏi SO cho C # hay Java chưa?
gnat

@gnat đó là một ví dụ riêng biệt của C v Python (mà nhân tiện có nhiều câu hỏi hơn!). Tôi không có kinh nghiệm với C # (bạn có nhận thấy tôi không đặt câu hỏi SO cho C # hoặc jav không?)
puk

Heh, tôi thấy cộng đồng #python trên StackOverflow hầu như luôn siêu nhanh. Mặc dù tôi sẽ rất ngạc nhiên nếu cộng đồng C vượt xa cộng đồng javascript về tốc độ trả lời. (Chủ yếu là vì âm lượng)
ThorSummoner
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.