Tôi có cần học C không?


8

Tôi là một sinh viên tiến sĩ về tính toán khoa học và trong vài tháng qua, tôi đã dành một khoảng thời gian tốt để học Python và C ++ đúng cách. Tôi cảm thấy rằng tôi đã học tốt C ++ và tôi có thể sử dụng Python để làm những gì tôi muốn nếu tôi giữ một cuốn sách tham khảo tốt xung quanh.

Tôi cũng biết MATLAB đủ để tạo nguyên mẫu cho ý tưởng của mình và nhận giải pháp. (Nếu tôi quá chán để viết mã Python là lựa chọn đầu tiên của tôi).

Tôi đã đọc nhiều lần ở đây rằng một người nên ghép C và C ++ thành một "C / C ++" vì chúng là những ngôn ngữ cực kỳ khác nhau với những động cơ khác nhau và tôi hoàn toàn đồng ý với quan điểm đó.

Mặc dù tôi không thể yêu cầu "biết" C ++ vì tôi luôn học hỏi nhưng tôi nghĩ tôi hiểu hầu hết cách tôi nên sử dụng và tôi không nên sử dụng nó như thế nào. Ngôn ngữ đầu tiên tôi học là C nhưng đã rất lâu kể từ lần cuối tôi sử dụng nó. Câu hỏi của tôi về cơ bản là thế này:

Cho rằng tôi biết MATLAB, C ++ và Python; Có nên đầu tư thời gian vào việc học C? Kiến thức của tôi về 3 ngôn ngữ được đề cập có đủ để tôi viết mã không?

Nghiên cứu của tôi là nhiều hơn về phía đại số tuyến tính số nhưng tôi cũng thực hiện một số tư vấn quy trình mô phỏng sự kiện / ngẫu nhiên rời rạc. Ý định của tôi là làm việc trong ngành Công nghiệp (Cố vấn của tôi đề nghị tôi học C ++ để tôi có thể tuyển dụng được mặc dù anh ta không có sở thích cá nhân về ngôn ngữ).


Sự khác biệt giữa Fortran 60 và Fortran 2003 lớn hơn giữa C99 và C ++ 98. Và giữa 77 và 2003 là khá nhiều như nhau. Tuy nhiên, mọi người gọi chúng là "chỉ" Fortran.
Misha

1
Bạn nên ném tất cả các ngôn ngữ khác và chỉ cần học Fortran;) Fortran hiện đại có mọi thứ bạn cần cho những gì bạn làm.
Nasser

Cho dù bạn sử dụng ngôn ngữ nào, hãy đảm bảo bạn ghi lại bất kỳ mã nào phải được duy trì và bao gồm một số ví dụ và kiểm tra tự động. Nếu bạn không làm điều đó thì bạn không thực sự biết bất kỳ ngôn ngữ nào.
cjordan1

@Nasser ngoại trừ nếu bạn muốn làm việc với bất kỳ khung nguồn mở quy mô lớn nào. Lammps, dealii, Trilinos, MercuryDPM, tất cả C ++. Tôi sẽ khuyên mọi người học mọi thứ Nhưng Fortran, nhưng cuối cùng đó chỉ là vấn đề ưu tiên.
BlaB

Câu trả lời:


13

Tôi sẽ chỉ giải quyết việc so sánh C với C ++. Mặc dù sự thật là mọi thứ được viết bằng C đều có thể được chuyển sang C ++ với một vài cú chạm cú pháp, các cộng đồng có các giá trị khác nhau. Cộng đồng thư viện C, hơn hầu hết mọi người khác, coi trọng sự ổn định nhị phân . Sự ổn định nhị phân là rất quan trọng đối với các thư viện cấp thấp để tránh gây đau liên tục cho các lớp trên, đặc biệt khi được sử dụng với mô hình phân phối nhị phân và thư viện dùng chung. C là ưu tiên áp đảo cho các thư viện như vậy chỉ cần hoạt động, với khả năng gửi các bản phát hành mới mà không cần biên dịch lại các lớp ở trên.

Có thể gửi các thư viện C ++ hoạt động ở cấp độ này, nhưng cuối cùng bạn cần phải "viết C trong C ++". Ví dụ: bạn sẽ không bao giờ đặt định nghĩa cấu trúc với các thành viên riêng hoặc ảo trong tiêu đề công khai, bạn sẽ không bao giờ sử dụng các mẫu trong giao diện công cộng và bạn sẽ không bao giờ có API dựa trên sự kế thừa từ các lớp có bất kỳ thành viên dữ liệu nào. Những ràng buộc này là cần thiết để chứa chính xác các phụ thuộc, để bạn có thể sửa đổi triển khai của mình mà không thay đổi giao diện nhị phân. C có xu hướng dễ dàng hơn nhiều để liên kết từ các ngôn ngữ khác nhau, do mô hình đối tượng đơn giản hơn và ABI được xác định rõ.

