Sự khác biệt cơ bản giữa C và C ++ là gì? [đóng cửa]


41

Nhiều người có xu hướng viết "C / C ++", như thể chúng là cùng một thứ. Mặc dù chúng có nhiều điểm tương đồng nhưng rõ ràng chúng không giống nhau.

Nhưng đâu là sự khác biệt cơ bản giữa C và C ++? C ++ có phải là phiên bản nâng cao của C hay có các tính năng trong C không tồn tại trong C ++ không?


2
Tôi nghĩ C ++ là siêu tập hợp của C
người dùng

1
C ++ không được tăng cường ... nó là siêu sao của C ..
Joe DF

2
@JoeDF Lúc mới bắt đầu nhưng thực ra nó "tương thích với C" bây giờ không có nghĩa là điều tương tự. Bạn không mã bằng C trong C ++ và không phải tất cả C chuẩn đều tương thích với C ++ chuẩn.
Klaim

+1 Bạn nói đúng, bây giờ giống như anh em hoặc anh em họ. Nếu bạn hiểu ý tôi.
Joe DF

Câu trả lời:


43

Các điểm sau liên quan đến C ++:

  1. Hệ thống loại tĩnh (do người dùng xác định): cho phép kiểm tra tĩnh về dữ liệu của bạn và việc sử dụng chúng - chỉ ra rất nhiều lỗi dễ thực hiện trong C.
  2. multi- "paradigm": cho phép làm việc như trong C, với các mô hình hướng đối tượng, với các mô hình chung, v.v.
  3. Con constructor / Destructor: cách duy nhất để nói một lần những việc cần làm khi tạo hoặc hủy một cái gì đó và chắc chắn rằng người dùng sẽ không phải tìm đúng chức năng và sử dụng nó như trong C.
  4. RAII (tên xấu): bạn không phải luôn quản lý bộ nhớ. Chỉ cần giữ mọi thứ trong phạm vi và sử dụng con trỏ thông minh mô tả các đối tượng của bạn suốt đời. Vẫn có thể sử dụng con trỏ thô.
  5. Mẫu: tốt hơn macro, một ngôn ngữ thực để thao tác và tạo các loại trước khi biên dịch cuối cùng. Chỉ thiếu một hệ thống loại (xem Khái niệm trong các tiêu chuẩn C ++ trong tương lai).
  6. Quá tải toán tử: cho phép mô tả các hoạt động theo cách cú pháp đơn giản và thậm chí để xác định các ngôn ngữ dành riêng cho miền được nhúng trong mã C ++ của bạn.
  7. Tên có phạm vi: không gian tên, lớp / cấu trúc, hàm, v.v. có các quy tắc đơn giản để đảm bảo tên không bị xung đột.
  8. Hệ thống ngoại lệ: một cách để truyền bá lỗi thường tốt hơn mã trả về. Trong thực tế, mã trả về là tốt cho các lỗi logic cụ thể của miền, vì ứng dụng phải quản lý nó. Các ngoại lệ được sử dụng cho các lỗi "cứng", những điều làm cho đoạn mã sau không chính xác. Nó cho phép bắt lỗi cao hơn trong ngăn xếp cuộc gọi nếu có thể, phản ứng với ngoại lệ đó (bằng cách đăng nhập hoặc sửa trạng thái) và với RAII, nếu được sử dụng tốt, nó sẽ không làm cho toàn bộ chương trình bị sai - nếu được thực hiện tốt, một lần nữa.
  9. Thư viện chuẩn: C có cái riêng, nhưng tất cả đều "động". Thư viện chuẩn C ++ hầu như (không phải luồng IO) được tạo từ các mẫu (bộ chứa và thuật toán) cho phép tạo mã chỉ cho những gì bạn sử dụng. Tốt hơn: vì trình biên dịch phải tạo mã, nó sẽ biết rất nhiều về bối cảnh và sẽ nhanh chóng áp dụng rất nhiều tối ưu hóa mà không phải yêu cầu bộ mã hóa làm xáo trộn mã của nó - nhờ vào các mẫu và những thứ khác.
  10. const-đúng: Cách tốt nhất để đảm bảo bạn không thay đổi các biến bạn không nên. Cho phép chỉ định quyền truy cập chỉ đọc vào các biến. Và nó chỉ được kiểm tra tại thời gian biên dịch nên không có chi phí thời gian chạy.

