Có một loạt các sự không tương thích xung quanh với độ tuổi (C90 o r trước đó), cũng như một loạt các tính năng thực sự tốt đẹp trong C99 và C11. Đây là tất cả ra khỏi đỉnh đầu của tôi.
// Valid C
int *array = malloc(sizeof(*array) * n);
// Valid C and valid C++, extra typing, it's always extra typing...
int *array = (int *) malloc(sizeof(*array) * n);
// Valid C++
int *array = new int[n];
C99 là tốt đẹp và các lập trình viên C ở khắp mọi nơi nên sử dụng nó
Các tính năng mới trong C99 là rất tốt đẹp cho lập trình nói chung. VLAs và restrict
không (theo ý kiến của tôi) nhắm mục tiêu sử dụng chung, nhưng chủ yếu là để đưa FORTRAN và các lập trình viên số tới C (mặc dù restrict
giúp bộ tự động hóa). Vì bất kỳ chương trình phù hợp nào sử dụng restrict
sẽ vẫn hoạt động chính xác theo cùng một cách (nhưng có thể không nhanh) nếu bạn #define restrict
ở đầu tệp, nó không phải là vấn đề lớn. VLAs là khá hiếm trong tự nhiên có vẻ như.
Thành viên mảng linh hoạt có thể đẹp. Lưu ý rằng chúng KHÔNG giống như các mảng có độ dài thay đổi! Mọi người đã sử dụng thủ thuật này trong nhiều năm, nhưng hỗ trợ chính thức có nghĩa là ít đánh máy hơn và nó cũng cho phép chúng tôi tạo các hằng số lúc biên dịch. (Cách cũ là có một mảng có kích thước 1, nhưng sau đó tính toán kích thước phân bổ là một sự phiền phức thực sự.)
struct lenstr {
unsigned length;
char data[];
};
// compile time constant
const struct lenstr hello = { 12, "hello, world" };
Trình khởi tạo được chỉ định. Tiết kiệm rất nhiều đánh máy.
struct my_struct { int a; char *b; int c; const char *d; };
struct my_struct x = {
.a = 15,
.d = "hello"
// implicitly sets b = NULL and c = 0
};
int hex_digits[256] = { ['0'] = 0, ['1'] = 1, ['2'] = 2, /* etc */ ['f'] = 15 };
Các inline
từ khóa cư xử khác nhau, bạn có thể chọn dịch đơn vị nhận được một phiên bản không-inline của một hàm tuyên bố nội tuyến bằng cách thêm một tuyên bố extern để đơn vị đó.
Chữ hợp chất.
struct point { float x; float y; };
struct point xy_from_polar(float r, float angle)
{
return (struct point) { cosf(angle) * r, sinf(angle) * r };
}
Các snprintf
chức năng có lẽ trong 10 chức năng thư viện hữu ích nhất đầu của tôi trong C. Nó không chỉ thiếu từ C++, nhưng thời gian chạy MSVC chỉ cung cấp một chức năng gọi là _snprintf
, mà không đảm bảo thêm một NUL terminator vào chuỗi. (snprintf
là trong C++ 11, nhưng vẫn vắng mặt thời gian chạy MSVC C.)
cấu trúc Anonymous và đoàn (C11, nhưng GCC mở rộng kể từ mãi mãi) (công đoàn vô danh là rõ ràng trong C + 03, không có hỗ trợ MSVC trong chế độ C):
struct my_value {
int type;
union {
int as_int;
double as_double;
}; // no field name!
};
Như bạn có thể thấy, rất nhiều các tính năng chỉ giúp bạn tiết kiệm rất nhiều cách gõ (literals hợp chất), hoặc thực hiện các chương trình dễ dàng hơn để gỡ lỗi (thành viên mảng linh hoạt) , làm cho nó dễ dàng hơn để tránh những sai lầm (được chỉ định initializers/quên để khởi tạo các lĩnh vực cấu trúc). Đây không phải là những thay đổi mạnh mẽ.
Đối với sự khác biệt ngữ nghĩa, tôi chắc chắn rằng quy tắc bí danh là khác nhau, nhưng hầu hết các trình biên dịch đều tha thứ đủ trong những ngày này tôi không chắc chắn cách bạn xây dựng một trường hợp thử nghiệm để chứng minh. Sự khác biệt giữa C và C++ mà mọi người đạt được là biểu thức sizeof('a')
cũ, luôn là 1 cho C++ nhưng thường là 4 trên hệ thống C 32 bit. Nhưng không ai quan tâm những gì sizeof('a')
là anyway. Tuy nhiên, có một số đảm bảo trong tiêu chuẩn C99 để mã hóa các thực hành hiện có.
Lấy mã sau đây. Nó sử dụng một thủ thuật phổ biến để xác định các loại công đoàn trong C mà không lãng phí thêm dung lượng lưu trữ. Tôi nghĩ rằng đây là ngữ nghĩa hợp lệ C99 và I nghĩ rằng đây là ngữ nghĩa không rõ ràng C++, nhưng tôi có thể sai.
#define TAG_FUNKY_TOWN 5
struct object { int tag; };
struct funky_town { int tag; char *string; int i; };
void my_function(void)
{
struct object *p = other_function();
if (p->tag == TAG_FUNKY_TOWN) {
struct funky_town *ft = (struct funky_town *) p;
puts(ft->string);
}
}
Thật đáng tiếc. Trình tạo mã MSVC đẹp, quá tệ không có giao diện người dùng C99.
C++ 11 có hỗ trợ các mảng có độ dài biến không? C99, vì vậy nếu không, đó là một ví dụ khá tốt. –
http://david.tribble.com/text/cdiffs.htm - rất nhiều trong số đó vẫn còn hợp lệ cho C++ 11. @CodyGray: VLAs không phải là một phần của C++ 11. – Mat
@CodyGray: C++ 11 không hỗ trợ VLA, vì vậy nhận xét của bạn có thể là câu trả lời :) –