Nếu bạn đang viết mã ở cấp ứng dụng thay vì cấp thư viện, thì giao diện nhị phân của bạn không quan trọng, vì vậy nhiều mối lo ngại này sẽ biến mất. Việc sử dụng các tính năng ngôn ngữ C ++ như kế thừa và các mẫu vẫn có xu hướng tạo ra mã được ghép chặt chẽ hơn, dẫn đến việc biên dịch lại tốn nhiều thời gian hơn khi dự án phát triển. Ngoài việc phụ thuộc nhiều vào thời gian biên dịch, chỉ cần biên dịch mã C bằng trình biên dịch C ++ làm tăng đáng kể thời gian biên dịch (khoảng 2 lần với hầu hết các công cụ).

Nếu những mối quan tâm này làm bạn quan tâm hoặc nếu bạn dự định làm việc trên các thư viện cấp thấp hơn, thì việc dành thời gian cho C có thể đáng giá. Nếu bạn thích sử dụng các tính năng ngôn ngữ C ++ và không quá bận tâm bởi giao diện nhị phân và độ chặt của khớp nối, thì đó có thể không phải là cách sử dụng tốt thời gian. Nhưng hãy nhớ C nếu những điều này bắt đầu làm phiền bạn trong tương lai.


Có rất nhiều câu trả lời tuyệt vời, thật khó để chọn một câu nhưng đây là câu mô tả và đầy đủ nhất theo ý kiến ​​của tôi. +1 cho mọi người mặc dù. Rất thích đọc rất nhiều quan điểm. Tôi quyết định tôi sẽ tiếp tục hoàn thiện C ++ và học C trên cơ sở cần thiết.
Cuộc điều tra

Để đầy đủ, có thể muốn thêm thành ngữ pimpl là một cách mà các lập trình viên C ++ có thể xây dựng "tường lửa biên dịch" để họ không phải biên dịch lại mã ứng dụng sau khi thay đổi triển khai cơ bản.
cjordan1

7

Thay vì "học C", tôi khuyên bạn nên ở thời điểm hiện tại bạn đã thực hiện đủ chương trình và làm việc với đủ ngôn ngữ lập trình mà bạn nên tập trung thay vào đó là cải thiện kỹ thuật lập trình và kiến ​​thức rộng hơn về khoa học máy tính. Sau đó học C nếu và khi bạn cần nó cho một dự án cụ thể.

Lập trình viên có kinh nghiệm nhanh chóng chọn ngôn ngữ lập trình mới khi cần thiết cho các dự án cụ thể. Họ có thể làm điều này bởi vì họ hiểu các khái niệm quan trọng dịch từ ngôn ngữ này sang ngôn ngữ khác - cú pháp không phải là vấn đề lớn nếu bạn nắm vững các khái niệm cấp cao hơn đó. Khi bạn xem các sinh viên cố gắng học ngôn ngữ lập trình thứ hai của họ, bạn sẽ thường thấy họ phải vật lộn với việc hiểu một số khái niệm mới không phải là một phần của ngôn ngữ đầu tiên của họ. Ví dụ, những sinh viên bắt đầu với Fortran thường phải vật lộn với các con trỏ trong C. Những sinh viên biết C thường phải vật lộn với các tính năng hướng đối tượng của C ++, v.v.


6

Câu trả lời cho câu hỏi này thực sự phụ thuộc vào những gì bạn thực sự làm.

Là một nhà khoa học máy tính chuyên về điện toán hiệu năng cao , tôi muốn nói rằng việc biết / hiểu lập trình trong C. là điều cần thiết.

Nhưng nếu bạn chỉ cần làm những thứ trên máy tính, sau đó kiến thức của bạn của C ++ nên là đủ để giúp bạn có được thông qua.

Cụ thể hơn, nếu bạn thực sự quan tâm đến các khía cạnh tính toán, tức là viết các thuật toán khai thác tối đa các máy tính hiện đại, bạn sẽ không thể tránh phải đối phó với các khía cạnh cấp thấp như quản lý bộ nhớ, bố cục dữ liệu, SIMD vector hóa, song song mức hướng dẫn, song song bộ nhớ chia sẻ hoặc tính toán GPU (CUDA và OpenCL dựa trên C).

