專題一經典問題解析

2021-10-03 15:30:19 字數 3579 閱讀 4187

什麼是符號表?

引用與指標的疑惑

過載的疑惑

c方式編譯的疑惑?

#include int main()

volatie會使編譯器不做任何優化,每次都從記憶體中取值

#include int main()

int main()

#include using namespace std;

int main()

什麼是符號表?

符號表儲存在程式中的哪個地方?

符號表是編譯器在編譯過程中產生的關於源程式中語法符號的資料結構

如常量表、變數名錶、陣列名表、函式名錶等等

符號表是編譯器自用的內部資料結構

符號表不會進入最終產生的可執行程式中

只有用字面量初始化的const常量才會進入符號表

對const常量進行引用會導致編譯器為其分配空間

雖然const常量被分配了空間,但是這個空間中的值不會被使用

使用其它變數初始化的const常量仍然是唯讀變數

使用其它變數初始化的const常量仍然是唯讀變數

#include using namespace std;

int main()

被volatile修飾的const常量不會進入符號表

退化為唯讀變數,每次訪問都從記憶體中取值

const引用的型別與初始化變數的型別

相同:使初始化變數成為唯讀變數

不同:生成乙個新的唯讀變數,其初始值與初始化變數相同

tips:

在編譯期間不能直接確定初始值的const量,都被作為唯讀變數處理。

#include struct sv

;struct sr

;int main()

; sr sr = ; 對int& x進行初始化

printf("&sv = %p\n", &sv);

printf("&sv.x = %p\n", &sv.x);

printf("&sv.y = %p\n", &sv.y);

printf("&sv.z = %p\n", &sv.z);

printf("&sr = %p\n", &sr);

printf("&sr.x = %p\n", &sr.x); //與&sv.x一樣

printf("&sr.y = %p\n", &sr.y);

printf("&sr.z = %p\n", &sr.z);

sv& rsv = sv; //引用就是別名

rsv.x = 4;

rsv.y = 5;

rsv.z = 6;

printf("sv.x = %d\n", sv.x);

printf("sv.y = %d\n", sv.y);

printf("sv.z = %d\n", sv.z);

return 0;

}

指標與引用的區別

指標是乙個變數,其值為乙個記憶體位址,通過指標可以訪問對應記憶體位址中的值

引用只是乙個變數的新名字,所有對引用的操作(賦值,取位址等)都會傳遞到其引用的變數上

指標可以被const修飾成為常量或者唯讀變數

const引用使其引用的變數具有唯讀屬性

指標就是變數,不需要初始化,也可以指向不同的位址

引用天生就必須在定義時初始化,之後無法在引用其它變數

從使用c++語言的角度來看

引用與指標常量沒有任何的關係

引用是變數的新名字,操作引用就是操作對應的變數

從c++編譯器的角度來看

為了支援新概念「引用」必須要乙個有效的解決方案

在編譯器內部,使用指標常量來實現「引用」

因此「引用」在定義時必須初始化

如何理解「引用的本質就是指標常量」?

答案:當進行c++程式設計時,直接站在使用的角度看待引用,與指標毫無關係!

當對c++程式中的一些涉及引用的bug或者「奇怪行為」進行分析時,可以考慮站在c++編譯器的角度看待引用!

c++編譯器對字面量的處理方式

整數型字面量的預設型別為int,占用4個位元組

浮點型字面量的預設型別為double,占用8個位元組

字元型字面量的預設型別為char,占用1個位元組

字串型字面量的預設型別為const char*,占用4個位元組

當使用字面量對變數進行初始化或賦值時

無溢位產生:編譯器對字面量進行預設型別轉換

產生溢位:編譯器會做截斷操作,並產生警告

char c = 2; //不會給警告

char cc = 20000; //會給警告

深入理解過載規則

精確匹配實參

通過預設型別轉換匹配實參

通過預設引數匹配實參

三條規則會同時對已存在的過載函式進行挑選

當實參為變數並能夠精確匹配形參時,不再進行預設型別轉換的嘗試。

當實參為字面量時,編譯器會同時進行精確匹配和預設型別轉換的嘗試。(注意:不同的編譯器有不同的實現,可能有二義性)

#include void func(int a, int b)

void func(int a, char b)

void func(char a, int b)

void func(char a, char b)

int main()

深入理解extern 「c」

extern 「c」告訴編c++譯器將其中的**進行c方式的編譯

c方式的編譯主要指按照c語言的規則對函式名進行編譯

函式名經過編譯後可能與原始碼中的名字有所不同

c++編譯器為了支援過載,函式名經過編譯後會加上引數資訊,因而編譯後的函式名與原始碼中完全不同

c編譯器不會在編譯後的函式名中加上引數資訊

tips:

extern 「c」中的過載函式經過c方式編譯後將得到相同的函式名,因此extern 「c」中不允許過載函式,但extern 「c」中的函式可以與extern 「c」之外的函式進行過載。

深入理解extern 「c」

extern 「c」告訴編c++譯器將其中的**進行c方式的編譯

c方式的編譯主要指按照c語言的規則對函式名進行編譯

函式名經過編譯後可能與原始碼中的名字有所不同

c++編譯器為了支援過載,函式名經過編譯後會加上引數資訊,因而編譯後的函式名與原始碼中完全不同

c編譯器不會在編譯後的函式名中加上引數資訊

深入理解extern 「c」

extern 「c」中的過載函式經過c方式編譯後將得到相同的函式名,因此extern 「c」中不允許過載函式,但extern 「c」中的函式可以與extern 「c」之外的函式進行過載。

#include extern "c"

}void func(const char* s)

int func(int a, int b)

int main()

5 專題一經典問題解析

1 const和引用的疑惑 include int main 2 符號表是編譯器在編譯過程中產生的關於源程式中語法符號的資料結構 如常量表 變數名錶 陣列名表 函式名錶等等 符號表是編譯器自用的內部資料結構 符號表不會進入最終產生的可執行程式中 3 只有用字面量初始化的const常量才會進入符號表 ...

專題一經典問題解析 7

一。const和引用的疑惑 include int main 輸出結果 2.什麼是符號表?符號表是編譯器在編譯過程中產生的關於源程式中語法符號的資料結構。如常量表 變數名錶 陣列名表 函式名錶。符號表是編譯器自用的內部資料結構 符號表不會進入最終產生的可執行程式中。3.上面程式疑惑解答 a。只有用字...

專題一之經典問題解析

一.例項1 const與引用的問題 什麼是符號表?如何才能進入到符號表,成為真正的常量 1 符號表是編譯器編譯過程中產生的資料結構 2 volatile修飾的const常量不會進入到符號表中 如 volatile const int y 2 不會進入符號表中 const引用的型別與初始化變數的型別 ...