指針
指針常量:和地址常量相同 指針變量:用來存儲指針常量
指針:通常將指針常量和指針變量統稱為指針
以字節為單位將內存進行劃分,沒一個字節的空間都有一個地址編號首地址:某一段空間的 第一個地址編號
指針永遠為4個字節指針的一般形式:
數據類型 *指針變量名例如:int a = 10;
int *p =&a;
p:存儲a這段空間首地址的變量 &a:a這段空間的首地址取地址符:&
取值符號:*
取值符號和取地址符互為逆運算初始化: int *p;
野指針:指針隨機指向某一段空間; 操作野指針可能會出現段錯誤int *p=NULL;
空指針:指針指向地址編號為0的那一段空間。 操作空指針一定會出現段錯誤如何調試段錯誤
gdb調試工具
gcc -g 文件名.c gdb ./a.out
r(run)執行文件
q退出指針運算
p+1:會發生指針偏移,偏移的是所指向數據的數據類型p++ ++p p p
p>q:一般情況下運用在某一段連續的空間
p-q:一般情況下也是運用在某一段連續的空間才有意義
查詢內存的保存形式(大端存儲或小端存儲) #include
int main(int argc ,congst char *argv[] )
{
int a = 0x12345678; int *p = &a;
printf("%#d\n",(char)*p); return 0;
}
輸出:0x78 說明計算機內存是小端存儲。
指針和數組的關系
int a[3] ={1,2,3}; 數組名:
a: 1、代表整個數組
2、數組名是一個地址常量,是數組所在內存空間的首地址
一級數組內部關系:
int a[3]={1,2,3};
a = &a[0]; a+1=&a[0]+1=&a[1];
*(a+1)=*(&a[1])=a[1];
結論: *(a+n)= a[n];
一維數組和一級指針的關系int *p=a; p+1=a+1=&a[0]+1=&a[1];
*(p+1)=*(a+1)=*(&a[0]+1)=*(&a[1])=a[1];
*(p+1)=p[1];
結論:*(p+n)=*(a+n)=a[n]=p[n];
二維數組內部關系
int a[2][3]={{1,2,3},{4,5,6}};
a=&a[0]; a+1=&a[0]+1=&a[1];
*(a+1)=*(&a[0]+1)=*(&a[1])=a[1]
將a[1]看做一個一維數組的數組名a[1] = &a[1][0]
a[1] + 1 = &a[1][0] + 1 = &a[1][1]
*(a[1] + 1) = *(&a[1][0] + 1) = *(&a[1][1])
*(a[1] + 1) = a[1][1]
*(*(a + 1) + 1) = a[1][1]
結論: *(*(a + i) + j) = a[i][j]
二維數組和數組指針的關系
int a[2][3];
int (*p)[3]=a;
p + 1 = a + 1 = (&a[0] + 1) = &a[1]
*(p + 1) = *(a + 1) = *(&a[0] + 1) = *(&a[1]) = a[1] = p[1] p[1] + 1= a[1] + 1 = &a[1][0] + 1 = &a[1][1]
*(p[1] + 1) = *(a[1] + 1) = *(&a[1][0] + 1) = *(&a[1][1])
*(p[1] +1) = *(a[1] + 1) = a[1][1]
結論:*(*(p+i)+j)=*(*(a+i)+j)=a[i][j]=p[i][j]
#include
{
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1); int *ptr2=(int *)((int)a+1);
printf("%x,%x",ptr1[-1],*ptr2); return 0;
}
輸出結果:5,2000000
字符指針
字符指針可以用來接受字符串,其實是接收字符串的首地址,但是不可以通過*的方式去修改,否則會發生段錯誤。
指針習題
程序:
輸出: