文章目錄
- 1.字符指針變量
- 2. 數組指針變量
- 2.1 數組指針變量初始化
- 3.?維數組傳參的本質
1.字符指針變量
在指針的類型中我們知道有?種指針類型為字符指針 char* ;
?般使?:
int main()
{ char ch = 'w'; char* pc= &ch;//pc的類型是char**pc='w';//對pc解引用 修改ch存放的內容return 0;
}
另一種使用方法:
int main()
{ const char* pc="abcdef";//"abcdef"是常量字符串不可被修改,所以加上const更完整更嚴謹//pc存放的是首字符a的地址//char arr[]="abcdef";//用數組可以被修改//char* pc=arr;printf("%c\n",*pc);printf("%s\n",pc);//按照起始位置打印return 0;
}
代碼const char* pc=“abcdef”;特別容易讓同學以為是把字符串abcdef放到字符指針pc?了,但是本質是把字符串abcdef?字符的地址放到了pc中。
《劍指offer》中收錄了?道和字符串相關的筆試題,我們?起來學習?下:
#include <stdio.h>
int main()
{ char str1[] = "hello bit."; char str2[] = "hello bit."; const char *str3 = "hello bit."; const char *str4 = "hello bit."; if(str1 ==str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"); if(str3 ==str4) printf("str3 and str4 are same\n"); else printf("str3 and str4 are not same\n"); return 0;
}
前置知識:這里比較的是地址,strcmp()才是用來比較字符串的內容
這?str3和str4指向的是?個同?個常量字符串。C/C++會把常量字符串存儲到單獨的?個內存區域,==當?個指針指向同?個字符串的時候,他們實際會指向同?塊內存。==但是?相同的常量字符串去初始化不同的數組的時候就會開辟出不同的內存塊。所以str1和str2不同,str3和str4相同。
2. 數組指針變量
2.1 數組指針變量初始化
? 整形指針變量: int * pint; 存放的是整形變量的地址,能夠指向整形數據的指針。
? 浮點型指針變量: float * pf; 存放浮點型變量的地址,能夠指向浮點型數據的指針。
類比得到數組指針變量應該是:存放的應該是數組的地址,能夠指向數組的指針變量。
那怎么獲得數組的地址呢?就是我們之前學習的&數組名
int arr[10] = {0};
&arr;//得到的就是數組的地址
如果要存放個數組的地址,就得存放在數組指針變量中,如下:
int(*p)[10] = &arr;
我們調試也能看到 &arr 和 p 的類型是一樣的,都是int(*)[10]
演示如下:
int main()
{int arr[10]={0};//arr=&arr[0]是首元素地址//int* p=arr;存的是首元素地址 類型是int*//這里的p是整型指針變量int (* p)[10]=&arr;//取出的是整個數組的地址 類型是int(*)[10]//p是數組指針變量//存放的是數組的地址//p指向的是數組arrreturn 0;
}
解釋:p先和* 結合,說明p是?個指針變量,然后指針指向的是?個??為10個整型的數組。所以p是?個指針,指向?個數組,叫數組指針。
這?要注意:[]的優先級要?于* 號的,所以必須加上()來保證p先和*結合。
數組指針類型解析:
int (*p) [10] = &arr;
| | |
| | |
| | p指向數組的元素個數
| p是數組指針變量名
p指向的數組的元素類型
1.那么如果p指向一個字符指針數組
int main()
{char* arr[5];char* (*p)[5]=&arr;return 0;
}
2.如何用數組指針的到數組的元素
int main()
{int arr[]={1,2,3,4,5,6,7,8,9};int (*p)[10]=&arr;int i=0;for(i=0;i<10;i++){printf("%d ",(*p)[i]);//這里的p相當于&arr//p是數組指針//*p得到整個數組//(*p)[i]用下標獲得數組的某個元素}return 0;
}
這個方法還是有點復雜,使用簡單的方法就行如下:
int main()
{int arr[]={1,2,3,4,5,6,7,8,9};int* p=arr;int i=0;for(i=0;i<10;i++){printf("%d ",p[i]);}return 0;
}
3.?維數組傳參的本質
有了數組指針的理解,我們就能夠講?下?維數組傳參的本質了。 過去我們有?個?維數組的需要傳參給?個函數的時候,我們是這樣寫的:
#include <stdio.h>
void test(int a[3][5], int r, int c)
{ int i = 0; int j = 0; for(i=0; i<r;i++){for(j=0; j<c;j++){printf("%d ", a[i][j]); } printf("\n"); }
}
int main()
{ int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}}; test(arr, 3, 5); return 0;
}
淺淺的補充一個知識
int a[3][5]可以省略行數寫成int a[][5]//因為電腦得到的是地址,不會真的創建一個二維數組,寫清楚行數是使你自己知道,地址還是一個挨著一個存放
這?實參是?維數組,形參也寫成?維數組的形式,那還有什么其他的寫法嗎?
?先我們再次理解?下?維數組,?維數組其實可以看做是每個元素是?維數組的數組,也就是?維數組的每個元素是?個?維數組。那么?維數組的?元素就是第??是個?維數組。
所以,根據數組名是數組?元素的地址這個規則,?維數組的數組名表?的就是第??的地址,是?維數組的地址。根據上?的例?,第??的?維數組的類型就是 int [5] ,所以第??的地址的類型就是數組指針類型 int(*)[5] 。那就意味著?維數組傳參本質上也是傳遞了地址,傳遞的是第??這個?維數組的地址,那么形參也是可以寫成指針形式的。
如下:
#include <stdio.h>
void test(int (*p)[5], int r, int c)//p存放的是一維數組的地址
{ int i = 0; int j = 0; for(i=0; i<r;i++){for(j=0; j<c;j++){printf("%d ", *(*(p+i)+j));//printf("%d ",p[i][j]);//p+i是arr[i]這行的首元素地址,取地址得到首元素,加j跳過j個元素得到arr[i]這行j列元素的地址,再取地址} printf("\n"); }
}
int main()
{ int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}}; test(arr, 3, 5);//實參是二維數組 return 0;
}
總結:?維數組傳參,形參的部分可以寫成數組,也可以寫成指針形式。