天天看點

C指針之指針帶來的一些符号的了解

指針帶來的一些符号的了解

  • 我們寫的代碼是給編譯器看的,代碼要想達到你想象的結果,就必要編譯器對你的代碼的了解和你自己對代碼的了解一樣。編譯器了解代碼就是了解的符号,是以我們要正确了解C語言中的符号,才能像編譯器一樣思考程式、了解代碼。

星号*

  • (1)C語言中*可以表示乘号,也可以表示指針符号。這兩個用法是毫無關聯的,隻是恰好用了同一個符号而已。
  • (2)星号在用于指針相關功能的時候有2種用法:
    • 第一種是指針定義時,*結合前面的類型用于表明要定義的指針的類型;
    • 第二種功能是指針解引用,解引用時*p表示p指向的變量本身
int *p1;			// *和int結果,表明p的類型是int *,也就是
						// p是指向int類型變量的指針			
int* p2;
int*p3;
int * p4;
           
  • 實際編譯測試,p1到p4都沒有警告,說明4種寫法編譯器認為是一樣的,都是定義了 int *類型的指針p
// 把*和指針變量放在一起,而不是和int挨着,是為了一行定義多個變量時好了解
int *p5, *p6;		// 這樣才是定義了2個int *指針變量p5、p6
int *p5, p6;		// p5是int *指針,p6是int的普通變量
int* p5, p6;		// p5是int *指針,p6是int的普通變量
           
int a = 23;
int b = 0;
// 示範指針變量解引用
int *p;							// *p就是我們說的星号的第一種用法
p = &a;
b = *p;			// b = 23		// *p就是我們說的星号的第二種用法
printf("b = %d.\n", b);
           

取位址符&

  • 取位址符使用時直接加在一個變量的前面,然後取位址符和變量加起來構成一個新的符号,這個符号表示這個變量的位址。
int a;		// &a就表示a的位址。
int *p;
p = &a;	
           
  • 編譯器一看到&a,就知道我們是要把變量a的位址指派給指針變量p,因為變量a的位址是編譯器配置設定的,是以隻有編譯器才知道a的位址。是以我們沒法直接把a的位址的數字指派給p,隻有用符号&a來替代。
  • 了解&a,*p這樣的符号,關鍵在于要明白當&和*和後面的變量結合起來後,就共同構成了一個新的符号,這個新的符号具有一定的意義。

指針定義并初始化、與指針定義然後指派的差別

  • (1)指針定義時可以初始化,指針的初始化其實就是給指針變量初值(跟普通變量的初始化沒有任何本質差別)。
  • (2)指針變量定義同時初始化的格式是:int a = 32; int *p = &a;
  • (3)不初始化時指針變量先定義再指派:int a = 32; int *p;     p = &a;  正确的       *p = &a;    錯誤

左值與右值

  • (1)放在指派運算符左邊的就叫左值,右邊的就叫右值。是以指派操作其實就是:左值 = 右值;
  • (2)左值與右值意義:
    • 當一個變量做左值時,編譯器認為這個變量符号的真實含義是這個變量所對應的那個記憶體空間;
    • 當一個變量做右值時,編譯器認為這個變量符号的真實含義是這個變量的值,也就是這個變量所對應的記憶體空間中存儲的那個數。
  • (3)左值與右值的差別,就好象現實生活中“家”這個字的含義。譬如“我回家了”,這裡面的家指的是你家的房子(類似于左值);但是說“家比事業重要”,這時候的家指的是家人(家人就是住在家所對應的那個房子裡面的人,類似于右值)
int a = 3, b = 5;	
a = b;		// 當a做左值時,我們關心的是a所對應的記憶體空間,而不是其中存儲的3
b = a;		// 當a做右值時,我們關心的是a所對應空間中存儲的數,也就是5