int * i; หรือ int * i; หรือ int * i; [ปิด]


30

อะไรคือวิธีที่คุณชื่นชอบในการประกาศตัวชี้?

int* i;

หรือ

int *i;

หรือ

int * i;

หรือ

int*i;

กรุณาอธิบายว่าทำไม

ดูเพิ่มเติมได้ที่: http://www.stroustrup.com/bs_faq2.html#whitespace


19
ฉันต้องการที่จะมุ่งเน้นไปที่คนอื่น ๆ 3000 เส้น ...

29
int*i;- ช่องว่างไม่เติบโตบนต้นไม้คุณรู้ไหมว่า ...
Shog9

นี่เป็นคำถามเดียวกัน นี่คือคำตอบของฉัน
Keith Thompson

คำตอบ:


75

ถ้าคุณเขียน:

int* i, j, k;

คุณทำให้เข้าใจผิดชี้ให้เห็นว่าทั้งหมดของฉัน j และ k intเป็นตัวชี้ไปยัง

ดังนั้นฉันจึงขอยืนยันว่ามันยอดเยี่ยมกว่าที่จะผนวก * กับชื่อตัวแปร


35
และฉันขอแนะนำint * i;ว่าไม่ใช่นักแข่งขันเท่านั้นเพราะมันดูเหมือนการคูณอย่างรวดเร็ว
John K

1
+1 เพราะฉันไม่ได้พิจารณาสถานการณ์นี้มาก่อน
ปรากฏ

4
"คุณแนะนำให้เข้าใจผิดว่า i, j และ k ทั้งหมดเป็นตัวชี้ไปยัง int" นอกจากว่าคุณกำลังเขียน C # ซึ่งint*ถูกมองว่าเป็นประเภทและint* i, jประกาศตัวชี้สองตัว คำถามอาจถูกพิจารณาว่าไม่สมบูรณ์ - ขึ้นอยู่กับภาษาที่คุณใช้ซึ่งรูปแบบนั้นเหมาะสม ใน CI ติดตามint *xใน C # ฉันทำอย่างอื่น
Joren

1
@Joren: ขออภัยที่ไม่ได้เป็นโปรแกรมเมอร์ C # ฉันเพียงแค่คิดโดยดูที่ส่วนรหัสในคำถามคือ C หรือ C ++
Randall Schulz

ฉันคิดว่ามันสมเหตุสมผลอย่างสมบูรณ์ที่จะสมมติว่า C หรือ C ++ เว้นแต่ว่า C # จะกล่าวถึงโดยเฉพาะ ไม่มีใครเห็นพอยน์เตอร์ใน C # บ่อยนัก
ทางเลือก

62

ฉันชอบint* iเพราะiมีประเภท "ตัวชี้ไปยัง int" และฉันรู้สึกว่ามันทำให้มันเหมือนกันกับระบบประเภท แน่นอนว่าพฤติกรรมที่เป็นที่รู้จักนั้นเกิดขึ้นเมื่อพยายามกำหนดพอยน์เตอร์หลาย ๆ ตัวในหนึ่งบรรทัด (คือต้องใส่เครื่องหมายดอกจันก่อนชื่อตัวแปรแต่ละตัวในการประกาศพอยน์เตอร์) แต่ฉันก็ไม่ได้ประกาศพอยน์เตอร์ด้วยวิธีนี้ นอกจากนี้ฉันคิดว่ามันเป็นข้อบกพร่องที่รุนแรงในภาษา C-style


8
ฉันก็ทำตามอนุสัญญานี้ด้วย ด้วยเหตุผลเดียวกัน
gablin

5
โดยส่วนตัวถ้าฉันประกาศตัวชี้หลายตัวในรหัสของฉันฉันถือว่ามันเป็นกลิ่นรหัส ฉันไม่ต้องการตัวชี้จำนวนมาก และโดยปกติแล้วฉันทำไม่ได้ ดังนั้นปัญหาของการประกาศหลายรายการในบรรทัดเดียวไม่เคยเกิดขึ้นในรหัสใด ๆ ที่ฉันเขียน: การประกาศหนึ่งรายการต่อบรรทัด
greyfade

