ฉันต้องการเข้าใจการเชื่อมโยงภายนอกและการเชื่อมโยงภายในและความแตกต่าง
ฉันยังต้องการทราบความหมายของ
constการเชื่อมโยงตัวแปรภายในโดยค่าเริ่มต้นเว้นแต่จะประกาศเป็นexternอย่างอื่น
ฉันต้องการเข้าใจการเชื่อมโยงภายนอกและการเชื่อมโยงภายในและความแตกต่าง
ฉันยังต้องการทราบความหมายของ
constการเชื่อมโยงตัวแปรภายในโดยค่าเริ่มต้นเว้นแต่จะประกาศเป็นexternอย่างอื่น
คำตอบ:
เมื่อคุณเขียนแฟ้มการดำเนินงาน ( .cpp, .cxxฯลฯ ) คอมไพเลอร์ของคุณสร้างหน่วยการแปล นี่คือไฟล์ต้นฉบับจากการนำไปใช้ของคุณรวมถึงส่วนหัวทั้งหมดที่คุณ#includeมี
การเชื่อมโยงภายในหมายถึงทุกอย่างเพียง แต่อยู่ในขอบเขตของหน่วยการแปล
การเชื่อมโยงภายนอกหมายถึงสิ่งที่มีอยู่นอกเหนือหน่วยแปลเฉพาะ กล่าวอีกนัยหนึ่งสามารถเข้าถึงได้ผ่านโปรแกรมทั้งหมดซึ่งเป็นการรวมกันของหน่วยการแปลทั้งหมด (หรือไฟล์วัตถุ)
constตัวแปร (เช่นเดียวกับจุดประสงค์) ที่นี่พลาดโดยสิ้นเชิง
                    ดังที่dudewat กล่าวว่าการ เชื่อมโยงภายนอกหมายถึงสัญลักษณ์ (ฟังก์ชั่นหรือตัวแปรทั่วโลก) สามารถเข้าถึงได้ตลอดทั้งโปรแกรมของคุณและการเชื่อมโยงภายในหมายความว่าสามารถเข้าถึงได้ในหน่วยการแปลเดียวเท่านั้น
คุณสามารถควบคุมการเชื่อมโยงของสัญลักษณ์ได้อย่างชัดเจนโดยใช้externและstaticคำหลัก หากไม่ได้ระบุการเชื่อมโยงการเชื่อมโยงเริ่มต้นจะใช้externสำหรับconstสัญลักษณ์ที่ไม่ใช่และstatic(ภายใน) สำหรับconstสัญลักษณ์
// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static
// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static โปรดทราบว่าแทนที่จะใช้staticสำหรับการเชื่อมโยงภายในจะเป็นการดีกว่าที่จะใช้เนมสเปซที่ไม่ระบุชื่อซึ่งคุณสามารถใส่classes การเชื่อมโยงสำหรับเนมสเปซนิรนามมีการเปลี่ยนแปลงระหว่าง C ++ 98 และ C ++ 11 แต่สิ่งสำคัญคือพวกเขาไม่สามารถเข้าถึงได้จากหน่วยการแปลอื่น ๆ
namespace {
   int i; // external linkage but unreachable from other translation units.
   class invisible_to_others { };
}externประกาศให้ตรงกันในไฟล์อื่นstaticประกาศด้วยคำหลัก ตัวแปรดังกล่าวจะกล่าวว่ามีการเชื่อมโยงภายในลองพิจารณาตัวอย่างต่อไปนี้:
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}fประกาศfว่าเป็นฟังก์ชั่นที่มีการเชื่อมโยงภายนอก (เริ่มต้น) คำจำกัดความของคำนิยามจะต้องระบุไว้ในภายหลังในไฟล์นี้หรือในหน่วยการแปลอื่น (ที่ระบุด้านล่าง)maxถูกกำหนดให้เป็นค่าคงที่จำนวนเต็ม เชื่อมโยงเริ่มต้นสำหรับค่าคงที่เป็นภายใน externการเชื่อมโยงของมันจะเปลี่ยนไปภายนอกที่มีคำหลัก ดังนั้นตอนนี้maxสามารถเข้าถึงได้ในไฟล์อื่นnถูกกำหนดให้เป็นตัวแปรจำนวนเต็ม เชื่อมโยงเริ่มต้นสำหรับตัวแปรที่กำหนดไว้นอกร่างกายของฟังก์ชั่นภายนอก#include <iostream>
using namespace std;
extern const int max;
extern int n;
static float z = 0.0;
void f(int i)
{
    static int nCall = 0;
    int a;
    //...
    nCall++;
    n++;
    //...
    a = max * z;
    //...
    cout << "f() called " << nCall << " times." << endl;
}maxมีการประกาศว่าจะมีการเชื่อมโยงภายนอก คำจำกัดความที่ตรงกันสำหรับmax(พร้อมลิงก์ภายนอก) จะต้องปรากฏในไฟล์บางไฟล์ (เช่นเดียวกับใน 1.cpp)nมีการประกาศว่าจะมีการเชื่อมโยงภายนอกzถูกกำหนดเป็นตัวแปรระดับโลกที่มีการเชื่อมโยงภายในnCallระบุว่าจะเป็นตัวแปรที่ยังคงความคุ้มค่าคุ้มข้ามสายไปยังฟังก์ชั่นnCall f()แตกต่างจากตัวแปรโลคัลที่มีคลาสหน่วยเก็บข้อมูลอัตโนมัติที่เป็นค่าเริ่มต้นnCallจะถูกกำหนดค่าเริ่มต้นเพียงครั้งเดียวเมื่อเริ่มต้นโปรแกรมและไม่ใช่หนึ่งครั้งสำหรับการเรียกใช้แต่ละf()ครั้ง ตัวระบุคลาสหน่วยเก็บข้อมูลstaticมีผลกับอายุการใช้งานของตัวแปรโลคัลและไม่ใช่ขอบเขตหมายเหตุ:คำหลักstaticมีบทบาทสองเท่า เมื่อนำมาใช้ในคำจำกัดความของตัวแปรโลกจะระบุการเชื่อมโยงภายใน เมื่อใช้ในคำจำกัดความของตัวแปรท้องถิ่นมันระบุว่าอายุการใช้งานของตัวแปรจะเป็นระยะเวลาของโปรแกรมแทนที่จะเป็นระยะเวลาของฟังก์ชัน
หวังว่าจะช่วย!
staticอนุญาตให้เริ่มต้นเดี่ยวขี้เกียจ (ซึ่งจะมีประโยชน์หากคุณต้องการวัตถุ Global-ish แต่ต้องควบคุมเมื่อมันถูกสร้างขึ้นเนื่องจากปัญหาเกี่ยวกับคำสั่งการก่อสร้างทั่วโลกและไม่สามารถจัดสรรแบบไดนามิกได้ ใช้newในขณะที่แผนการเริ่มต้นในเชิงลึกเพิ่มเติมอาจเกินสิ่งที่จำเป็นสำหรับวัตถุในคำถามโดยนัยนี่เป็นปัญหาหลักในระบบฝังตัวที่ใช้ C ++)
                    ให้พูดคุยเกี่ยวกับขอบเขตที่แตกต่างใน 'C'
