慕課網 Linux C語言指標與記憶體 學習筆記

2021-09-20 04:37:20 字數 3174 閱讀 6549

#include void change(int a, int b)

int main()

上述**無法實現a,b數值的交換。

改為指標實現**如下:

#include void change(int *a, int *b)

int main()

3和5可以成功的交換。

需要將實參的位址傳到子函式才能改變實參!(&a,&b)

c語言 int未初始化時,初值為隨機

int變數未初始化的預設初值,和變數的型別有關。

安裝gdb工具:apt-get install gdb

gcc -g main.c -o main.out生成可除錯版本。

gdb ./main.out

*a 取a這個位址的內容

&a 去a這個變數的位址

因為不知道乙個指標指向的資料有多大, 所以需要在宣告乙個指標變數的時候需要明確的型別。

解析:只是傳值,只是change的區域性變數,是實參的備份。

0x表示十六進製制

1個16進製制的數字,就可以表示4位二進位制數字

32根位址匯流排就有2的32次方個狀態

記憶體分配

1byte = 8bit

1位元組 = 8進製位

使用者程式的記憶體空間從高到低又劃分為:

高位記憶體空間分配給作業系統核心使用,低位記憶體空間分配給使用者程式使用。

我們編寫的函式在編譯後存到磁碟,執行程式時,就把源**編譯後的二進位制資料載入到記憶體空間中的**段中。宣告的全域性變數或常量放置在資料段。每次呼叫新的函式,就將新的函式壓入棧區。

64位系統中 只有前48位是給程式設計師使用的。 0x7fffffffffffffff ~ 0x0

#include int global = 0;

int rect (int a,int b)

int quadrate(int a)

int main()

gdb除錯命令:

變數的本質是什麼?

指標的本質?

指標儲存記憶體的位址。

a = 第五個櫃子第二個抽屜。

棧先宣告的位址大,後宣告的位址小,與**段資料段相反。

資料段(data segment)通常是指用來存放程式中已初始化的全域性變數的一塊記憶體區域。資料段屬於靜態記憶體分配。

32位系統指標占用4個位元組, 也就是32個bit,64位系統占用64個bit,也就是8位元組。

64位系統下,指標佔8個位元組,32位 4個位元組。

編譯器優化**,把宣告時不在一起的同一型別變數,放到一起(某種程度上修改了原始碼)

如 宣告 int a ; float b ; int c; 編譯後變數a的位址和c的位址是連在一起的.

cpu在編譯的時候對棧內變數的儲存位址進行優化,他會將型別相同的變數在連續位址中儲存。

位址分配:**,資料段是從下往上分配(先低位址,後高位址),棧是從上往下分配(先高位址,後低位址)

函式中靜態變數,區域性變數區別:

區域性變數在棧(相對資料段而言的高位址)中,而靜態變數在資料段(低位址)中.

所以在多次呼叫函式時,靜態變數不會被重新,初始化. 或者這麼說,靜態變數的生存週期和資料段相同,區域性變數生存時間受呼叫函式時,所屬函式進棧出棧的影響而會重新初始化.

全域性變數和靜態變數都在資料段中,但靜態變數是某個函式特有的.

#include int global = 0;

int rect (int a,int b)

int quadrate(int a)

int main()

(gdb)p *0x7fffffffcc6c

$15 = 1

(gdb) p *0x7fffffffcc70

$17 = 10

(gdb) p *0x7fffffffcc74

$18 =100

可以看出陣列是按順序放置元素的。

指標偏移運算。

p +=3;

把指標往下移三格-整型移動12個位元組

*p =101;

將p指標所指向的值修改為101

p =&a;

讓p再次指向a的位址

p[4] = 101

把指標往下移三格-整型移動12個位元組

p[4]不是p往下面移動了4個位置,而是從p開始的位址往後移動4個位置取值,p指向的位址還是不變的

陣列其實就是個指標常量,指標是指標變數,常量就是不可更改的

int array[2];

int *pa =array;

pa[0]=1;

pa[1]=10;

pa[2]=100;

int a;

scanf("%d",&a);

int main()

因為str3是乙個字元陣列,

gdb的x命令,可以列印位址中的值

scanf可以將輸入存入str或str3,但是不能存入str2

堆和棧記憶體裡才可以寫入(預留空間才可寫入)

而str2是乙個**段變數。不允許寫入。

#include int main()

只會列印出hel,因為prinf列印以/0為結束。

char str1 = "hello";

char str3[5];

str1 = "helloworld";

很有意思 :

string型別輸出遇到/0 結束

char型別輸出遇到/0 繼續輸出.

指標變數char *str2 = "hello",用scanf 向str2中輸入字串出錯,其實也可以這麼理解,指標str2只是指向乙個位址,從這個位址開始寫入"hello",沒有指定記憶體長度,沒有空間去容納字串。記憶體溢位!這個與char str = "hello"不同,str已經有了6個位元組的記憶體空間,

慕課網 Linux C語言結構體 學習筆記

c檔案 i檔案 s檔案 o檔案 可執行檔案 gcc o helloworld.i helloworld.c e e表示只讓gcc執行預處理。vim跳到整個文件底部,命令 c語言常量分為直接常量和符號常量 define 識別符號 常量值 沒有分號 hello.c源 include define r 1...

學習筆記 《Linux C語言指標與記憶體》

vi sample.c以乙個簡單的數值交換為例,引入記憶體概念。include void change int a,int b int main void 編譯 安裝gdb除錯工具 sudo apt get install gdb 編譯gcc g sample.c o sample.out 執行gd...

CSS3 文字與字型 慕課網 學習總結

text overflow用來設定是否使用乙個省略標記 標示物件內文字的溢位。text overflow只是用來說明文字溢位時用什麼方式顯示,要實現溢位時產生省略號的效果,還須定義強制文字在一行內顯示 white space nowrap 及溢位內容為隱藏 overflow hidden 如下 te...