(在 指標與記憶體位址 中提及 :變數(Variable)提供具名稱的記憶體儲存空間,(儲存資訊
包含)一個變數關聯(的)一個資料型態、儲存的值與儲存空間的位址值。所以我們常見的變數
其實也是有包含儲存位址的資訊)
常用符號
符號&,叫作取址運算子(Address-of operator),它可以用來取得變數所在的"記憶體位址"
符號* ,叫作取值運算子(Dereference operator),它可以用來取得變數儲存的"數值"
宣告方式
根據指標的宣告方式,不同的資料型別的指標,宣告方式有些微不同,像是:
int *ptr1; or int* ptr; float *ptr2; char *ptr3;
備註:這邊的*號是指宣告一個指標變數,*靠左靠右都可以,但是
int* ptr1, ptr2;
只有ptr1是指標變數,ptr2是整數變數。若都要宣告,則可以使用
int *ptr1,*ptr2;
使用細節
不像我們可以直接對變數進行操作,因為指標儲存的資訊是變數的位址資訊
如果我們想透過指標對變數進行操作,我們必須透過別的方式才行
這時就要提到指標的另一個特性:Dereference 提取
透過 * (dereference operator) 這個取值運算子,可以用來提取變數資訊
例如
int *ptr1 = &var1;
意思是,原本 ptr 這個指標變數所存的是變數 var1 的位址
*ptr
在前面加了*符號,則能夠將var1的數值給取出來
指標與陣列
觀念澄清: char a[] 跟 char *a 是一樣的嗎???
答案: 是完全不同! 指標跟陣列雖然有相似的地方,但是本質上是不一樣的東西
char a[] = "hello"; char *p = "world";
Q: If they're so different, then why are array and pointer declarations interchangeable as function formal parameters?
指標與字串
演算法作業2需要同時處理指標與字串
來紀錄一下實作的細節部份
前面是getline()所需要使用的基本參數
char *line = NULL; //string pointer size_t len = 0; //unsigned ssize_t read = 0; //signed
line 儲存的是 line[] 的起始位址
這邊則是由 getline() 將字串讀入
read = getline(&line, &len, stdin);
完整的程式碼
//---2017/4/6 #c getline() 使用方法--- #include <string.h> char *line = NULL; //string pointer size_t len = 0; //unsigned ssize_t read = 0; //signed int main(){ read = getline(&line, &len, stdin); while( read != -1){ for(int i=0;i<read-1;i++){ printf("line+%d = %c\n",i,*(line+i)); //一個個的印出line指標指到的字串字元 }; } free(line); //釋放記憶體 }
如果需要一個個的把字元指針 line 所指的字串字元給印出來,這邊需要這樣寫
printf("line+%d = %c\n",i,*(line+i));
這邊的
*(line+i)
取值運算子*取出的是字元指針 line 指向第 i 個元素位址儲存的字元
printf() 的format specifier 需要選用c,寫成c code就變成
%c
如果是%s,它會直接印出一整行,而且後面需要放的是指向字串的指針 line
不是*(line+i)
可以參考這篇 Can a pointer to a string be used in a printf?
底下也有鄉民提到%s接受的格式是字元指針(char *)形式
The "%s" format specifier for printf always expects a char* argument.
segmentation fault(core dump)
如果這樣寫
printf("line+%d = %s\n",i,*(line+i));
gcc編譯過的話,執行到這行時會得到錯誤資訊 segmentation fault(core dump)
原因是因為,%s這邊想要讀取的資料格式是資料的位址
所以我們這邊要放入的變數應該是字元指針變數line
可是今天我們輸入的資料是另一個數值*(line+i),當作字串位址丟進去
程式會訪問到其他不該訪問的程式記憶體位置
於是就發生了segmentation fault(core dump)
----------------------------------------------------------------------------
思考題 Q: *line+(i-1) vs *( line+(i-1) ) 差別在哪?
沒有留言:
張貼留言