C語言指標的初始化和賦值

2021-06-23 04:08:19 字數 3538 閱讀 6071

**:

1、指標的初始化

指標初始化時,「=」的右運算元必須為記憶體中資料的位址,不可以是變數,也不可以直接用整型位址值(但是int*p=0;除外,該語句表示指標為空)。此時,*p只是表示定義的是個指標變數,並沒有間接取值的意思。

例如:int a = 25;

int *ptr = &a;

int b[10];

int *point = b;   

int *p = &b[0];

如果:int  *p;

*p = 7;

則編譯器(vs2008)會提示the variable 'p' is being used without being initialized.即使用了未初始化的變數p。

因為p是指向7所在的位址,*p = 7給p所指向的記憶體賦值,p沒有賦值,所以p所指向的記憶體位置是隨機的,沒有初始化的。

int k;

int *p;

p = &k;  //給p賦值

*p = 7; //給p所指向的記憶體賦值,即k= 7

2、指標的賦值

int *p;

int a;

int b[1];

p = &a; 

p = b; 

指標的賦值,「=」的左運算元可以是*p,也可以是p。

當「=」的左運算元是*p時,改變的是p所指向的位址存放的資料;

當「=」的左運算元是p時,改變的是p所指向的位址。

陣列的變數名b表示該陣列的首位址,因此p=b;也是正確的

同型別的指標賦值:

int val1 = 18,val2 = 19;

int *p1,*p2;

p1 = &val1;

p2 = &val2;

p1 = p2;   //注意啦,p1指向了val2,而沒有指向val1

備註:字串與指標的初始化和賦值

初始化:

char *cp = "abcdefg"; //這個初始化過程,是將指標cp指向字串的首位址,而並不是傳遞字串的值。因為,在c語言裡面,沒有整體處理乙個字串的機制

賦值:cp = "abcdefg";

*cp=」abcdefg」 ;//錯誤!字串常量傳遞的是它的首位址,不可以通過*cp修改該字串的值,因為該字串為常量,而它只是簡單的將指標指向該字串常量

3、指標常量

在c語言中沒有一種內建(built-in)的方法去表示指標常量,所以當我們使用它的時候通常先寫成整型常量的形式,然後再通過強制型別轉換把它轉換成相應的型別,如:int * , double * , char *等。 所以後面所示的做法是不行的: int *p = 0x12345678 ; 正確的方式應為:int *p = (int *) 0x12345678; 要注意指標中只能存放位址,不能將乙個非0值整型常量表示式或者其他非位址型別的資料賦給乙個指標,原因就在此。在大多數計算機中,記憶體位址確實是以無符號整型數來表示的,而且多以16進製表示,但我們在c語言中不能用整型數去表示位址,只能用指標常量來表示,因為它是被用來賦給乙個指標的。

對於這個賦值問題還可以換乙個角度去理解,在c語言中,使用賦值操作符時,賦值操作符左邊和右邊的表示式型別應該是相同的,如果不是,賦值操作符將試圖把右邊表示式的值轉換為左邊的型別。所以如果寫出int *p = 0x12345678 ; 這條語句編譯器會報錯:'=' : cannot convert from ' const int ' to ' int * ' ,因為賦值操作符左邊和右邊的表示式的型別應該相同,而0x12345678是int型常量,p是乙個指向int型的指標,兩者型別不同,所以正確的方式是:int *p = (int *) 0x12345678 ; 

4、指標初始化補充

ansi c定義了零指標常量的概念:乙個具有0值的整形常量表示式,或者此類表示式被強制轉換為void *型別,則稱為空指標常量,它可以用來初始化或賦給任何型別的指標。也就是說,我們可以將0、0l、'/0'、2–2、0*5以及(void *)0賦給乙個任何型別的指標,此後這個指標就成為乙個空指標,由系統保證空指標不指向任何物件或函式。

ansi c還定義了乙個巨集null,用來表示空指標常量。大多數c語言的實現中null是採用後面這種方式定義的:#define  null  ((void *)0)。

對指標進行初始化時常用的有以下幾種方式:

1.採用null或空指標常量,如:int *p = null;或 char *p = 2-2; 或float *p = 0;

2.取乙個物件的位址然後賦給乙個指標,如:int i = 3;  int *ip = &i;

3.將乙個指標常量賦給乙個指標,如:long *p = (long *)0xfffffff0;

4.將乙個t型別陣列的名字賦給乙個相同型別的指標,如:char ary[100]; char *cp = ary;

5.將乙個指標的位址賦給乙個指標,如:int i = 3;  int *ip = &i;int **pp = &ip;

6.將乙個字串常量賦給乙個字元指標,如:char *cp = 「abcdefg」;

對指標進行初始化或賦值的實質是將位址或同型別

(或相相容的型別

)的指標

在定義它之後最好把它初始化為

null

,並在解引用這個指標時對它進行檢驗

,防止解引用空指標

。另外,為程式中任何新建立的變數提供乙個合法的初始值是乙個好習慣,它可以幫你避免一些不必要的麻煩。

5、void *型指標

ansi c定義了一種void *型指標,表示定義乙個指標,但不指定它指向何種型別的資料。void *型指標作為一種通用的指標,可以和其它任何型別的指標(函式指標除外)相互轉化而不需要型別強制轉換,但不能對它進行解引用及下標操作。c語言中的malloc函式的返回值就是乙個void *型指標,我們可以把它直接賦給乙個其他型別的指標,但從安全的程式設計風格角度以及相容性上講,最好還是將返回的指標強制轉換為所需的型別,另外,malloc在無法滿足請求時會通過返回乙個空指標來作為「記憶體分配失敗」的訊號,所以要注意返回值指標的判空。

6、指向指標的指標

在指標初始化的第5種方式中提到了用乙個指標的位址來初始化乙個指標。回憶一下上一講的內容:指標是一種變數,它也有自己的位址,所以它本身也是可用指標指向的物件。我們可以將指標的位址存放在另乙個指標中,如:

int i = 5000;

int *pi = &i;

int **ppi = π

此時的ppi即是乙個指向指標的指標,下圖表示了這些物件:

i的位址為108,pi的內容就是i的位址,而pi的位址為104,ppi的內容即是pi的位址。對ppi解引用照常會得到ppi所指的物件,所獲得的物件是指向int型變數的指標pi。想要真正地訪問到i.,必須對ppi進行兩次解引用,如下面**所示:

printf("%d", i );

printf("%d", *pi );

printf("%d", **ppi );

以上三條語句的輸出均為5000。

C語言指標的初始化和賦值

1 指標的初始化 指標初始化時,的右運算元必須為記憶體中資料的位址,不可以是變數,也不可以直接用整型位址值 但是int p 0 除外,該語句表示指標為空 此時,p只是表示定義的是個指標變數,並沒有間接取值的意思。例如 int a 25 int ptr a int b 10 int point b i...

C語言指標的初始化和賦值

1 指標的初始化 初看起來,指標的初始化和賦值好像很混亂,又是 又是 時不時又出來乙個陣列。其實總結起來很簡單 int p int a 25 int b 10 int m a int n b int r b 0 指標的定義如上所示,以 打頭的變數代表該變數為指標變數。指標初始化時,的右運算元必須為記...

C語言指標的初始化和賦值

1 指標的初始化 指標初始化時,的右運算元必須為記憶體中資料的位址,不能夠是變數,也不能夠直接用整型位址值 可是int p 0 除外,該語句表示指標為空 此時,p僅僅是表示定義的是個指標變數,並沒有間接取值的意思。比如 int a 25 int ptr a int b 10 int point b ...