Bây giờ, hầu hết những điều này có thể được các trình biên dịch chăm sóc (ví dụ như quản lý bộ nhớ, bố cục dữ liệu, vector hóa) và / hoặc trừu tượng hóa ở cấp độ cao hơn (ví dụ OpenMP, OpenACC, thư viện được tối ưu hóa). Nhưng chỉ ở một mức độ nhất định. Làm mọi thứ bằng tay thường liên quan đến nhiều công việc hơn, nhưng mức chi trả có thể là một thứ tự lớn trong hiệu suất.

Về cơ bản, bất cứ khi nào bạn muốn tự mình kiểm soát các chi tiết , bạn thường kết thúc bằng C vì nó "gần với kim loại" hơn. Câu hỏi là, tuy nhiên, đó là những gì bạn thực sự muốn?


1
Làm thế nào bạn có thể nói C ++ là bất kỳ xa kim loại hơn C? Bạn không thể làm gì trong C ++ mà bạn có thể làm trong C? Và bạn có nói rằng có các tính năng hữu ích không đáng kể trong C ++ cho tính toán cấp thấp không?
Milind R

@MilindR: Cấp, bạn có thể biên dịch chương trình C bằng trình biên dịch C ++, vì vậy C ++ có thể làm mọi thứ mà C làm. Vấn đề là với các tính năng bổ sung mà C ++ cung cấp, ví dụ như các đối tượng đa hình, mẫu, đường ống, v.v ... không phù hợp với "kim loại" thực tế. Nếu bạn sử dụng bất kỳ tính năng nào trong số các tính năng này của C ++, bạn sẽ mất quyền kiểm soát những gì chương trình của bạn thực sự đang làm, trên cơ sở hướng dẫn theo hướng dẫn. Đó là điểm mà tôi đã cố gắng thực hiện, và qua đó tôi đứng.
Pedro

Tôi đồng ý về các đối tượng đa hình, nhưng làm thế nào các mẫu có thể đưa bạn ra xa kim loại hơn? Tôi nghĩ rằng bạn đang đề cập đến hệ thống phân cấp thừa kế ở đây. Bất cứ thứ gì không sử dụng chúng đều có khả năng khá gần với kim loại.
Milind R

1
@MilindR: Không. Giả sử bạn sử dụng lớp mẫu cho vectơ floathoặc double. Các hoạt động thực tế trên các vectơ đó sẽ được thực hiện theo cách tối ưu cho cái này hoặc cái kia, nhưng không bao giờ cho cả hai. Hệ thống phân cấp kế thừa có cùng một vấn đề với các đối tượng đa hình: Nếu bạn không biết loại chính xác tại thời gian biên dịch, bạn không chỉ có một chi phí nhỏ trong việc chọn hàm chính xác, mà bạn cũng không thể định tuyến hàm mục tiêu.
Pedro

Đó là những gì chuyên môn hóa mẫu dành cho. Đồng ý về việc không biết loại tại thời gian biên dịch dẫn đến chi phí chung.
Milind R

4

Có một chút sao chép từ câu trả lời của tôi cho câu hỏi này , với một vài chi tiết bổ sung.

Tôi làm việc trong ngành công nghiệp (nhà sản xuất thiết bị điều khiển và điều khiển máy) bằng cách sử dụng bộ xử lý nhúng yếu (nghĩ rằng bộ xử lý điện thoại di động), trong đó khoảng 50% số máy tính được sử dụng để tính toán số - chủ yếu là công việc tổng hợp cảm biến.

Chúng tôi có một nhà toán học làm việc cho chúng tôi, người đã từng làm việc trong một nhóm HPC, vì vậy đây là một trong những nơi kỳ lạ mà cuối cùng bạn có thể tìm được việc làm!

Trong môi trường này, nơi bạn gần như chắc chắn sẽ có một hệ điều hành (ví dụ: Linux, QNX, WinCE), C ++ là vua. Chúng tôi chỉ sử dụng C cho công việc kernel (tức là trình điều khiển thiết bị) và cho công việc được nhúng sâu mà không cần hệ điều hành (micros 8 bit). Chúng tôi không sử dụng C cho bất kỳ công việc số. Thật vậy, chúng tôi không có trình biên dịch FORTRAN cho nền tảng của chúng tôi!

Hiệu suất cao là vấn đề với chúng tôi vì chúng tôi chỉ có CPU 1 watt để xử lý. Mặc dù chúng ta không có một số vấn đề "quyến rũ" song song, chúng ta phải nhận biết bộ nhớ cache và bộ nhớ, và ngày càng cần phải biết về SIMD (nghĩ NEON ). Hơn nữa, không giống như HPC, chúng ta phải nhận thức sâu sắc về độ trễ (đây là điều khiển máy!) Và các khía cạnh khác của hệ điều hành như lập lịch và chuyển đổi ngữ cảnh. Phân bổ bộ nhớ đặc biệt khó chịu trong môi trường này vì nó gần như chắc chắn có nghĩa là chuyển đổi ngữ cảnh (== độ trễ và, trên CPU 400 MHz, tốn kém về thời gian).

