什麼是指針數組
指針就就是數據的內存地址。函數
指針的做用一指針
當你須要在函數間傳遞大量數據時就用指針,由於能夠下降的內存開銷內存
指針的做用二字符串
定義指針變量的格式it
定義一個指針變量的方法編譯
Examples:ast
char *p;變量
int *q;軟件
float *r;
long double *s;
long int *t;
沒有初始化的指針
沒有初始化的指針
1.沒有初始化的指針,稱之爲野指針。
2.指針裏面是一個隨機的值。
3.野指針有很大的風險。
如何初始化一個指針?
Answer: set it to NULL
int *p;
p = NULL;
或者
p = 0;
注意:永遠不要使用一個空指針。
在C裏,使用空指針會有一個空指針錯誤。會使得程序崩潰。
如何初始化一個指針?
int a;
int *p;
p = &a;
代碼演示
*pr = *pa + *pb;
如何經過指針去訪問一個變量
For example:
p = &a;
c = *p + 43;
指針訪問內存能夠經過*這個操做符去訪問所指向的內存空間。
特別注意:
1.永遠不要返回一個指向本地變量的指針。
Why?
float *mistake()
{
float temp = 12;
return &temp;
}
指針變量所佔用的存儲空間
爲什麼指針變量要分類型?
int i = 2;
char c = 1;
int *p = &c;
printf(「%d」, *p);
指針與數組
數組名就像是一個指針
char name[] = {‘i’,’t’,’c’,’a’,’s’,’t’};
char *np = name;
那麼
name[1] == *(name +1) == *(1 + name) == 1[name]==*(np + 1) == *(1 + np) == *(np++) == np[1] == 1[np]
爲何數組下標是從0開始的?
數組是一塊連續的內存
數組元素的下標是,是該元素的位置相對與數組起始地址的偏移量
由於第一個元素的地址與數組名地址是相同的,因此偏移量是0
數組名與指針的區別
char array [] = {‘i’,’t’,’c’,’a’,’s’,’t’};
char *p = array;
sizeof(array) 返回的結果是array所佔的字節數,sizeof(p) 是 8
當使用指針變量指向一個數組的時候,數組有些信息不能經過指針,好比數組長度,這稱爲指針信息遺失。
&array = array,&p != p
數組的地址仍是數組的地址,指針的地址變量的地址不是指針變量裏存放的地址
數組變量的指向不能夠改變
指針變量就是就是用來存放地址變量,系統爲其開闢了存儲空間,因此指針變量中地址能夠任意改變,可是系統沒有數組變量分配存儲空間,當系統編譯後全部出現數組名的地方都會被替換成該數組的首地址,因此你不可該數組變量的指向。
字符串的兩種表示方式
字符數組
char name[] = 「itcast」 ;
字符指針
char *name = 「otcast」;
二者區別
使用字符數組定義的字符串,系統會把字符串中的每一個字符拷貝到字符數組中;所以你能夠變字符串中的字符
使用指針定義的字符串,系統把常量字符串的地址賦值給了char類型的指針。因此你不能經過指針改變字符串中的字符,由於字符指針指向的字符串是一個常量,是隻讀的。
系統內存分區
兩種字符串的區別
使用數組定義的字符串
該字符串存放在棧中
你能夠隨意的修改字符串中的字符
當你返回一個函數內部定義的字符數組時候,它返回的是這個數組的地址,你若在外邊使用這個地址會報錯,由於該變量在函數執行完成後比回收了。
使用字符指針定義的字符串
該字符串存放在常量區
你不可修改該字符串中的字符,由於它是隻讀的
你可使用它做爲函數的返回值,它返回的是常量的地址,由於常量是常駐內存,直到程序退出纔會被回收,因此你能夠放心使用不會報錯!
指針數組與指向數組的指針
指針數組就是數組元素爲指針的數組
定義一個指針數組格式:數據類型 * 指針數組名[元素個數]
如:int a[2][2] ={1,2,3,4}
int *ap[2] = {a[0],a[1]}
指向數組的指針就是一個指針變量,它是用來指向數組的也能夠說,它指向數據類型是數組
定義一個指向一維數組的指針
格式:數據類型 (*指針名稱)[指向的一位數組的元素個數]
如 int a[2][2] = {1,2,3,4}
int (*p)[2] = a;
注意:括號不能夠省略
指針與字符串數組
定義指針數組的兩種形式
char *name[]={"Monday", "Tuesday」}
char name[][8]={"Monday", "Tuesday」}
這兩種形式的區別是什麼呢?
指向指針的指針
所謂的指向指針的指針就是:這個指針變量中存放的地址是一個指針變量的地址;如:
int a = 10;
int *p = &a;
int **pp = &p;
咱們要訪問a中的值該怎麼辦呢?
*p 能夠訪問 a 的存儲空間,操做a變量中的值
*pp能夠訪問 p 拿到 p中存放的地址因此
**pp能夠訪問p所指向的存儲
指向指針的指針使用場景
定義一個把字符串的內容寫到文件中的函數
方式一 :
char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer desighn"};
char **p;
p = name;
p = name + 1;
使用方式二:在函數中返回一個常量字符串的地址
int writeToFile(char *conttent,char **error){
// 檢查文件是否被鎖定了
if(isLocked){
*error = 「該文件沒法寫入,它被其餘軟件佔用了」;
return 0;
}
//寫文件
}
什麼是函數指針
指向函數的指針稱爲函數指針,也就存放函數地址的變量就是函數指針變量
函數指針定義的格式
格式:
返回值類型 (*函數指針名稱) (參數類型,參數類型)
定義一個指向 int sum (int a,int b); 函數指針的步驟
首先是指針相關必就有 *
是變量就有名字 *myPoint
將要指向的函數的名左邊拷貝到左邊 int *myPoint
將要執行的函數的名右邊拷貝的右邊 int *myPoint (int a,int b)
因爲*的優先級低於()的優先級,如今這個是返回值爲int * 的函數
咱們須要給 *myPoint加上括號來提升它的優先級 int (*myPoint) (int a,int b)
(可選)函數指針能夠省略形參名稱 int (*myPoint) (int ,int )
函數指針初始化
函數名就是函數的地址,而函數指針變量就是存放函數地址的,因此能夠直接把函數名賦值給函數指針
先定義在初始化
int (myPointer)(int,int);
myPointer = sum;
定義的同時進行初始化
int (myPointer) (int,int) = sum;
如何使用函數指針
因爲函數指針存放就是函數的地址,函數名也是函數地址,因此能夠像函數名同樣使用函數指針
int s = myPointer(10,20);
你也找到函數對應的代碼來執行它,這種方式不經常使用
(*myPointer)(10,20);