31

C ++ được phát minh để quản lý sự phức tạp mà C không thể xử lý. Ví dụ, một vấn đề phổ biến với C là bạn có thể "hết tên cho các biến" (tất nhiên không được hiểu theo nghĩa đen) vì không có sự đóng gói, không gian tên, v.v.

Ngoài ra, C không có ngoại lệ, do đó việc xử lý lỗi rất dễ xảy ra lỗi, vì nó phụ thuộc vào người dùng thư viện để luôn kiểm tra giá trị trả về của funcs, trong khi với ngoại lệ, nhà phát triển thư viện chỉ cần ném một ngoại lệ để đảm bảo luồng chương trình sẽ bị tạm dừng.

C ++ giúp bằng cách có các đối tượng init constructor được trình biên dịch tự động gọi. Không giống như các cấu trúc C cần được khởi tạo bởi người lập trình (do đó, một khu vực dễ bị lỗi khác).

Cuối cùng, có rất nhiều lợi thế khác được OOP chào mời, chẳng hạn như tái sử dụng đối tượng cũng như các khái niệm dựa trên lập trình chung, chẳng hạn như các mẫu và tổng quát cho phép bạn sử dụng lại mã nguồn, v.v.

Và rất nhiều thứ khác sẽ mất quá nhiều thời gian của tôi để liệt kê ở đây.


Tôi thích rằng bạn viết về hàm tạo C ++ so với các cấu trúc C và nó dễ bị lỗi. Tôi đồng ý với điều đó. Nhưng tôi không thích cách sử dụng Java này trong JavaBeans, nó luôn sử dụng một hàm tạo trống và sau đó đặt các trường thành viên bằng setters. Theo quan điểm của tôi, đó là lỗi dễ xảy ra như các cấu trúc C. Tôi chỉ muốn đặt các Đối tượng Java của mình với hàm tạo. Xem câu hỏi của tôi trên StackOverflow về điều này.
Jonas

Bạn có một điểm ở đó, nhưng trọng tâm của câu trả lời của tôi ở đây là C so với C ++.
Jas

1
Ồ, thôi nào, ai ngăn bạn sử dụng OOP với C? Bạn có thể tái sử dụng các đối tượng và làm bất cứ điều gì, thậm chí ngoại lệ. Thậm chí còn có một cuốn sách về nó, được gọi là lập trình OOP trong C.

2
@Vlad, không có gì bạn đang nói là một lựa chọn 25 năm trước.
Jas

4
Bạn CÓ THỂ thực hiện OOP trong gần như mọi ngôn ngữ lập trình vẫn được sử dụng, nhưng điều đó không có nghĩa là ngôn ngữ được thiết kế cho nó. Lấy Lua làm ví dụ. Mặc dù về mặt kỹ thuật cho phép OOP, có vẻ như có khoảng năm mươi cách làm khác nhau, một nguyên nhân gây ra nhiều đau đầu.
tyjkenn

15

Nói chung, mọi thứ tồn tại trong C đều được hỗ trợ trong C ++. Rõ ràng điều ngược lại là hoàn toàn sai.

Nói một cách đơn giản, C ++ là hướng đối tượng (vì vậy, ví dụ, bạn có các lớp), C thì không.

C ++ có kiểu C89 boolean không.

Chúng là những ngôn ngữ khác nhau. Họ chỉ chia sẻ hầu hết các cú pháp.