Các vấn đề này không phụ thuộc vào lựa chọn ngôn ngữ, vì vậy tôi sẽ không đồng ý với câu trả lời của @ Pedro rằng C là cần thiết - xét cho cùng, nội tại của trình biên dịch cho SIMD có sẵn khi sử dụng C ++. Tuy nhiên, điều đó có nghĩa là bạn phải rất cẩn thận về các tính năng của C ++ mà bạn sử dụng và giá của chúng.

Vì vậy, để hoàn thành câu trả lời, không, bạn không cần C. Chúng tôi sử dụng MATLAB cho công việc phân tích và python để viết kịch bản để hai ngôn ngữ của bạn ngoài C ++ là những lựa chọn tốt - ít nhất là trong ngành của tôi.


3

Thật tốt khi biết C và bạn thực sự có thể triển khai nhiều tính năng OO của C ++ có liên quan đến tính toán khoa học trong C mà không gặp nhiều rắc rối (rất nên xem mã nguồn của PETSC để xem cách họ làm nó).

Điều đó nói rằng, không có câu trả lời một kích cỡ phù hợp cho câu hỏi này. Có nhiều yếu tố trong việc lựa chọn một ngôn ngữ, thời gian chạy là một trong số đó. Bạn dành bao lâu để viết, gỡ lỗi, lược tả mã là một yếu tố quan trọng khác. Cuối cùng, bạn muốn có năng suất cao nhất có thể. Biết C sẽ rất tuyệt nếu bạn có ý định tham gia vào lĩnh vực nghiên cứu hiệu suất cao hoặc nếu bạn dự đoán rằng mã của bạn sẽ mất một thời gian rất dài để chạy (tức là thời gian chạy nhanh hơn thời gian xử lý mã hóa của bạn). Mặt khác, nếu bạn biết C ++ và những điều này không phải là vấn đề, bạn sẽ có thể hiểu mã C đủ tốt để giao tiếp với những người đang sử dụng nó.


2
Nhưng C có thực sự nhanh hơn C ++ không?
Thắc mắc

2
Ngôn ngữ lập trình không phải là nhanh hay chậm, đó là lập trình viên viết mã tốt quyết định hiệu quả của nó. Lợi ích của C là nó rất đơn giản và việc viết mã hiệu quả trong đó dễ dàng hơn nhiều so với việc viết mã hiệu quả bằng C ++ hoặc Python (giả sử ở đây bạn đang sử dụng đầy đủ các khoa ngôn ngữ). Tôi đã thấy mã C ++ rất nhanh sử dụng toàn bộ khả năng của nó yêu cầu quản lý bộ nhớ của riêng bạn và thực hiện tất cả các loại điều khó chịu với quá tải toán tử, xem xét thời gian để viết so với phiên bản C tương đương với cùng tốc độ.
Reid.Atcheson

2
@GeoffOxberry Một số gói bạn đề cập thực sự được viết vì tính linh hoạt (trong một số phạm vi) vượt xa tốc độ. Những người viết cho tốc độ tuyệt đối phải chịu khó gỡ lỗi, thời gian biên dịch lớn và nhị phân lớn vốn có trong việc sử dụng các mẫu nhiều hơn là thực sự cần thiết cho hiệu suất. Tất nhiên bạn có thể viết gói "C" trong C ++, nhưng các giá trị cộng đồng hoàn toàn khác nhau.
Jed Brown

1
Hơn nữa, bởi "hiệu suất cao" tôi không nhất thiết chỉ đơn giản là viết mã hiệu suất cao. Ý tôi là về phía nghiên cứu của HPC, thường xử lý nhiều chi tiết cấp thấp hơn. những thứ này có thể bị che khuất bằng cách sử dụng kiểu lập trình C ++. Đây không hẳn là một điều xấu, nhưng nó phụ thuộc vào mục tiêu của bạn là gì.
Reid.Atcheson

1
Nói cách khác, nếu bạn là một nhà nghiên cứu của HPC thì việc viết mã với một gói khác xảy ra nhanh không thực sự có giá trị nghiên cứu nhiều. Mọi người sẽ muốn biết lý do tại sao mã của bạn nhanh hơn và tại sao cách tiếp cận của bạn có hiệu quả, trích dẫn một gói không cắt nó.
Reid.Atcheson

