“指向指標的指標”的作用和應用
阿新 • • 發佈:2019-01-29
(1)在子函式中修改主函式傳過來的指標的指向
- 比如主函式申明一個指標變數,且不為其分配指向空間(只是指向NULL),然後取該指標變數的地址傳參給子函式;
- 在子函式里根據需要申請一片空間;
- 對傳參解引用後得到原來的指標變數,且把該指標變數指向剛才申請的空間(修改了原來指標的指向,這是本質);
- 從而實現不確定返回值個數的程式設計方法(這是應用);
例子1(本質):
#include<stdio.h> int find(char *s, char src, char **rt)//從s中查詢出src字元所在的位置並在rt中返回。 { int i = 0; while (*(s + i)) { if (*(s + i) == src)//只會出現一次滿足條件,此時將此地址給*rt,即p { * rt = s + i;//這裡修改了p的指向 } i++; } return 0; } int main(void) { char a[10] = "zhuyujia"; char *p=NULL; find(a, 'y', &p);//改變p的指向,在子函式中實現 printf("%s", p); getchar(); getchar(); return 0; } /* //補充: 列印指標的時候,會把指標所指向的內容以及至字串末位的內容都打印出來 #include<stdio.h> int main(void) { char a[10] = "abcdefgff"; char* p = &a[6]; printf("%s", p);//會列印gff getchar(); getchar(); return 0; } */
例子2:
#include <stdlib.h> #include <time.h> #include<stdio.h> /*當然有必須使用二級指標才能解決的情況,如,某個函式的功能是 返回某個問題的計算結果,但是結果資料是不確定個數的值,所以 在呼叫此函式時不知道事先應分配多少空間來儲存返回的資料,此時 的處理辦法就是傳遞一個沒有分配空間的指標的指標(地址)進去, 讓函式自己根據計算的結果分配足夠的空間來儲存結果,並返回, 呼叫者使用了結果後,由呼叫者負責記憶體的釋放,即,大家可能聽說 過的"誰使用(呼叫)誰釋放"之類的話,如下面的程式碼:*/ //返回不定結果個數的計算函式 //引數int **pResult 儲存返回資料的指標的指標 //引數int &count 儲存返回的結果個數 void Compute2(int **pResult, int &count) { //使用隨機數來模擬計算結果數的個數 srand(time(NULL)); count = rand() % 10;//控制個數在10個以內 *pResult = new int[count];//*pResult相當於主函式傳來的pResult指標, //這裡就修改了主函式中的pResult指向,因為還是指標,因此可以指向新開闢的空間 for (int i = 0; i < count; i++) { (*pResult)[i] = rand();//給結果隨即賦值 } } //返回不定結果個數的計算函式(此函式不能返回資料) //引數int *pResult 為儲存返回資料的指標 //引數int &count 為儲存返回的結果個數 void Compute1(int *pResult, int &count) { //使用隨機數來模擬計算結果數的個數 srand(time(NULL)); count = rand() % 10;//控制個數在10個以內 pResult = new int[count]; for (int i = 0; i < count; i++) { pResult[i] = rand();//給結果隨即賦值 } } int main(void) { int *pResult = NULL;//待獲取結果的指標,這裡沒有分配空間大小,因為不知道返回結果的個數 //具體返回的個數在在子函式中確定,此時指標pResult指向也改變了 //這就間接的說明“在子函式中修改主函式傳來的指標”的意圖 //具體的應用就在於返回個數不確定的場景,這是後面程式設計的一個體會點 int count = 0;//返回結果的個數 /* Compute1(pResult,count);//pResult為指標,第二個引數使用引用傳遞, //使用這個函式時,在函式內部分配的記憶體的指標並沒有返回到主函式中 for ( int i = 0 ; i < count ; i++ ) printf("第 %d 個結果為 : %d\n",pResult[i]);//執行了Compute1()函式後,pResult的值還是為NULL delete [] pResult; pResult = NULL; */ Compute2(&pResult, count); //&pResult為指標的地址(即指標的指標),第二個引數使用引用傳遞 for (int i = 0; i < count; i++) printf("第 %d 個結果為 : %d\n", i, pResult[i]); delete[] pResult; pResult = NULL; getchar(); return 0; }
(2)用指標的指標取二維陣列的元素
/* #include<stdio.h //錯誤的做法 int change(char **p) { int i, j; for (i = 0; i < 5; i++) { for (j = 0; *(*(p + i) + j) != '\0'; j++) { printf("%c", *(*(p + i) + j)); } printf("\n"); } return 0; } //若希望賦值,則不能使用指標的指標,要使用陣列進行運算。 int change(char p[][10]) { int i, j; for (i = 0; i < 5; i++) { for (j = 0; p[i][j] != '\0'; j++) { p[i][j] = 'c'; printf("%c", p[i][j]); } printf("\n"); } return 0; } int main(void) { char a[5][10] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" }; change(a); return 0; } */ #include<stdio.h> int change(char **p) { int i, j; for (i = 0; i < 5; i++) { for (j = 0; *(*(p + i) + j) != '\0'; j++)//利用指標的指標取二維陣列的元素 { *(*(p + i) + j) = 'c'; printf("%c", *(*(p + i) + j)); } printf("\n"); } return 0; } int main(void) { char a[5][10] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" }; char *b[5] = { a[0],a[1],a[2],a[3],a[4] };//這樣做讀取和寫入操作都是可以的。 change(b); return 0; }
(3)用指標的指標指向指標陣列
#include<stdio.h>
int change(char **p)
{
int i, j;
for (i = 0; i < 5; i++)
{
for (j = 0; *(*(p + i) + j) != '\0'; j++)//利用指標的指標取二維陣列的元素
{
*(*(p + i) + j) = 'c';
printf("%c", *(*(p + i) + j));
}
printf("\n");
}
return 0;
}
int main(void)
{
char *a[5] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" };//如果想使用 需使用指標陣列即*a[5] 宣告一個有五個字串指標的陣列。
//但是由於每個元素都是指標字串,所以只能夠讀取,而不能夠寫入。
change(a);
return 0;
}