5
ปัญหานี้คือประเภทไม่ได้เป็น "ตัวชี้ไปยัง int" C (และ C ++) ไม่มีประเภทตัวชี้ มันเป็นตัวชี้ไปยังบล็อกของหน่วยความจำซึ่งเป็นประเภท int
Billy ONeal

10
ฉันจะยืนยันว่ามีประเภทของ*i int
ทิมกู๊ดแมน

5
@Billy: ถ้าเป็นเช่นนั้นฉันไม่เคยเห็นความสับสนในช่วง 12 ปีของการพยายามที่จะเข้าใจแยกวิเคราะห์และอธิบายมาตรฐาน "ตัวชี้ไปยัง int" เป็นประเภทที่ถูกต้องสมบูรณ์ใน C และ C ++

23

สำหรับ C ที่เราไม่ได้มุ่งเน้นที่ประเภทฉันชอบ:

int *i;

เพราะมันมีการเน้นที่intไม่ใช่ตัวชี้ คือintอะไร *iเป็น int


2
จุดดี. ด้วยพอยน์เตอร์คุณสามารถนึกถึงจุดเริ่มต้นว่าเป็นส่วนหนึ่งของชื่อ ตัวอย่างเช่นถ้าคุณมีint i = 5ที่จะได้รับค่าของคุณใช้ชื่อi iในทำนองเดียวกันถ้าคุณมีแล้วจะได้รับค่าที่คุณใช้int *i; *i = 5 *i
mipadi

ฉันอ่าน int * i เป็น: * ฉันเป็น int ดังนั้นฉันจึงเป็นตัวชี้ไปยัง int การประกาศตัวแปรใน C ใช้นิพจน์ชนิด int และ * เป็นเพียงตัวดำเนินการ int * i แยกวิเคราะห์เป็น int (* (i)) และตีความตามที่ฉันมีประเภทตัวชี้ไปที่จำนวนเต็ม ถ่าน * p [] แยกวิเคราะห์เป็นถ่าน (* ([] (p))) (เพราะ [] มีลำดับความสำคัญสูงกว่า *) และหมายถึง: p มีประเภทอาร์เรย์ของตัวชี้ไปยังถ่าน
Giorgio

ด้วยเหตุนี้ฉันคิดว่าพวกเขาเลือกที่จะเขียน * ถัดจากตัวแปรเนื่องจาก * เป็นตัวดำเนินการที่ใช้กับมัน
Giorgio

7

ฉันชอบint* iมานานหลายปี อย่างไรก็ตามมีข้อโต้แย้งที่ดีint *iเพราะเมื่อใช้รูปแบบเดิมคุณยังต้องจำกฎการประกาศหลายกฎ:

int* a, *b; // not int* a, b;

เนื่องจากคุณต้องจำกฎนี้คุณจะไม่ได้รับความเรียบง่าย แต่ฉันจะไม่บอกว่ามันซับซ้อนกว่ากัน การหลีกเลี่ยงการประกาศหลายครั้งในหนึ่งบรรทัดเป็นอีกวิธีหนึ่งที่จะบอกว่าคุณจำกฎนี้ได้ ความแตกต่างระหว่างสองสไตล์คือ moot

แม้ว่าฉันจะใช้มัน แต่ก็รู้สึกว่าโง่เล็กน้อยที่จะแกล้งทำไวยากรณ์การประกาศ C ทำงานได้ดีกว่าที่ทำโดยวางเครื่องหมายดอกจันถัดจากประเภทแทนที่จะเป็นตัวแปรที่ถูกผูกไว้ทาง syntactically

ฉันไม่ซื้อลงไปในอันนั้นเน้นประเภทตัวชี้ (สำหรับi) ในขณะที่อีกประเภทเน้นประเภท int (สำหรับ*i) แต่นั่นอาจเป็นไปได้ว่าหลังจาก 15 ปีของการใช้ C และ C ++ มันเป็นเพียงเมื่อฉันมองที่มันโดยไม่ต้อง ต้องคิดดูสิ - บางสิ่งที่ผู้เริ่มต้นส่วนใหญ่ถามคำถามนี้ยังทำไม่ได้