2

Giá trị của c, chẳng hạn như ngày nay, là nó buộc bạn phải làm quen với chức năng của máy tính ở mức độ trừu tượng thấp (so với, nói là trăn). Bây giờ, c ++ có tất cả các cơ sở cấp thấp của c và cũng có thể hoạt động tốt, nhưng hầu hết mọi người đều được khuyến khích khi nghiêng c ++ để tránh sự trừu tượng ở mức thấp nhất và dựa vào các mức độ cao (đã được kiểm tra và gỡ lỗi); những thứ như thư viện container, con trỏ thông minh, đa hình và như vậy.

Điều hợp lý là hầu hết các lập trình viên dành phần lớn thời gian của họ để chơi trong các lĩnh vực trừu tượng cao, bởi vì họ có thể dành nhiều thời gian tinh thần và năng lượng để viết những gì họ có ý nghĩa hơn là xử lý các chi tiết nhỏ nhặt về cách bạn hoàn thành nó.

Cái giá phải trả cho thái độ đó là một số rủi ro về sự trừu tượng bị rò rỉ cắn bạn khi bạn ít mong đợi nhất , nhưng nó gần như chắc chắn sẽ tăng thêm hiệu quả lập trình tổng thể.

Vì vậy, nếu bạn hài lòng với những gì bạn biết về chức năng cấp thấp của máy tính, bạn có thể tắt c một cách an toàn và ngay cả khi bạn không, bạn có thể sử dụng một bộ c ++ bị hạn chế để thực hiện điều tương tự.


1

Tôi đã trả lời một câu hỏi tương tự một lần trên Stack Overflow. Câu trả lời rõ ràng là học mọi thứ bạn có thể, phải không?

Vì vậy, hãy nhìn vào quan điểm tiêu cực. Bạn đã thành thạo ba ngôn ngữ mà tôi cho là có giá trị hơn C đối với lập trình khoa học. Trong công việc tư vấn của tôi, viết phần mềm khoa học, tôi đã sử dụng MATLAB, Python, FORTRAN và Java. Tôi chưa bao giờ có nhu cầu sử dụng C hoặc C ++, nhưng lưu ý rằng tất cả công việc của tôi là cho các dự án mới. Tôi sẽ không khuyên khách hàng bắt đầu một dự án lớn trong C / C ++, nhưng sẽ khuyến nghị Java hoặc thậm chí là Scala, trừ khi có một số lý do thuyết phục để sử dụng C / C ++. Đối với một dự án nhỏ hơn, tôi sẽ đi với Python, có lẽ. Trong trường hợp của bạn, có vẻ như bạn có thể đối phó với C trên cơ sở khi cần thiết.

Tôi hy vọng rằng việc tìm hiểu thêm về các lĩnh vực mà bạn sẽ làm việc sẽ được đền đáp nhiều hơn là một tay đua ngôn ngữ. Cuối cùng, đó là giải pháp cho vấn đề chứ không phải công cụ mới là vấn đề. Knuth's đã thấy về "tối ưu hóa sớm" cũng áp dụng cho việc chuẩn bị cho sự nghiệp.


1

Có lẽ nó không đáng

C ++ và C có xu hướng chiếm cùng một ngóc ngách trong khoa học tính toán (có thể các hệ thống nhúng là một ngoại lệ). Nó từng là trường hợp trình biên dịch C tốt hơn (hoàn thiện nhiều tính năng hơn, tối ưu hóa tốt hơn) so với trình biên dịch C ++, nhưng từ những gì tôi hiểu bây giờ, đó không còn là trường hợp nữa.

Chắc chắn, C là một ngôn ngữ tuyệt vời (và tôi thích nó hơn C ++), và nếu bạn có thời gian và mong muốn, tôi khuyên bạn nên học nó, nhưng nếu bạn bị trói buộc thời gian, tôi không thấy lý do nào thuyết phục ngoài "Tôi cần phải làm việc với một dự án đang được viết bằng C "(và thậm chí sau đó, rất nhiều kiến ​​thức về C ++ của bạn sẽ tiếp tục).


0

Tôi nghĩ rằng một số kiến ​​thức C hữu ích, chủ yếu là tìm hiểu về cách biên dịch mọi thứ với liên kết "extern C" để bạn có thể kéo các thư viện C / Fortran cũ (ví dụ: lapack) vào các dự án C ++ mới. Tôi sẽ không đầu tư nhiều thời gian vào việc tìm hiểu các thư viện C cũ, những thứ đó có thể được chọn / googled khi cần hoặc đôi khi được thay thế bằng chức năng tương đương trong stdlib 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.