指標 記憶體中的五大區域
IOS學習第13天
指標
- 指標為什麼要分型別
1.不管是什麼型別的指標,都是佔8個位元組
2.指標的型別如果不和指向的變數的型別相同的話,那麼通過指標就無法正確的操作指向的變數
通過指標操作變數是,指標變數的型別決定了要操作多少連續位元組的空間
- 多級指標
1.一級指標:
首先是一個指標,儲存了一個普通變數的地址
int num =10;
int *p_num = #
二級指標:
首先是一個指標,儲存了一個一級指標的地址
int num =10;
int *p_num = #
int ** pp_num = &p_num;
100級指標:
首先是一個指標,儲存了一個99級指標的地址
2.n級指標的使用
int num = 10;
int * p_num = #//一級
int ** pp_num = &p_num;//二級
int *** ppp_num = &pp_num;//三級指標
列印num的值
%d用來輸出num
%d用來輸出*p_num
%d用來輸出**pp_num
%d用來輸出***ppp_num;
```
* ** 指標與證書之間的加減法**
1.我們可以宣告1個指標變數指向陣列的元素.通過指標間接的運算元組的元素.
2.陣列名 就是一個地址 它儲存了陣列的首地址,也是陣列第0個元素的地址
int arr[] = {10,20,30,40,50,60,70};
int *p1 = &arr[0];
int *p2 = arr
3.遍歷陣列的三種方式
指標 + 1 === > 指標的值 + sizeof(所指向元素的資料型別)
(int*型別的指標) 0xfff001 + 1 實際上 ==>0xfff005
1>使用指標遍歷陣列的第一種方式. int arr[7] = {10,20,30,40,50,60,70}; int* p1 = &arr[0];//p1指標指向了陣列的第0個元素. // p1+0 p1+1 ...p1+6 for(int i = 0;i < 7;i++){ printf("%d ",*(p1+i)); } 2>使用指標遍歷陣列的第二種方式. int arr[7] = {10,20,30,40,50,60,70}; //arr是陣列名,就是一個地址 儲存了 &num[0] for(int i = 0;i < 7;i++){ printf("%d ",*(arr+i)); } 3>使用指標遍歷陣列的第三種方式. int arr[7] = {10,20,30,40,50,60,70}; int* p1 = arr; for(int i = 0;i < 7;i++){ printf("%d ",*(p++)); //通過p++ 也可以是指標p依次指向所有元素 }
// 以下這種方式不行
// int arr[7] = {10,20,30,40,50,60,70};
// int* p1 = arr;
//
// for(int i = 0;i < 7;i++){
// printf(“%d “,*(arr++));//這裡不行,因為arr是陣列名,陣列名是一個地址,但是這個陣列名儲存的地址是一個常量
// }
注意點:
1.不能給陣列名重新賦值,這個地址是在定義陣列的時候系統分配
2.指標變數+1的本質:指標變數的值+sizeof(指標應該指向的資料的型別)
* 中括弧的本質
1.指標變數後面可以使用中括弧,在中括弧中寫上下標來訪問資料.
2.p1[n],前提p1必須是一個指標
p1[n] <==>*(p1 + n);
3.其實運算元組的資料 使用下標的時候,本質上
int nums[] = {1,2,3,4,5};
nums[3];//4這個數
*(nums + 3);//也是訪問4這個資料
“`
- 儲存指標的陣列
1.儲存指標的陣列: 簡稱 指標de陣列 (陣列指標)
2.申明格式:
資料型別* 陣列名[長度];
int num1 = 10;
int num2 = 100;
int num3 = 1000;
//定義一個數組 儲存了三個變數
int nums[] = {num1,num2,num3};
//定義一個數組 儲存了三個變數的地址
int * p_nums[] = {&num1,&num2,&num3};
// 要訪問 num1的值
printf("num1 = %d\n",num1);
printf("num1 = %d\n",nums[0]);
printf("num1 = %d\n",*(p_nums[0]));
- 指標與指標之間的減法運算
1.指標相減的意義:代表兩個指標指向的變數之間相差多少個單位變數
2.指標相減的前提:這兩個指標必須指向同一個陣列中的元素
字串
- 記憶體中的五大區域
1.不同的區域是來幹嘛的?為什麼要分五個區域?[瞭解]
不管是那1個區域都是來儲存資料的.
不同的資料儲存在不同的區域.方便系統的管理.
2.記憶體中的五大區域?(面試題)
a.棧
儲存區域性變數
b.堆(OC是必須明白)
程式設計師手動的申請指定位元組的空間
c.bss段
未初始化的全域性或者靜態變數
d.DATA段/資料段/常量區/全域性區/靜態區
已初始化的全域性或者靜態變數,或者常量
e.程式碼段
儲存二進位制程式碼
- 儲存字串資料的兩種方式的區別
1). 當他們都是區域性變數的時候.
char name1[] = "jack";//name1儲存在棧,"jack"的每一個字元,存在陣列中的,也就是棧區
char *name2 = "rose";//name2儲存在棧,但是"rose"是存常量區
2). 當他們作為全域性變數的時候.
char name1[] = "jack";//name1儲存在常量區,"jack"每一個字元,都是儲存在陣列中的,也就是常量區
char* name2 = "rose";//name2儲存在常量區,"rose"也是常量區,name2這個指標 指向了"rose"這個字串的首字母的地址
3). 二者還有區別
char name1[] = "jack";
name1[0] = 'U';//可以改的
char* name2 = "rose";
name2[0] = 'R';//不允許,因為"rose"是一個常量
- 字串陣列
“`
1.字串陣列:一個數組,每一個元素是一個字串
2.如何儲存字串陣列?
1>二維的字元陣列: char name[] = “jack”;
char [][20] = {“jack”,”lilei”,”marryluck”,”jackmarrylilei”};
2>一維指標陣列:
char * names[4];//指標陣列中每一元素 是 char*的型別
names[0] = "jack";
names[1] = "lilei";
names[2] = "marryluck";
names[3] = "jackmarrylilei";
char * names[4] = {"jack","lilei","marryluck","jackmarrylilei"};
陣列的長度:sizeof(陣列名)/sizeof(char*)
```