นี่อาจเป็นคำถามง่าย ๆ แต่ทำไม const char * ไม่จำเป็นต้องระบุที่อยู่หน่วยความจำ
ตัวอย่าง:
const char* a = "Anthony";
และไม่:
const char *a = // Address to const char
เหมือนประเภทอื่น ๆ
นี่อาจเป็นคำถามง่าย ๆ แต่ทำไม const char * ไม่จำเป็นต้องระบุที่อยู่หน่วยความจำ
ตัวอย่าง:
const char* a = "Anthony";
และไม่:
const char *a = // Address to const char
เหมือนประเภทอื่น ๆ
คำตอบ:
คุณสามารถจินตนาการประกาศนี้
const char* a = "Anthony";
วิธีดังต่อไปนี้
const char string_literal[] = "Anthony";
const char *a = string_literal;
นั่นคือคอมไพเลอร์สร้างอาร์เรย์ของตัวอักษรที่มีระยะเวลาการจัดเก็บข้อมูลแบบคงที่ร้านค้าสตริง"Anthony"
และที่อยู่ของตัวอักษรตัวแรกของอาร์เรย์ (เนื่องจากการแปลงโดยนัยของ designators อาร์เรย์จะชี้ไปยังตัวอักษรแรกของพวกเขา) a
ได้รับมอบหมายให้ตัวชี้
นี่คือโปรแกรมสาธิตที่แสดงให้เห็นว่าตัวอักษรสตริงเป็นอาร์เรย์อักขระ
#include <iostream>
#include <type_traits>
decltype( auto ) f()
{
return ( "Anthony" );
}
template <size_t N>
void g( const char ( &s )[N] )
{
std::cout << s << '\n';
}
int main()
{
decltype( auto ) r = f();
std::cout << "The size of the referenced array is "
<< std::extent<std::remove_reference<decltype( r )>::type>::value
<< '\n';
g( r );
return 0;
}
ผลลัพธ์ของโปรแกรมคือ
The size of the referenced array is 8
Anthony
ขนาดของตัวอักษรสตริง (ของอาร์เรย์ที่เก็บสายอักขระตัวอักษร) เท่ากับ8
เพราะสตริงยังรวมถึงยุติศูนย์อักขระ \0'
'
ในโปรแกรมสาธิตการแสดงออก
std::extent<std::remove_reference<decltype( r )>::type>::value
อาจถูกแทนที่ด้วยเพียงการแสดงออก
sizeof( r )
เหตุใด const char จึงไม่ต้องการที่อยู่หน่วยความจำให้ชี้ไปที่ *
มันทำ
C-string เหมือนตัวอักษร
"Anthony"
จะสลายตัวไปยังที่อยู่ของตน 1 เซนต์ตัวอักษร ชอบ BTW; อาร์เรย์ใน C ใด ๆ
const char[8]
(ใน C ++, อาจจะchar [8]
อยู่ใน C, ไม่แน่ใจ) และชอบอาร์เรย์ในตัวทั้งหมดเมื่อใช้มันเป็นค่าที่จะสลายตัวชี้ไปยังองค์ประกอบแรก
char [8]
ใน C: c-faq.com/ansi/strlitnotconst.html
มันต้องการที่อยู่หน่วยความจำและมันก็มีที่อยู่หน่วยความจำ ในตัวอย่างของคุณเป็นเพียงที่อยู่หน่วยความจำของจุดเริ่มต้นของสตริง มันเหมือนกับตัวแปรอาเรย์อื่น ๆ ที่เริ่มต้น ณ เวลาคอมไพล์เช่น "int array [] = {0, 1, 2, 3};"
หากคุณใช้โปรแกรมแก้ไขไบนารีเพื่อดูไฟล์ปฏิบัติการคุณจะเห็นสตริง "Anthony" อยู่ในนั้น หากคุณใส่บรรทัด "printf (" a อยู่ที่% p \ n ", (void *) a);" ในโปรแกรมของคุณจากนั้นรวบรวมและเรียกใช้คุณจะเห็นที่อยู่
"ทำไม
const char*
ไม่ต้องการตัวชี้ไปยังที่อยู่หน่วยความจำ"
ในความเป็นจริงมันไม่จำเป็นต้องมีที่อยู่หน่วยความจำชี้ไปที่
const char* a
หมายความว่าa
เป็นตัวชี้ไปยังตัวอักษรสตริงหรือค่าคงที่ตัวละคร
ตัวชี้เสมอต้องมีที่อยู่ที่จะชี้ไปเพราะมันเป็นธรรมชาติของตัวชี้ไปยังจุดที่จะเป็นวัตถุที่เฉพาะเจาะจงในหน่วยความจำ ดังนั้นa
และตัวชี้อื่น ๆconst char
ก็ทำเช่นกัน
สตริงตัวอักษรชอบ"Hi My Name is Alfred!"
โดยได้รับมอบหมายเช่น:
const char* a;
a = "Hi My Name is Alfred!";
สลายตัวชี้ไปยังที่อยู่ขององค์ประกอบแรกของตัวอักษรสตริง
หมายถึงa
ได้รับมอบหมายจากที่อยู่ขององค์ประกอบแรกของตัวอักษรสตริง"Hi My Name is Alfred!"
ซึ่งสามารถเก็บไว้ที่ใดก็ได้ในหน่วยความจำขึ้นอยู่กับสภาพแวดล้อมการดำเนินการ
มันไม่ได้อยู่ในความสามารถของโปรแกรมเมอร์ที่เก็บสตริงตัวอักษรอย่างแน่นอน การมอบหมายของคุณเป็นเพียงการมอบหมายและจัดการตัวชี้ตามลำดับอย่างเหมาะสมเท่านั้น