ขอบเขต: โดยทั่วไปแล้วฉันจะเห็นอะไรและไกลเท่าไหร่
ตัวแปรท้องถิ่น: ขอบเขตอยู่ภายในฟังก์ชันเท่านั้น มันอยู่ในพื้นที่สแต็คของ RAM ซึ่งหมายความว่าทุกครั้งที่ฟังก์ชั่นได้รับการเรียกตัวแปรทั้งหมดที่เป็นส่วนหนึ่งของฟังก์ชั่นนั้นรวมถึงข้อโต้แย้งฟังก์ชั่นจะถูกสร้างขึ้นใหม่และจะถูกทำลายเมื่อการควบคุมออกไปจากฟังก์ชั่น (เพราะสแต็กจะถูกลบทิ้งทุกครั้งที่ฟังก์ชันส่งคืน)
ตัวแปรคงที่: ขอบเขตของสิ่งนี้สำหรับไฟล์ มันสามารถเข้าถึงได้ทุกที่ในไฟล์
                ที่มีการประกาศ มันอยู่ในส่วน DATA ของ RAM ตั้งแต่นี้สามารถเข้าถึงได้ภายในไฟล์และด้วยเหตุนี้การเชื่อมโยงภายใน ใด ๆ
                ไฟล์อื่น ๆ ไม่สามารถดูตัวแปรนี้ ในความเป็นจริงคำหลัก STATIC เป็นวิธีเดียวที่เราสามารถแนะนำระดับข้อมูลหรือฟังก์ชั่นบางอย่างที่
                ซ่อนอยู่ใน 'C'
