รหัสต่อไปนี้ (นำมาจากที่นี่ ):
int* ptr = int();
คอมไพล์ใน Visual C ++ และค่าเริ่มต้นตัวชี้
เป็นไปได้อย่างไร? ฉันหมายถึงint()
ให้วัตถุประเภทหนึ่งint
และฉันไม่สามารถกำหนดให้int
กับตัวชี้ได้
โค้ดข้างบนไม่ผิดกฎหมายได้อย่างไร?
รหัสต่อไปนี้ (นำมาจากที่นี่ ):
int* ptr = int();
คอมไพล์ใน Visual C ++ และค่าเริ่มต้นตัวชี้
เป็นไปได้อย่างไร? ฉันหมายถึงint()
ให้วัตถุประเภทหนึ่งint
และฉันไม่สามารถกำหนดให้int
กับตัวชี้ได้
โค้ดข้างบนไม่ผิดกฎหมายได้อย่างไร?
int()
อัตราผลตอบแทนคุ้มค่าคุ้มค่าสร้างint
(ซึ่งผมคิดว่า C ++ สิ่งที่ระบุ 03) และค่าเริ่มต้นของการมีint
0
เทียบเท่ากับint *ptr = 0;
NULL
อาจเป็นค่าที่ไม่ใช่ศูนย์ ฉันบอกว่ามันอาจเป็นค่าคงที่จำนวนเต็มศูนย์ใด ๆ ก็ได้ (ซึ่งรวมถึงint()
)
คำตอบ:
int()
เป็นนิพจน์คงที่ที่มีค่าเป็น 0 ดังนั้นจึงเป็นวิธีที่ถูกต้องในการสร้างค่าคงที่ของตัวชี้ค่าว่าง ท้ายที่สุดมันเป็นเพียงวิธีการพูดที่แตกต่างกันเล็กน้อยint *ptr = NULL;
nullptr
ซึ่งคุณสามารถใช้แทน0
หรือNULL
ในรหัสใหม่ได้
0
อาจหมายถึงค่าคงที่ของตัวชี้ที่เป็นโมฆะหรือตัวเลข 0 ในขณะที่nullptr
เห็นได้ชัดว่าค่าคงที่ของตัวชี้เป็นโมฆ นอกจากนี้ตามที่ Jamin กล่าวไว้มันยังมี "การตรวจสอบเวลาคอมไพล์พิเศษ" อีกด้วย พยายามคิดก่อนพิมพ์
เนื่องจากint()
ให้ผลตอบแทน0
ซึ่งสามารถใช้แทนกันNULL
ได้ NULL
ตัวเองถูกกำหนดให้เป็น0
ซึ่งแตกต่างจากซีซึ่งเป็นNULL
(void *) 0
โปรดทราบว่านี่อาจเป็นข้อผิดพลาด:
int* ptr = int(5);
และจะยังคงใช้งานได้:
int* ptr = int(0);
0
เป็นค่าคงที่พิเศษและสามารถถือเป็นค่าตัวชี้ได้ นิพจน์คงที่ที่ให้ผล0
เช่น1 - 1
ได้รับอนุญาตเช่นเดียวกับค่าคงที่ของตัวชี้ null
(void *)0
เช่นกัน มันเป็นเพียงการใช้งานที่กำหนดไว้ "นิพจน์คงที่จำนวนเต็มที่มีค่า 0 หรือนิพจน์ดังกล่าวส่งให้พิมพ์เป็นโมฆะ *"
NULL
เป็น(void*)0
; มันเป็นเสมอ0
(หรืออาจจะ0L
) (แต่ตอนนั้น C90 ทำให้(void*)0
ถูกกฎหมายใน C ฉันก็ใช้ C ++ อยู่แล้ว)
#if !defined(__cplusplus) \n #define NULL ((void*)0) \n #else \n #define NULL (0)
เวอร์ชันปัจจุบันของ gcc ใน ubuntu คือ 4.5 ในระบบของเราคือ 4.0
0
เป็นลิเทอรัลพิเศษ" - เพียงเพราะมันเป็นนิพจน์คงที่และมีค่าพิเศษ 0 (1-1)
พิเศษไม่แพ้กันมันยังเป็นค่าคงที่ของพอยน์เตอร์ว่างด้วยเช่นint()
กัน ข้อเท็จจริงของ0
การเป็นตัวอักษรนั้นเพียงพอ แต่ไม่จำเป็นต้องมีเงื่อนไขที่จะเป็นนิพจน์คงที่ บางอย่างเช่นstrlen("")
แม้ว่ามันจะมีค่าพิเศษ0
แต่ก็ไม่ใช่นิพจน์คงที่และด้วยเหตุนี้จึงไม่ใช่ค่าคงที่ของพอยน์เตอร์ว่าง
0
ไม่ใช่ค่า0
ตามตัวอักษร
นิพจน์int()
จะประเมินค่าเป็นจำนวนเต็มที่เริ่มต้นคงที่ซึ่งเป็นค่า 0 ค่านั้นเป็นค่าพิเศษ: ใช้เพื่อเริ่มต้นตัวชี้ไปยังสถานะ NULL
int f() { return 0; }
นิพจน์f()
จะให้ค่า 0 แต่ไม่สามารถใช้เพื่อเริ่มต้นตัวชี้ได้
จาก n3290 (C ++ 03 ใช้ข้อความที่คล้ายกัน) การแปลงตัวชี้ 4.10 [conv.ptr] ย่อหน้าที่ 1 (การเน้นเป็นของฉัน):
1 ค่าคงที่พอยน์เตอร์ว่างคือค่าปริพันธ์ของนิพจน์คงที่ (5.19) ของชนิดจำนวนเต็มที่ประเมินค่าเป็นศูนย์หรือค่า prvalue ของชนิด std :: nullptr_t ค่าคงที่ของพอยน์เตอร์ว่างสามารถแปลงเป็นชนิดตัวชี้ได้ ผลลัพธ์คือค่าตัวชี้ค่าว่างของชนิดนั้นและสามารถแยกแยะได้จากค่าอื่น ๆ ของตัวชี้วัตถุหรือประเภทตัวชี้ฟังก์ชัน การแปลงดังกล่าวเรียกว่าการแปลงตัวชี้โมฆะ [... ]
int()
เป็นค่าปริซึมปริพันธ์คงที่แบบปริพันธ์ของประเภทจำนวนเต็มที่ประเมินค่าเป็นศูนย์ (นั่นคือคำหนึ่ง!) และสามารถใช้เพื่อเริ่มต้นชนิดตัวชี้ได้ อย่างที่คุณเห็น0
ไม่ใช่นิพจน์อินทิกรัลเพียงอย่างเดียวที่ถูกระบุไว้เป็นพิเศษ
int ไม่ใช่วัตถุ
ฉันเชื่อว่าสิ่งที่เกิดขึ้นที่นี่คือคุณกำลังบอกให้ int * ชี้ไปที่ที่อยู่หน่วยความจำที่กำหนดโดย int ()
ดังนั้นถ้า int () สร้าง 0 int * จะชี้ไปที่ที่อยู่หน่วยความจำ 0
int()
แน่นอนที่สุดคือวัตถุ
int()
ได้ กำหนดint i;
แล้วไม่มีคำถามi
คือวัตถุ
int
เป็นประเภทไม่ใช่วัตถุ ไม่ว่าจะint()
ให้ผลตอบแทนเป็นวัตถุหรือเพียงแค่ค่า r ก็ไม่ส่งผลกระทบต่อสิ่งใด ๆ ที่ใคร ๆ กล่าวไว้