4
C99 có loại Boolean (được đặt tên _Bool, với booltên bí danh).
Jerry Coffin

1
Điều này không đúng. Ví dụ, C99 có long longkiểu dữ liệu không phải là một phần của ISO C ++.
Chinmay Kanchi

11
Err ... C ++ không chỉ hướng đối tượng: bạn có thể sử dụng mô hình hướng đối tượng với C ++ vì ngôn ngữ cung cấp các tính năng cho điều đó, nhưng nó cũng cung cấp các tính năng cho các mô hình khác. Bạn nên đề cập rằng, nó thực sự quan trọng, nó thay đổi mọi thứ. Nếu không, tất cả chúng ta sẽ chuyển sang java ...
Klaim

4
Có nhiều cấu trúc trong C không hoạt động trong C ++.

1
@klez: có - nhưng nó vẫn sai. Mặc dù ANSI ban đầu đã phát triển C89 (không có loại Boolean), nhưng việc phát triển mới hiện được thực hiện bởi ISO và ANSI chấp nhận tiêu chuẩn ISO, do đó, tiêu chuẩn ANSI C hiện tại giống hệt với tiêu chuẩn ISO C hiện tại (có một loại Boolean).
Jerry Coffin

8

C99 có một vài tính năng không tồn tại (ít nhất là ở dạng chính xác) trong C ++ (ví dụ: thành viên mảng linh hoạt, mảng có chiều dài thay đổi, v.v.)

C99 cũng đã thêm rất nhiều vào thư viện không có trong tiêu chuẩn C ++ 98/03; hầu hết điều này đã được thêm vào C ++ 11.

Về mặt định hướng cơ bản, C về cơ bản hỗ trợ lập trình thủ tục có cấu trúc. C ++ hỗ trợ điều đó cũng như lập trình hướng đối tượng, lập trình chung và siêu lập trình (thực hiện tính toán tùy ý tại thời điểm biên dịch). Với C ++ 11, nó thêm một vài bit và phần ít nhất có thể bị nhầm lẫn với hỗ trợ lập trình chức năng (ví dụ: biểu thức lambda). C ++ 14 đã thêm một vài chi tiết, nhưng hầu hết trong số chúng thực sự tiện lợi hơn là bất kỳ thay đổi lớn nào trong định hướng.


1

Cá nhân, tôi nghĩ rằng các mẫu là tính năng quan trọng nhất mà C ++ thêm vào C.


1
Er, làm thế nào về các lớp với thừa kế? Đó là công việc thực sự khó khăn trong C, trong khi rất nhiều Mẫu có thể được thực hiện với Macros tiền xử lý.
JBRWilkinson

4
Các macro tiền xử lý không phải là loại an toàn; đó là sự thay thế văn bản thuần túy, điều này cũng làm cho việc gỡ lỗi khó khăn hơn. Để có được các lớp cơ bản và kế thừa để làm việc không phải là rất nhiều công việc trong C. + bạn có thể tạo mô hình metaobject của riêng mình thay vì bị mắc kẹt với bất cứ điều gì mà nhà thiết kế ngôn ngữ đã chọn cho bạn. Xem, ví dụ, bài viết này: arxiv.org/abs/1003.2547
zvrba

2
Phiếu bầu của tôi sẽ là yếu tố hủy diệt cho tính năng quan trọng nhất C ++ có trên C (thậm chí hơn cả các nhà xây dựng vì khả năng dọn dẹp tuyệt vời của họ).
Thomas Eding

@zvrba #define GENERATE_INTERFACE(T) T T##_func(T x);; (loại) nạp chồng / mẫu an toàn trong C. Tôi đồng ý với Thomas rằng các hàm hủy là một tính năng quan trọng hơn nhiều mà C thiếu. Nhưng các hàm hủy thường ẩn mã quan trọng. Không gian tên (phạm vi) theo tôi là quan trọng nhất.
YoYoYonnY
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.