รหัสต่อไปนี้ (นำมาจากที่นี่ ):
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 ก็ไม่ส่งผลกระทบต่อสิ่งใด ๆ ที่ใคร ๆ กล่าวไว้