ios學習之旅---指針也不難
阿新 • • 發佈:2017-05-25
ror 邏輯 初始化 維數 賦值運算 等價 格式 沒有 本質
4、指針為什麽要區分類型
1、變量的地址是變量所在占存儲空間的首地址
2、指針變量只能夠存儲一個地址編號,假設沒有類型。當通過指針就不知道要訪問多少個字節的存儲空間
3、指針區分類型是為了在通過指針訪問它所指向的存儲空間的時候,可以正確訪問
4、假設通過一個char類型的指針操作一個int的變量,假設值的二進制數據超過1字節,那麽就造成數據錯誤
5、假設通過一個int 類型的指針操作一個char變量,那麽你就會改動了你不該改動的內存。造成程序邏輯錯誤
5、指針運算概述
指針變量:存放是內存字節的地址編號(無符號的整形數)
指針:是運算受限的無符號的整形數
運算運算:
指針 + 整形數 === 指針變量中值 + sizeof(其所指向數據類型)
指針 - 整數數 === 指針變量中值 - sizeof(其所指向數據類型)
pointer1 - pointer2 = (pointer1中值 - pointer2中值) / sizeof(其指向數據類型)
賦值運算:
=
+= 必須是一個整形數
-= 必須是一個整形數
比較運算
==
!=
>
<
>=
<=
自增自減
p++; p = p + 1;
++p; p = p + 1;
--p;
p--;
數組像一個指針:訪問數組中元素。使用數組與使用指向這個數組的指針是等價
nums[1] ==== p[1]
nums+1 ==== p + 1;
nums[1] 的本質 *(nums + 1)
指針 + 整數 ===== 指針中的值 + sizeof(所指向的數據類型) * 整數
// int nums[] = {1,2,3,4,5};
//
// int *p = nums;
double nums[] = {1.0,2.0,3,4,5};
double * p = nums;
// printf("%d,%d,%d,%d,%d,%d\n",nums[1],p[1],*(nums + 1),*(p + 1),*(++p),。);
printf("%p\n",nums);
printf("%p\n",nums+2);
printf("%p\n",p);
printf("%p\n",p+2);
數組不是一個指針
1、sizeof(array) != sizeof(pointer):當一個數組賦值一個指針變量的時候。那麽數組中有些信息就丟失了,比方數組長度。這樣的現象指針信息遺失
2、指針的指向是能夠改變的,數組的指向是不能夠改變
3、array == &array 數組名就是數組地址,pointer != &pointer : 指針所指向地址不是指針本身地址
7、指針與二維數組
指針數組與二維數組指針變量的差別
應該註意指針數組和二維數組指針變量的差別。這兩者盡管都可用來表示二維數組。可是其表示方法和意義是
不同的。
二維數組指針變量是單個的變量。其一般形式中"(*指針變量名)"兩邊的括號不可少。而指針數組類型表示的
是多個指針(一組有序指針)在一般形式中"*指針數組名"兩邊不能有括號。比如:
int (*p)[3];
表示一個指向二維數組的指針變量。
1、認識指針
#include <stdio.h> //基本數據類型作為函數參數傳遞是值傳遞 //void moveFront(int x ,int y) //{ // x = x + 2; //} void test() { // 確定當前坐標 int x = 20; int y = 150; printf("%p\n",&x); printf("%lu\n",&x); *((int *)(0x7fff5fbff76c)) = 22; printf("(%d,%d)\n",x,y); // moveFront(x, y); // printf("(%d,%d)\n",x,y); } //假設你想訪問指針所指向存儲空間,就必須使用訪問指針所指向的存儲空間的操作符 void moveFront(int *x ,int *y) { // x = x + 2;//此時是改變指針的指向,而不是訪問指針所指向的存儲空間 *x = *x + 2; } int main(int argc, const char * argv[]) { // 確定當前坐標 int x = 20; int y = 150; printf("(%d,%d)\n",x,y); moveFront(&x, &y); printf("(%d,%d)\n",x,y); return 0; }
2、指針的定義與初始化(重點掌握)
內存中最小的存儲單元:字節,每個字節在內存中都有一個編號,這編號就是指針
指針:內存地址
有了指針你就有了打開這塊內存鑰匙,就能夠操作這一塊內存
指針變量:存放內存地址的變量
定義指針:指針所指向數據類型 * 指針變量名稱;
在的定義變量時候,*是一個類型說明符,說明定義這個變量是一個指針變量
在不是定義的變量的時候。*是一個操作符,訪問(讀、寫)指針所指向的那塊存儲空
指針的初始化:
註意點:
1、僅僅有定義沒有初始化指針裏面是一個垃圾值,這時候我們成為這個指針為野指針
2、假設操作一個野指針
2.1 程序崩潰
2.2 訪問不該你訪問存儲。操作潛在邏輯錯誤
3、不能夠使用整形常量賦值一個指針變量
由於內存是操作系統分配我們的,不是我們隨便取的
4、什麽類型的指針,僅僅指向什麽類型的變量
5、多個指針能夠指向同一變量
6、指針的指向是能夠改變的
#include <stdio.h> //指針的定義 void test() { int num = 10; // 定義一個指針變量 int *p; p = # *p = 20; printf("num = %d\n",num); } int main(int argc, const char * argv[]) { // 先定義在進行初始化 int num = 10; // 定義一個指針變量p int * p; // *p = # // p 還有進行初始,不可以訪問它所指向存儲空間 p = #//p 指向 num *p = 20; // 定義指針變量的同一時候進行初始 int num2 = 20; int *p2 = &num2; *p2 = 40; printf("%d,%d\n",num2,*p2); // 不可以使用整形常量賦值一個指針變量 // 由於內存是操作系統分配我們的,不是我們隨便取的 // int *p3 = 100000;//此處是錯誤的 // // *p3 = 10; p2 = # printf("%p\n",p2); char c = ‘a‘; int *pc = &c; *pc = 10; printf("%p\n",p2); return 0; }
3、多級指針
通過指針訪問變量稱為間接訪問。
因為指針變量直接指向變量,所以稱為“一級指針”。
而
假設通過指向指針的指針變量來訪問變量則構成“二級指針”。
#include <stdio.h> void test() { int num = 10; int *p = # // 定義一個指針來指向變量p // pp就是一個二級指針 int **pp = &p; **pp = 30; printf("%d\n",num); int ***ppp = &pp; ***ppp = 50; printf("%d\n",num); // 四級指針 int ****pppp = &ppp; ****pppp = 100; printf("%d\n",num); } void readFile(char **error) { *error = "讀取錯誤"; } int main(int argc, const char * argv[]) { // char error[100]; char *error; readFile(&error); printf("%s",error); return 0; }
4、指針為什麽要區分類型
1、變量的地址是變量所在占存儲空間的首地址
2、指針變量只能夠存儲一個地址編號,假設沒有類型。當通過指針就不知道要訪問多少個字節的存儲空間
3、指針區分類型是為了在通過指針訪問它所指向的存儲空間的時候,可以正確訪問
4、假設通過一個char類型的指針操作一個int的變量,假設值的二進制數據超過1字節,那麽就造成數據錯誤
5、假設通過一個int 類型的指針操作一個char變量,那麽你就會改動了你不該改動的內存。造成程序邏輯錯誤
#include <stdio.h> /* 全部指針類型都是占用八個字節的存儲空間 */ void testEveryPointerIs8B() { printf("%lu\n",sizeof(int *)); printf("%lu\n",sizeof(char *)); printf("%lu\n",sizeof(double *)); printf("%lu\n",sizeof(float *)); printf("%lu\n",sizeof(float **)); } int main(int argc, const char * argv[]) { int num = 10; char *cp = # printf("%d\n",num); return 0; }
5、指針運算概述
指針變量:存放是內存字節的地址編號(無符號的整形數)
指針:是運算受限的無符號的整形數
運算運算:
指針 + 整形數 === 指針變量中值 + sizeof(其所指向數據類型)
指針 - 整數數 === 指針變量中值 - sizeof(其所指向數據類型)
pointer1 - pointer2 = (pointer1中值 - pointer2中值) / sizeof(其指向數據類型)
賦值運算:
=
+= 必須是一個整形數
-= 必須是一個整形數
比較運算
==
!=
>
<
>=
<=
自增自減
p++; p = p + 1;
++p; p = p + 1;
--p;
p--;
#include <stdio.h> //算術運算 void test() { int a = 10; int *p = &a; // 指針+1 p = p + 1; int nums[5] = {1,2,3,4,5}; int * pointer1 = nums; int * pointer2 = &nums[4]; size_t size = pointer2 - pointer1; printf("%lu\n",size); // pointer1 + pointer2; // pointer2 * pointer1; // pointer1 / pointer2; // pointer1 / 2; } //賦值運算 void test1() { int a = 10; // int *p = &a; int nums[] = {1,2,3,4,5}; int *p = nums; int *p2 = nums; p += 2; p = p + 2; p -= 1; printf("%d\n",*p); } //關系運算 int main(int argc, const char * argv[]) { int nums[] = {1,2,3,4,5}; int *p = nums; p++; int result = nums == p; result = p > nums; p--; result = p < nums; result = p >= nums; result = p <= nums; printf("%d\n",result); return 0; }6、指針與一維數組(理解)
數組像一個指針:訪問數組中元素。使用數組與使用指向這個數組的指針是等價
nums[1] ==== p[1]
nums+1 ==== p + 1;
nums[1] 的本質 *(nums + 1)
指針 + 整數 ===== 指針中的值 + sizeof(所指向的數據類型) * 整數
// int nums[] = {1,2,3,4,5};
//
// int *p = nums;
double nums[] = {1.0,2.0,3,4,5};
double * p = nums;
// printf("%d,%d,%d,%d,%d,%d\n",nums[1],p[1],*(nums + 1),*(p + 1),*(++p),。);
printf("%p\n",nums);
printf("%p\n",nums+2);
printf("%p\n",p);
printf("%p\n",p+2);
數組不是一個指針
1、sizeof(array) != sizeof(pointer):當一個數組賦值一個指針變量的時候。那麽數組中有些信息就丟失了,比方數組長度。這樣的現象指針信息遺失
2、指針的指向是能夠改變的,數組的指向是不能夠改變
3、array == &array 數組名就是數組地址,pointer != &pointer : 指針所指向地址不是指針本身地址
#include <stdio.h> int main(int argc, const char * argv[]) { int nums[] = {1,2,3,4,5}; int *p = nums; p = nums; // nums = nums + 1; printf("%lu,%lu\n",sizeof(nums),sizeof(p)); printf("%p\n",nums); printf("%p\n",&nums); printf("%p\n",p); printf("%p\n",&p); return 0; }
7、指針與二維數組
指針數組與二維數組指針變量的差別
應該註意指針數組和二維數組指針變量的差別。這兩者盡管都可用來表示二維數組。可是其表示方法和意義是
不同的。
二維數組指針變量是單個的變量。其一般形式中"(*指針變量名)"兩邊的括號不可少。而指針數組類型表示的
是多個指針(一組有序指針)在一般形式中"*指針數組名"兩邊不能有括號。比如:
int (*p)[3];
表示一個指向二維數組的指針變量。
該二維數組的列數為3或分解為一維數組的長度為3。
int *p[3]
表示p是一個指針數組。有三個下標變量p[0],p[1],p[2]均為指針變量。
#include <stdio.h> void test() { int nums[3][2] = {{1,2},{3,4},{5,6}}; int *p = nums[0]; printf("%p\n",p); printf("%p\n",nums); for (int i = 1; i < 6; i++) { printf("%d ",*(p + i)); } } /* 定義指針數組的格式: 數據類型 * 指針變量名稱[指針個數] */ void test2() { int nums[3][2] = {{1,2},{3,4},{5,6}}; // int * p[2] = {nums[0],nums[1]}; // p = nums; // // printf("%d\n",p[0][1]); int a = 10; int b = 20; int c = 30; int *p = &a; // *p === p[1]; 沒有這麽寫的 int *ps[3] = {&a,&b,&c}; printf("%d,%d,%d",*ps[0],*ps[1],*ps[2]); } /* 定義一個指向一維數組的指針 數據類型 (*指針名稱)[所指向的一維數組的元素個數] 指針 + 整數 === 指針中的值 + 所指向數據類型的長度 * 整數 */ int main(int argc, const char * argv[]) { int nums[3][2] = {{1,2},{3,4},{5,6}}; int (*ps)[2]; ps = nums;//能夠覺得ps 與 nums是等價的 int num = ps[0][1]; printf("%d\n",num); printf("%p\n",nums); printf("%p\n",nums+1); printf("%p\n",ps); printf("%p\n",ps+1); for (int i =0 ; i < 3; i++) { for (int j = 0; j < 2 ; j++) { printf("%d ",ps[i][j]); } printf("\n"); } // nums nums[0] // 同樣點:相應地址都是一樣的 // 不同點:指針類型是不同 // nums + 1 = nums + sizeof(nums[0]) // nums[0] + 1 = nums + sizeof(int) // sizeof(nums) 二維數組所用占用存儲空間字節數 // sizeof(nums) / sizeof(int) 二維數組中一共同擁有多少個int的數據 int *p = nums[0]; for (int i = 0; i < sizeof(nums) / sizeof(int); i++) { printf("%d ",p[i]); } return 0; }
ios學習之旅---指針也不難