ตัวแปรทั่วโลก: ขอบเขตของสิ่งนี้สำหรับทั้งแอปพลิเคชัน มันเป็นรูปแบบที่สามารถเข้าถึงได้ทุกที่ของแอปพลิเคชัน ตัวแปรทั่วโลกยังอยู่ในส่วนข้อมูลเนื่องจากสามารถเข้าถึงได้ทุกที่ในแอปพลิเคชันและด้วยการเชื่อมโยงภายนอก
โดยค่าเริ่มต้นฟังก์ชั่นทั้งหมดอยู่ในระดับโลก ในกรณีที่คุณต้องการซ่อนบางฟังก์ชั่นในไฟล์จากภายนอกคุณสามารถใส่คีย์เวิร์ด static ให้กับฟังก์ชั่นนั้นได้ :-)
ก่อนที่จะพูดคุยเกี่ยวกับคำถามที่ว่ามันจะดีกว่าที่จะรู้ว่าคำแปลหน่วย , โปรแกรมและบางแนวคิดพื้นฐานของภาษา C ++ (อันที่จริงการเชื่อมโยงเป็นหนึ่งในพวกเขาในทั่วไป) ได้อย่างแม่นยำ นอกจากนี้คุณยังจะต้องรู้ว่าสิ่งที่เป็นขอบเขต
ฉันจะเน้นประเด็นสำคัญบางอย่างโดยเฉพาะ ที่หายไปในคำตอบก่อนหน้า
เชื่อมโยงเป็นทรัพย์สินของเป็นชื่อซึ่งเป็นที่รู้จักจากการประกาศ ชื่อที่ต่างกันสามารถแสดงถึงเอนทิตีเดียวกันได้(โดยทั่วไปคือวัตถุหรือฟังก์ชัน) ดังนั้นการพูดถึงการเชื่อมโยงของเอนทิตี้มักจะเป็นเรื่องไร้สาระเว้นแต่คุณจะแน่ใจว่าเอนทิตีจะถูกเรียกด้วยชื่อที่ไม่ซ้ำจากการประกาศเฉพาะบางอย่างเท่านั้น
หมายเหตุวัตถุเป็นเอนทิตี แต่ตัวแปรไม่ ขณะที่พูดถึงการเชื่อมโยงของตัวแปรจริงๆแล้วชื่อของเอนทิตีที่แสดงแทน (ซึ่งถูกนำเสนอโดยการประกาศเฉพาะ) นั้นเกี่ยวข้อง การเชื่อมโยงของชื่อเป็นหนึ่งในสาม: ไม่มีการเชื่อมโยงการเชื่อมโยงภายในหรือการเชื่อมโยงภายนอก
หน่วยการแปลที่แตกต่างกันสามารถแบ่งปันการประกาศเดียวกันโดยรวมไฟล์ส่วนหัว / ซอร์ส (ใช่เป็นถ้อยคำมาตรฐาน) ดังนั้นคุณอาจอ้างอิงชื่อเดียวกันในหน่วยการแปลที่แตกต่างกัน หากชื่อที่ประกาศมีการเชื่อมโยงภายนอกข้อมูลประจำตัวของเอนทิตีที่อ้างอิงชื่อจะถูกแชร์เช่นกัน หากชื่อที่ประกาศมีการเชื่อมโยงภายในชื่อเดียวกันในหน่วยการแปลที่แตกต่างกันแสดงถึงเอนทิตีที่แตกต่างกัน แต่คุณสามารถอ้างอิงเอนทิตีในขอบเขตที่แตกต่างกันของหน่วยการแปลเดียวกัน หากชื่อไม่มีการเชื่อมโยงคุณก็ไม่สามารถอ้างอิงเอนทิตีจากขอบเขตอื่น ๆ
(อุ๊ปส์ ... ฉันพบสิ่งที่ฉันพิมพ์แล้วค่อนข้างเพียงแค่ใช้ถ้อยคำมาตรฐานซ้ำ... )
นอกจากนี้ยังมีประเด็นที่สับสนอื่น ๆ ซึ่งไม่ได้ครอบคลุมอยู่ในข้อกำหนดภาษา
__attribute__หรือ__declspec) หรือตัวเลือกคอมไพเลอร์และภาพไม่ใช่โปรแกรมทั้งหมดหรือไฟล์อ็อบเจ็กต์ที่แปลจากหน่วยการแปลดังนั้นจึงไม่มีแนวคิดมาตรฐานที่สามารถอธิบายได้อย่างถูกต้อง เนื่องจากสัญลักษณ์ไม่ใช่คำศัพท์เชิงบรรทัดฐานใน C ++ จึงเป็นเพียงรายละเอียดการนำไปใช้งานแม้ว่าส่วนขยายของภาษาถิ่นที่เกี่ยวข้องอาจถูกนำมาใช้อย่างกว้างขวางกฎการเชื่อมโยงของขอบเขต namespace constตัวแปรเป็นสิ่งที่พิเศษ (และโดยเฉพาะอย่างยิ่งแตกต่างกันไปconstวัตถุประกาศในขอบเขตแฟ้มในภาษา C ซึ่งยังมีแนวคิดของการเชื่อมโยงของตัวระบุ) ตั้งแต่ODRจะถูกบังคับใช้โดย C ++ มันเป็นสิ่งสำคัญที่จะให้ไม่เกินหนึ่งนิยามของตัวแปรเดียวกันหรือฟังก์ชั่นที่เกิดขึ้นในโปรแกรมทั้งหมดยกเว้นสำหรับinlineฟังก์ชั่น หากไม่มีกฎพิเศษดังกล่าวconstการประกาศconstตัวแปรที่ง่ายที่สุดด้วย initializers (เช่น= xxx) ในส่วนหัวหรือไฟล์ต้นฉบับ (มักจะเป็น "ไฟล์ส่วนหัว") รวมอยู่ในหลายหน่วยการแปล (หรือรวมอยู่ในหนึ่งหน่วยการแปลมากกว่าหนึ่งครั้ง) แม้จะไม่ค่อยมี) ในโปรแกรมที่จะละเมิด ODR ซึ่งทำให้ใช้งานได้const ไม่สามารถแทนที่มาโครที่มีลักษณะคล้ายวัตถุบางตัวได้
ฉันคิดว่าการเชื่อมโยงภายในและภายนอกใน C ++ให้คำอธิบายที่ชัดเจนและรัดกุม:
หน่วยการแปลหมายถึงไฟล์การนำไปใช้ (.c / .cpp) และไฟล์ส่วนหัว (.h / .hpp) ทั้งหมดที่มี หากวัตถุหรือฟังก์ชั่นภายในหน่วยการแปลนั้นมีการเชื่อมโยงภายในสัญลักษณ์ที่ระบุนั้นจะปรากฏแก่ผู้เชื่อมโยงภายในหน่วยการแปลนั้นเท่านั้น หากวัตถุหรือฟังก์ชั่นมีการเชื่อมโยงภายนอก linker สามารถมองเห็นได้เมื่อประมวลผลหน่วยการแปลอื่น ๆ คำสำคัญคงที่เมื่อใช้ใน namespace ส่วนกลางบังคับให้สัญลักษณ์มีการเชื่อมโยงภายใน คำหลักภายนอกจะส่งผลให้มีสัญลักษณ์ที่มีการเชื่อมโยงภายนอก
คอมไพเลอร์เริ่มต้นการเชื่อมโยงของสัญลักษณ์เช่นนั้น:
ตัวแปรโกลบอลที่ไม่ใช่ const มีการเชื่อมโยงภายนอกโดยค่าเริ่มต้น
ตัวแปรโกลบอล Const มีการเชื่อมโยงภายในโดยค่าเริ่มต้น
ฟังก์ชั่นมีการเชื่อมโยงภายนอกโดยค่าเริ่มต้น
การเชื่อมโยงกำหนดว่าตัวระบุที่มีชื่อเหมือนกันอ้างถึงวัตถุฟังก์ชันหรือเอนทิตีอื่น ๆ แม้ว่าตัวระบุเหล่านั้นจะปรากฏในหน่วยการแปลที่แตกต่างกันหรือไม่ การเชื่อมโยงของตัวระบุขึ้นอยู่กับวิธีการประกาศ การเชื่อมโยงมีสามประเภท:
c ++ เท่านั้น : คุณยังสามารถมีการเชื่อมโยงระหว่าง C ++ และไม่ใช่รหัส c ++ เศษซึ่งเรียกว่าการเชื่อมโยงภาษา
ที่มา: IBM Program Linkage
เป็นพื้น
extern linkage ตัวแปรจะปรากฏในไฟล์ทั้งหมดinternal linkage ตัวแปรจะปรากฏในไฟล์เดียวอธิบาย: ตัวแปร const เชื่อมโยงภายในโดยค่าเริ่มต้นเว้นแต่จะประกาศเป็นอย่างอื่นภายนอก
external linkageconstตัวแปรทั่วโลกคือinternal linkageextern constตัวแปรพิเศษระดับโลกคือexternal linkageวัสดุที่ดีเกี่ยวกับการเชื่อมโยงใน C ++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
ใน C ++
ตัวแปรใด ๆ ที่ขอบเขตไฟล์และที่ไม่ซ้อนอยู่ภายในคลาสหรือฟังก์ชันสามารถมองเห็นได้ตลอดหน่วยการแปลทั้งหมดในโปรแกรม สิ่งนี้เรียกว่าการเชื่อมโยงภายนอกเพราะในเวลาเชื่อมโยงชื่อจะปรากฏแก่ผู้เชื่อมโยงทุกที่ภายนอกหน่วยการแปลนั้น
ตัวแปรทั่วโลกและฟังก์ชั่นสามัญมีการเชื่อมโยงภายนอก
วัตถุคงที่หรือชื่อฟังก์ชั่นที่ขอบเขตไฟล์เป็นหน่วยการแปล ที่เรียกว่าเป็น Internal Linkage
การเชื่อมโยงหมายถึงองค์ประกอบที่มีที่อยู่ในลิงก์ / เวลาโหลดเท่านั้น ดังนั้นการประกาศคลาสและตัวแปรโลคัลไม่มีการเชื่อมโยง