1. 程式人生 > >指標 記憶體中的五大區域

指標 記憶體中的五大區域

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*)
```