ฉันอ่านหนังสือหลายเล่มที่ C เป็นส่วนย่อยของ C ++
หนังสือบางเล่มบอกว่า C เป็นส่วนหนึ่งของ C ++ ยกเว้นสำหรับรายละเอียดเล็ก ๆ น้อย ๆ
มีกรณีใดบ้างที่โค้ดจะคอมไพล์ใน C แต่ไม่ใช่ C ++
ฉันอ่านหนังสือหลายเล่มที่ C เป็นส่วนย่อยของ C ++
หนังสือบางเล่มบอกว่า C เป็นส่วนหนึ่งของ C ++ ยกเว้นสำหรับรายละเอียดเล็ก ๆ น้อย ๆ
มีกรณีใดบ้างที่โค้ดจะคอมไพล์ใน C แต่ไม่ใช่ C ++
คำตอบ:
หากคุณเปรียบเทียบC89
กับC++
นี่คือสองสิ่ง
int n;
int n; // ill-formed: n already defined
int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]
int b(a) int a; { } // ill-formed: grammar error
struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)
auto a; // ill-formed: type-specifier missing
C99 เพิ่มกรณีอื่น ๆ มากมาย
// ill-formed: invalid syntax
void f(int p[static 100]) { }
// ill-formed: n is not a constant expression
int n = 1;
int an[n];
// ill-formed: fam has incomplete type
struct A { int a; int fam[]; };
// ill-formed: two names for one parameter?
void copy(int *restrict src, int *restrict dst);
typedef;
เป็น TU ตามกฎหมายใน C แต่ไม่ใช่ใน C ++
auto a;
ใช้ได้ในการแก้ไขมาตรฐาน C ++ ใหม่ล่าสุด
a
คืออะไร?
auto x;
ไม่ถูกต้องในการแก้ไขล่าสุด แต่ตัวอย่างเช่นauto x = 0;
คือ ตอนแรกตกใจนิดหน่อย :)
ใน C, มีค่าเท่ากับsizeof('a')
sizeof(int)
ใน C ++ sizeof('a')
มีค่าเท่ากับsizeof(char)
.
'a'
คือint
ไฟล์. ใน C ++ 'a'
คือไฟล์char
.
C ++ มีคำหลักใหม่เช่นกัน ต่อไปนี้เป็นรหัส C ที่ถูกต้อง แต่จะไม่รวบรวมภายใต้ C ++:
int class = 1;
int private = 2;
int public = 3;
int virtual = 4;
มีมากมายเต็มไปหมด เป็นเพียงตัวอย่างง่ายๆ (ควรจะเพียงพอที่จะพิสูจน์ว่า C ไม่ใช่ส่วนย่อยที่เหมาะสมของ C ++):
int* test = malloc(100 * sizeof(int));
ควรคอมไพล์ในภาษา C แต่ไม่ใช่ใน C ++
int*
ควรจะต้องมีนักแสดงอย่างชัดเจนในการ
void *
ซึ่งใน C สามารถกำหนดให้กับชนิดตัวชี้ใดก็ได้และไม่สามารถกำหนด C ++ ให้กับตัวชี้ประเภทอื่นได้
ใน C ++ ถ้าคุณประกาศstruct
, union
หรือenum
ชื่อของมันสามารถเข้าถึงได้ทันทีโดยไม่บ่นใด ๆ
struct foo { ... };
foo x; // declare variable
ในภาษา C จะใช้ไม่ได้เนื่องจากประเภทที่ประกาศอยู่ในเนมสเปซเฉพาะของตัวเอง ดังนั้นคุณต้องเขียน:
struct foo { ... };
struct foo x; // declare variable
สังเกตว่าstruct
มีอยู่ที่บรรทัดที่สอง คุณต้องทำเช่นเดียวกันสำหรับunion
และenum
(โดยใช้คำหลักที่เกี่ยวข้อง) หรือใช้typedef
เคล็ดลับ:
typedef struct { ... } foo;
foo x; // declare variable
ดังนั้นคุณสามารถตั้งชื่อประเภทต่างๆได้หลายประเภทเหมือนกันใน C เนื่องจากคุณสามารถทำให้ไม่ชัดเจน:
struct foo { ... };
typedef enum { ... } foo;
struct foo x;
foo y;
อย่างไรก็ตามใน C ++ แม้ว่าคุณจะสามารถนำหน้าstruct
ชื่อด้วยคำหลักได้struct
ทุกเมื่อที่คุณอ้างอิง แต่เนมสเปซจะถูกรวมเข้าด้วยกันดังนั้นข้อมูลโค้ด C ด้านบนจึงไม่ถูกต้อง ในทางกลับกัน C ++ ให้ข้อยกเว้นโดยเฉพาะเพื่อให้ประเภทและ typedef สำหรับประเภทนั้นมีชื่อเดียวกัน (เห็นได้ชัดว่าไม่มีผลใด ๆ ) เพื่อให้การใช้typedef
เคล็ดลับไม่เปลี่ยนแปลงจาก C
struct
, union
และenum
) ส่วน namespace เดียวกัน ตัวอย่างที่ดีกว่าคือstruct foo { ... }; typedef enum { ... } foo;
นอกจากนี้ยังขึ้นอยู่กับความหลากหลายของ C ที่คุณใช้ Stroustrup ทำให้ C ++ เข้ากันได้มากที่สุดเท่าที่จะทำได้และไม่มีความเข้ากันได้อีกต่อไปโดยมีมาตรฐาน ISO 1989 ANSI และ 1990 และเวอร์ชัน 1995 ไม่เปลี่ยนแปลงอะไรเลย คณะกรรมการ C ไปในทิศทางที่แตกต่างกันเล็กน้อยกับมาตรฐานปี 1999 และคณะกรรมการ C ++ ได้เปลี่ยนมาตรฐาน C ++ ถัดไป (อาจจะออกในปีหน้าหรือมากกว่านั้น) เพื่อให้สอดคล้องกับการเปลี่ยนแปลงบางอย่าง
Stroustrup แสดงรายการความเข้ากันไม่ได้กับ C90 / C95 ในภาคผนวก B.2 ของ "The C ++ Programming Language" รุ่นพิเศษ (ซึ่งเป็นรุ่นที่ 3 พร้อมเนื้อหาเพิ่มเติมบางส่วน):
'a'
เป็นint
ภาษา C char
ใน C ++
ขนาดของ enum อยู่int
ใน C ไม่จำเป็นต้องอยู่ใน C ++
C ++ มี//
ความคิดเห็นที่ท้ายบรรทัด C ไม่มี (แม้ว่าจะเป็นส่วนขยายทั่วไปก็ตาม)
ใน C ++ ที่struct foo {
ทำให้ความหมายfoo
ลงใน namespace โลกในขณะที่ใน C struct foo
ก็จะต้องได้รับการเรียกว่า สิ่งนี้ช่วยให้struct
คำจำกัดความเงาชื่อในขอบเขตภายนอกและมีผลกระทบอื่น ๆ อีกเล็กน้อย นอกจากนี้ C ยังอนุญาตขอบเขตที่ใหญ่กว่าสำหรับstruct
คำจำกัดความและอนุญาตให้ใช้ในการประกาศประเภทผลตอบแทนและประเภทอาร์กิวเมนต์
C ++ นั้นยุ่งยากกว่าเกี่ยวกับประเภทโดยทั่วไป จะไม่อนุญาตให้กำหนดจำนวนเต็มให้กับ an enum
และvoid *
ไม่สามารถกำหนดอ็อบเจกต์ให้กับตัวชี้ประเภทอื่นได้หากไม่มีการร่าย ใน C เป็นไปได้ที่จะระบุค่าเริ่มต้นที่ซ้อนทับ ( char name[5] = "David"
โดยที่ C จะละทิ้งอักขระว่างต่อท้าย)
C89 อนุญาตโดยปริยายint
ในหลายบริบทและ C ++ ไม่ได้ ซึ่งหมายความว่าต้องประกาศฟังก์ชันทั้งหมดใน C ++ ในขณะที่ใน C89 มักเป็นไปได้ที่จะได้รับโดยสมมติว่าint
ทุกสิ่งที่เกี่ยวข้องในการประกาศฟังก์ชัน
ใน C เป็นไปได้ที่จะข้ามจากนอกบล็อกไปสู่ภายในโดยใช้คำสั่งที่มีป้ายกำกับ ใน C ++ สิ่งนี้ไม่ได้รับอนุญาตหากข้ามการเริ่มต้น
C มีความเสรีมากขึ้นในการเชื่อมโยงภายนอก ใน C const
ตัวแปรโกลบอลเป็นโดยปริยายextern
และนั่นไม่เป็นความจริงใน C ++ C อนุญาตให้ประกาศอ็อบเจ็กต์ข้อมูลส่วนกลางได้หลายครั้งโดยไม่มีextern
แต่นั่นไม่เป็นความจริงใน C ++
คีย์เวิร์ด C ++ จำนวนมากไม่ใช่คีย์เวิร์ดใน C หรือ#define
d อยู่ในส่วนหัว C มาตรฐาน
นอกจากนี้ยังมีคุณสมบัติที่เก่ากว่าของ C ที่ไม่ถือว่าเป็นสไตล์ที่ดีอีกต่อไป ใน C คุณสามารถประกาศฟังก์ชันที่มีนิยามอาร์กิวเมนต์หลังรายการอาร์กิวเมนต์ได้ ใน C, การประกาศเช่นint foo()
หมายความว่าfoo()
สามารถใช้จำนวนของประเภทของข้อโต้แย้งใด ๆ ในขณะที่ใน C ++ int foo(void)
มันเทียบเท่ากับ
ดูเหมือนว่าจะครอบคลุมทุกอย่างตั้งแต่ Stroustrup
หากคุณใช้ gcc คุณสามารถใช้คำเตือน-Wc++-compat
เพื่อให้คำเตือนเกี่ยวกับรหัส C ที่น่าสงสัยใน C ++ ได้ไม่ทางใดก็ทางหนึ่ง ปัจจุบันใช้ใน gcc เองและดีขึ้นมากเมื่อเร็ว ๆ นี้ (อาจลองใช้เวอร์ชันต่อคืนเพื่อให้ได้สิ่งที่ดีที่สุด)
(สิ่งนี้ไม่ได้ตอบคำถามอย่างเคร่งครัด แต่ชาวบ้านอาจชอบ)
ความแตกต่างที่ใหญ่ที่สุดเพียงอย่างเดียวที่ฉันคิดคือนี่คือไฟล์ต้นฉบับ C ที่ถูกต้อง:
int main()
{
foo();
}
โปรดทราบว่าฉันไม่ได้ประกาศ foo
ที่ไหนเลย
นอกเหนือจากความแตกต่างของภาษา C ++ นอกจากนี้ยังทำให้การเปลี่ยนแปลงบางอย่างไปยังห้องสมุดที่จะสืบทอดมาจาก C เช่นฟังก์ชั่นบางอย่างกลับมาแทนconst char *
char *
s,C,C89,
และสังเกตว่าเป็นซอร์สไฟล์ C99 ที่ไม่ถูกต้อง
#include <stdio.h>
int new (int n) {
return n/2;
}
int main(void) {
printf("%d\n", new(10));
return 0;
}
ดูเพิ่มเติมc ++ คำถามที่พบบ่อยเข้า
คำตอบจำนวนหนึ่งที่นี่ครอบคลุมความแตกต่างทางไวยากรณ์ที่อาจทำให้คอมไพเลอร์ C ++ ล้มเหลวในซอร์สโค้ด C89 (หรือ C99) อย่างไรก็ตามมีความแตกต่างทางภาษาเล็กน้อยที่ถูกกฎหมายในทั้งสองภาษา แต่จะทำให้เกิดพฤติกรรมที่แตกต่างกัน ความsizeof (char)
แตกต่างที่ Naveen กล่าวถึงเป็นตัวอย่างหนึ่ง แต่เขียนโปรแกรมที่จะพิมพ์ "C" หากคอมไพล์เป็นโปรแกรม C (ANSI) และ "C ++" หากคอมไพล์เป็นโปรแกรม C ++ จะแสดงรายการอื่น ๆ
โดยทั่วไปคอมไพเลอร์ C อนุญาตให้มีการตัดมุมเล็กน้อยที่ C ++ ไม่ทำ C ++ นั้นเข้มงวดกว่า C มากและโดยทั่วไปความแตกต่างเหล่านี้บางส่วนขึ้นอยู่กับคอมไพเลอร์ g ++ อนุญาตบางสิ่งที่คอมไพเลอร์ Intel C ++ ไม่มีเช่น แม้แต่โค้ด C ที่เขียนค่อนข้างดีก็ไม่สามารถคอมไพเลอร์ C ++ ที่ทันสมัยได้
คุณไม่สามารถเปรียบเทียบภาษาด้วยไวยากรณ์เท่านั้น หากคุณทำเช่นนั้นคุณอาจเห็น C เป็นส่วนย่อยของ C ++ ในความคิดของฉันความจริงที่ว่า C ++ คือ OO (และ C ไม่ใช่) ก็เพียงพอที่จะบอกได้ว่า C และ C ++ เป็นภาษาที่แตกต่างกัน