1.指標的概念
在計算機中,所有的資料都是存放在儲存器中的。 一般把儲存器中的乙個位元組稱為乙個記憶體單元, 不同的資料型別所占用的記憶體單元數不等,如整型量佔2個單元,字元量佔1個單元等, 在第二章中已有詳細的介紹。為了正確地訪問這些記憶體單元, 必須為每個記憶體單元編上號。 根據乙個記憶體單元的編號即可準確地找到該記憶體單元。記憶體單元的編號也叫做位址。 既然根據記憶體單元的編號或位址就可以找到所需的記憶體單元,所以通常也把這個位址稱為指標。 記憶體單元的指標和記憶體單元的內容是兩個不同的概念。
2.指標是變數
a.指標是乙個變數,指標能夠存值,值為另外乙個變數的位址值(記憶體位址值)
b.系統為指標分配記憶體空間
c.指標有自己的位址
d.指標就像其他變數或常量一樣,在使用之前必須對指標進行宣告。
3.指標的型別和指標所指向的型別
a.指標的型別
從語法的角度看,只要把指標宣告裡的指標名字去掉,剩下的部分就是這個指標的型別,這是指標本身所具有的型別。
例如:(1)int *ptr;
//指標的型別是 int *
(2)char *ptr;
//指標的型別是char *
(3)int **ptr;
//指標的型別是int **
(4)int (*ptr)[3]; //指標的型別是int (*)[3]
(5)int *(*ptr)[4];
//指標的型別是int *(*)[4]
b.指標所指向的型別
當你通過指標來訪問指標所指向的記憶體區時,指標所指向的型別決定了編譯器將把那片記憶體區里的內容當做什麼來看待。
從語法上看,只須把指標宣告語句中的指標名字和名字左邊的指標宣告符「*」去掉,剩下的就是指標所指向的型別。
指標一般形式為: 型別說明符 *變數名;
其中,*表示這是乙個指標變數,變數名即為定義的指標變數名,型別說明符表示本指標變數所指向的變數的資料型別。
例如: int *p1;表示p1是乙個指標變數,它的值是某個整型變數的位址。 或者說p1指向乙個整型變數。至於p1究竟指向哪乙個整型變數, 應由向p1賦予的位址來決定。
4.指標變數的關係運算
指向同一陣列的兩指標變數進行關係運算可表示它們所指陣列元素之間的關係。例如:
pf1==pf2表示pf1和pf2指向同一陣列元素
pf1>pf2表示pf1處於高位址位置
pf1b)
else
if(c>*pmax) pmax=&c;
if(c<*pmin) pmin=&c;
printf("max=%d/nmin=%d/n",*pmax,*pmin);
}......
pmax,pmin為整型指標變數。
輸入提示。
輸入三個數字。
如果第乙個數字大於第二個數字...
指標變數賦值
指標變數賦值
指標變數賦值
指標變數賦值
判斷並賦值
判斷並賦值
輸出結果
5.字串指標變數與字元陣列的區別
用字元陣列和字元指標變數都可實現字串的儲存和運算。 但是兩者是有區別的。在使用時應注意以下幾個問題:
a. 字串指標變數本身是乙個變數,用於存放字串的首位址。而字串本身是存放在以該首位址為首的一塊連續的記憶體空間中並以『/0』作為串的結束。字元陣列是由於若干個陣列元素組成的,它可用來存放整個字串。
b. 對字元陣列作初始化賦值,必須採用外部型別或靜態型別,如: static char st=;而對字串指標變數則無此限制,如: char *ps="c language";
c. 對字串指標方式 char *ps="c language";可以寫為: char *ps; ps="c language";而對陣列方式:
static char st=;
不能寫為:
char st[20];st=;
而只能對字元陣列的各元素逐個賦值。
從以上幾點可以看出字串指標變數與字元陣列在使用時的區別,同時也可看出使用指標變數更加方便。前面說過,當乙個指標變數在未取得確定位址前使用是危險的,容易引起錯誤。但是對指標變數直接賦值是可以的。因為c系統對指標變數賦值時要給以確定的位址。因此,
char *ps="c langage";
或者 char *ps;
ps="c language";都是合法的。
6.常量指標和指標常量
a.常量指標
常量指標是指向常量的指標,指標指向的記憶體位址的內容是不可修改的。
常量指標定義「const int *p=&a;」告訴編譯器,*p是常量,不能將*p作為左值進行操作。但這裡的指標p還是乙個變數,它的內容存放常量的位址,所以先宣告常量指標再初始化是允許的,指標也是允許修改的,例如:
int a=0,b=1;
const int *p; //宣告常量指標p
p=&a; //p指向a
p=&b; //修改指標p讓其指向b,允許
*p=2; //不允許
b.指標常量
指標常量是指標的常量,它是不可改變位址的指標,但可以對它所指向的內容進行修改。
指標常量定義"int *const p=&a;"告訴編譯器,p是常量,不能作為左值進行操作,但允許修改其指向的內容,即*p是可修改的。指標常量必須在宣告的同時對其初始化,不允許先宣告乙個指標常量隨後再對其賦值,這和宣告一般的常量是一樣的,例如:
int a=0,b=1;
int *const p1=&a;
int *const p2; //不允許,必須對其初始化
p2=&b; //不允許,p2是常量不允許作為左值
*p1=2; //允許修改指標*p1的值
6.在使用非全零為空指標內部表達的機器上,null如何定義
跟其他機器一樣:定義為0 (或某種形式的 0)。當程式設計師請求乙個空指標時,無論寫"0"還是「null」,都由編譯器生成適合機器的二進位制表達形式。因此,在空指標的內部表達不為 0的機器上定義null 為 0 跟其他機器一樣合法:編譯器在指標上下文看到的未加修飾的 0 都會生成正確的空指標。
7.如果 null和 0作為空指標常數等價,該用哪乙個?
許多程式設計師認為指標上下文都應該使用null,以表明該值應該被看做指標。另一些人認為用乙個巨集定義 0,只會把事情搞的更複雜,他們傾向於使用未加修飾的 0 。
c程式設計師應該明白,在指標上下文中 null 和 0完全等價,而未加修飾的 0也可以完全接受。任何使用 null的地方都應該看作一種溫和的指標提示,然而程式設計師並不能依靠它來區分指標0 和 整數0。
【最佳實踐】雖然 null和 0具有相同的功能,但建議使用null 替代 0。這種實踐有兩個好處:
a.你可以認為 null的值改變了,比如在使用非零內部空指標的機器上,用null會比 0 有更好的相容性,但事實並非如此。
b.儘管符號常量經常代替數字,以備數字的變化,但這不是null 替代 0 的原因。語言本身確保了原始碼中的 0(用於指標上下文)會生成空指標。null只是用做一種格式習慣。
8.萬能指標void
void指標一般被稱為通用指標或泛指針,它是c語言關於"純粹位址「的一種約定。void指標指向某個物件,但該物件不屬於任何型別。請看下例。
int * ip;
void *p;
在上例中,ip指向乙個整型值,而p指向的物件不屬於任何型別。
在c語言中,任何時候都可以用其他型別的指標來代替void指標,或者用void指標來代替其他型別的指標,並且不需要進行強制轉換。例如,可以把char*型別的指標傳遞給需要void指標的函式。
當進行純粹的記憶體操作時,或者傳遞乙個指向未定型別的指標時,可以使用void指標。void指標也經常用作函式指標。
有些c**只進行純粹的記憶體操作。在較早版本的c語言程式中,這一點是通過字元指標"char*"實現的,但是這容易產生混淆,因為人們不容易判定乙個字元指標究竟是指向乙個字串,還是指向乙個字元陣列,或者僅僅是指向記憶體中的某個位址。
例如,strcpyo函式將乙個字串複製到另乙個字串中,slcpyo函式將乙個字串中的部分內容複製到另乙個字串中。
char *strcpy(char'strl,const char *str2);
char *strncpy(char *strl, const char*str2, siz.e_t n);
memcpyo函式將記憶體中的資料從乙個位置複製到另乙個位置。
void *memcpy(void *addrl, void *addr2,size_t n);
memcpy()函式使用了void指標,以說明該函式只進行純粹的記憶體複製,包括null字元(零位元組)在內的任何內容都將被複製。請看下例。
#include"thingie, h" /*defines struct thingie */
struct thingie * p_src * p_dest;
/ *... * /
memcpy
返回型別可以是任何基本型別和復合型別。
返回指標的函式的用途十分廣泛。事實上,每乙個函式,即使它不帶有返回某種型別的指標,它本身都有乙個入口位址,該位址相當於乙個指標。比如函式返回乙個整型值,實際上也相當於返回乙個指標變數的值,不過這時的變數是函式本身而已,而整個函式相當於乙個「變數」。
舉例:float *find(float pointer,int n) /*定義指標函式*/
學習指標遇到的問題
第乙個問題 上邊這個圖中列印出來的ptr1的位址和 ptr1的位址分別是什麼的位址?我理解的ptr1的位址就是ptr1這個指標變數自己的位址,ptr1的位址就是ptr1這個指標指向的位址,也就是這個程式中urn這個字元陣列的首位址,是這樣嗎?如果我的理解是正確的話,是不是就是代表ptr1 urn 這...
學習中遇到的問題
頂層const和底層const的概念與區別。vector的sort演算法究竟有沒有使用std swap或者自定義型別自己的swap?類中static成員在 初始化?函式的預設引數是引用,用右值初始化時,為什麼必須是const型別?void resize size t n,std string s s...
C 學習中遇到的問題
在c 學習中遇到的問題集中在此,若有高人看見希望給出解決辦法,在日後的學習中本人若找到解決辦法,也在此更新!1 如何實現ipconfig all命令的全部功能 region 另類解法 程式如下 system.diagnostics.process p new system.diagnostics.p...