2.3 指針大小
l 使用sizeof()測量指針的大小,得到的總是:4或8
l sizeof()測的是指針變量指向存儲地址的大小
l 在32位平台,所有的指針(地址)都是32位(4字節)
l 在64位平台,所有的指針(地址)都是64位(8字節)
int *p1;
int **p2;
char *p3;
char **p4;
printf("sizeof(p1) = %d\n", sizeof(p1));
printf("sizeof(p2) = %d\n", sizeof(p2));
printf("sizeof(p3) = %d\n", sizeof(p3));
printf("sizeof(p4) = %d\n", sizeof(p4));
printf("sizeof(double *) = %d\n", sizeof(double *));
7.2.4 野指針和空指針
指針變量也是變量,是變量就可以任意賦值,不要越界即可(32位為4字節,64位為8字節),但是,任意數值賦值給指針變量沒有意義,因為這樣的指針就成了野指針,此指針指向的區域是未知(操作系統不允許操作此指針指向的內存區域)。所以,野指針不會直接引發錯誤,操作野指針指向的內存區域才會出問題。
int a = 100;
int *p;
p = a; //把a的值賦值給指針變量p,p為野指針, ok,不會有問題,但沒有意義
p = 0x12345678; //給指針變量p賦值,p為野指針, ok,不會有問題,但沒有意義
*p = 1000; //操作野指針指向未知區域,內存出問題,err
但是,野指針和有效指針變量保存的都是數值,為了標志此指針變量沒有指向任何變量(空閑可用),C語言中,可以把NULL賦值給此指針,這樣就標志此指針為空指針,沒有任何指針。
NULL是一個值為0的宏常量:
7.2.5萬能指針void *
void *指針可以指向任意變量的內存空間:
void *p = NULL;
int a = 10;
p = (void *)&a; //指向變量時,最好轉換為void *
//使用指針變量指向的內存時,轉換為int *
*( (int *)p ) = 11;
printf("a = %d\n", a);
7.2.6 const修飾的指針變量
int a = 100;
int b = 200;
//指向常量的指針
//修飾*,指針指向內存區域不能修改,指針指向可以變
const int *p1 = &a; //等價於int const *p1 = &a;
//*p1 = 111; //err
p1 = &b; //ok
//指針常量
//修飾p1,指針指向不能變,指針指向的內存可以修改
int * const p2 = &a;
//p2 = &b; //err
*p2 = 222; //ok
指針
指針的定義和使用:
1、指針:是一種數據類型 指針變量也是一種變量
2、指針格式: 對應的數據類型 * p:指針類型變量 用來指向一個變量的地址
3、通過指針修改變量的值
*p = 200;
4、指針類型在內存中的大小 : 在32位操作系統中所有指針大小都是4個字節大小
打印指針內存大小格式: sizeof(int *) || sizeof(p)
5、內存按照 unsignned int 為每個一個內存分配編號
6、講解:
①定義變量 int a =10; 數值10 存在內存 為a開辟的空間中 a的地址為0xff00
②定義指針 int * p = &a 指針變量p 在內存中存貯的是 a的地址 0xff00,指針變量p 在內存中的大小在32位系統中都是4個字節大小
③*p = 200 通過操作指針變量p 所存儲的 a的地址 來改變a的值
④指針p 有一個自己的內存地址 指針p地址 與 定義變量a的地址 0xff00不同
野指針、空指針與 萬能指針
1、野指針:野指針是指向一個未知的內存空間,可能在讀寫的時候出現錯誤。
0-255都是系統保留的 不可以讀,不可以寫
2、空指針 沒有指向任何的地址(其指向0的地址)
空制指針就是指向內存編號為零的空間,操作該內存空間會報錯,一般情況空指針用於程序條件判斷
3、萬能指針:void * 指針可以指向任意變量的內存空間
const修飾指針
1.通過指針修改const修飾的常量
const int a = 10;
int *p += &a;
*p = 100;
a =100;
可以通過1級指針修改一個常量的值
2.const修飾指針類型 int * 不能改變指針變量指向的內存地址的值 但是可以改變指針指向的地址
const int *p = &a
p=&b
*p = 100
可以改變指針指向的地址
3.const修飾指針變量 能改變指針指向地址的值,但不能改變指針指向的地址
int * const p = &a;
*p = 100;
p=&b
可以修改指針指向地址的值
4.const修飾指針類型修飾指針變量 不能改變指針指向的的值 也不能改變指針指向的地址
const int * const *p = &a;
*p =100;
p = &b;
指針和數組、指針運算:
1、數組名是數組的首地址,這是一個常量
2、指向數組的指針
格式int arr [10] = { 0 } ;
int * p = arr;
當操作指針的時候 間接操作了數組 arr[i] = p[i];
3、指針的降級操作 ,取當前地址的值:p[5]、*p
4、對指向數組的指針進行加減操作,可能會導致數組下標越界 。
5、相同的類型的指針相減 結果是兩個指針相差的長度
區別:數組名通過sizeof可以求出數組大小,指針只包含數組的首地址信息
課后練習題:輸入格式:【 空格 你好 空格 】輸出格式為【你好】
指針數組
1、存儲char *類型的地址數組
char * arr[] ={"hello","world","niao","baobei"};
2、指針數組,它是數組,數組的每個元素都是指針類型。
多級指針:
1、如果二級指針前面加一個* 代表一級指針的值
2、二級指針前面加** 代表指針指向一級指針指向地址的值,加*降維度
3、如果n級指針在前面加n個*就是指針指向一級指針指向地址的值