ยิ่งไปกว่านั้นฉันยังไม่ชอบมันในการอ่าน / เขียนโค้ดในรูปแบบอื่น ความสอดคล้อง bla bla blah

int * iยังไม่จำเป็นต้องพูดถึง


6

ฉันชอบอันแรก มันเป็นเรื่องธรรมดาเนื่องจากเป็นตัวชี้เป็นส่วนหนึ่งของประเภท

เมื่อฉันใช้ C # มันจัดการประเภทในวิธีที่ง่ายกว่า C ดังนั้นจึงไม่มีปัญหาในการประกาศตัวชี้หลายตัวในคำสั่งเดียวกัน:

int* a, b, c; // three pointers

5

ฉันชอบint* i(C ++ - สไตล์)
ฉันหลีกเลี่ยงการประกาศตัวแปรหลายตัวในข้อความเดียวเนื่องจากความกำกวมของภาพ ( int* i, j)

ดูเพิ่มเติมที่C ++ สไตล์และเทคนิคคำถามที่พบบ่อยของ Bjarne Stroustrupสำหรับเหตุผล


4

หากคุณต้องการประกาศหลายตัวแปร แต่ไม่ต้องการทำเครื่องหมายดอกจันซ้ำ:

template <typename T>
struct pointer_to
{
    typedef T* type;
};

pointer_to<int>::type p1, p2, p3;

(อย่างที่คุณเห็นภายในเทมเพลต struct ฉันชอบint* iสไตล์นี้)

และนี่คือคำตอบทั่วไปเพิ่มเติม:

template <typename T>
struct identity
{
    typedef T type;
};

identity<int*>::type p1, p2, p3;

อันนี้ใช้งานได้กับ "ประเภทที่มีปัญหา" ตัวอย่างเช่นอาร์เรย์และการอ้างอิง:

identity<int[10]>::type a1, a2, a3;

identity<int&>::type r1(*p1), r2(*p2), r3(*p3);

omg, c ++ แสดงสิ่งใหม่ให้ฉันเสมอ :) ขอบคุณ!
Tamás Szelei

1
OMG, C ++ น่ากลัวมาก! typedef int* int_ptrจะได้ทำเคล็ดลับ แน่นอนฉันต้องประกาศ typedef ใหม่สำหรับประเภทของตัวชี้ที่แตกต่างกัน แต่ในทางปฏิบัติจะมีจำนวนเท่าไร แปดอย่างมากที่สุด?
benzado

1
@benzado ในทางปฏิบัติคุณไม่จำเป็นต้องใช้ typedef หรือเทคนิคแฟนซีใด ๆ ที่ฉันแสดงเพราะไม่มีคนที่มีสติประกาศตัวแปรหลายตัวในหนึ่งบรรทัด ยังคงน่าสนใจ
fredoverflow

2
ฉันรู้ว่าฉันกำลังพูดถึงแนวโน้มของโปรแกรม C ++ มากขึ้นเพื่อใช้คุณสมบัติภาษาเพียงเพราะพวกเขาทำได้
benzado

@benzado: !!! ฉันเคยเห็นสิ่งนี้บ่อยมาก!
Giorgio

2

ฉันจะไปint* i;ตั้งแต่ส่วนแรกหมายถึงประเภทตัวแปร (ตัวชี้ไปที่ int) ในขณะที่ส่วนที่สองหมายถึงชื่อ ( i) มันจะไม่ทำให้ความรู้สึกกับผมว่าประเภทคือและชื่อเป็นint *iนอกจากนี้ยังint * i;มีลักษณะเหมือนการคูณให้ฉัน


ไวยากรณ์การประกาศ C ไม่สอดคล้องกันในเรื่องนี้เนื่องจากข้อมูลประเภทสามารถมาหลังตัวระบุได้ง่าย: อาร์เรย์เป็นตัวอย่างที่ชัดเจนที่สุด

@ Roger: ฉันรู้ แต่คำถามนี้เฉพาะเจาะจงเกี่ยวกับการประกาศตัวแปรเดียวและไม่มีอะไรอื่น
Allon Guralnek

ฉันคิดว่ามันอ่านมากไปหน่อย :) วิธีที่ฉันเข้าใจคำถามมันถามถึงสไตล์ที่คุณใช้ทุกที่

@ Roger: คุณอาจจะพูดถูก แต่เป้าหมายของฉันคือตอบคำถามของ OP: "คุณชอบวิธีใดในการประกาศพอยน์เตอร์" เห็นได้ชัดว่าทุกคนมีอิสระที่จะตรวจสอบปัญหาที่นำเสนอในคำถามและได้รับการสนับสนุนแม้ที่นี่ ในฐานะคนที่ไม่ได้พัฒนาใน C / C ++ ฉันรู้สึกว่าทำเช่นนั้นจะหลงทางไกลจากความเชี่ยวชาญของฉัน
Allon Guralnek

2

ในการประกาศผมใช้คุณอ่านมันเป็นint * i;i is a pointer to an integer

ตัวชี้ก่อให้เกิดทั้งประเภทและตัวแปรดังนั้นจึงควรอยู่ตรงกลาง

เป็นเรื่องดีที่จะหลีกเลี่ยงการประกาศหลายสิ่งในบรรทัดเดียวกัน: int * i, j;


1

จริง ๆ แล้วฉันใช้การประชุมทั้งสามในสถานการณ์ที่เฉพาะเจาะจง เมื่อดูแวบแรกฉันดูเหมือนจะไม่ลงรอยกัน แต่ ...

  • int * เมื่อไม่มีการระบุเพื่อเสริมสร้างการมองเห็นว่าไม่มีชื่อ
  • int* intptrในtypedefs และประกาศที่คล้ายกันเพื่อเสริมสร้างภาพให้เห็นว่ามันเป็นส่วนหนึ่งของประเภท ในทำนองเดียวกันกับการประกาศฟังก์ชั่นตัวชี้:(int* (*foo)(int))
  • int *identifierและclass &identifierในฟังก์ชั่นพารามิเตอร์เพื่อเสริมกำลังให้มองเห็นว่าพารามิเตอร์นั้นอาจเป็นพารามิเตอร์ที่เรียกว่า "ออก"
  • const int * const * constเมื่อใดก็ตามที่ผมใช้พันธุ์บ่น
  • int * foo; ในการประกาศในท้องถิ่น

ฉันคิดว่าฉันค่อนข้างมุ่งเน้นการมองเห็น


1

ไม่มีประเภทตัวชี้ใน C! ดังนั้น "int *" จึงไม่มีความหมายอะไรเลย เครื่องหมายดอกจันถูกผูกไว้กับองค์ประกอบที่ถูกต้องเสมอมันเป็นขององค์ประกอบที่ถูกต้องไป "* i" เป็น int และเนื่องจาก * i เป็น int จึงเป็นไปตามที่ i เป็นตัวชี้ไปยัง int นั่นคือเหตุผลเบื้องหลังและนั่นคือสาเหตุที่ "int * i" เป็นทางออกเดียวที่เป็นไปได้ ทุกอย่างอื่นเป็นภาพลวงตา (ซึ่งส่วนใหญ่จะได้รับการแก้ไขโดยอัตโนมัติ) ใน C ++ และ C # นั่นคือสิ่งที่แตกต่าง แต่สำหรับ C มีเพียงพระคัมภีร์เดียว: "เดนนิสเอ็มริตชี่: ภาษาการเขียนโปรแกรม C" Dennis (RIP!) เขียนว่า: "int * i" ไม่จำเป็นต้องถามคำถามนี้


6
"ไม่มีตัวชี้ประเภทใน C" - คุณได้รับความคิดนั้นที่ไหน int*เป็นประเภทตัวชี้
Keith Thompson

-2

ฉันใช้int *iเพราะง่ายกว่าที่จะเห็นว่ามันเป็นตัวชี้ถึงแม้ว่าฉันไม่คิดว่ามันจะเป็นเรื่องสำคัญ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.