1、變數的儲存
(1)記憶體是一塊空間,把其中的每個位元組做了編號,為了以後電腦能通過編號找到資料
(2)編址方式:絕對編址(在整個程式中使用),相對編址(位元組相對於邏輯0位移量,在進程中使用)
2、取變數地址
(1)"&" &i 表示取記憶體中i的地址
地址的編址用十六進位表示
(2)邏輯0在代碼區
全域變數在資料區,地址的編址是大於0的
局部變數在棧區,地址的編址是小於0的
3、數組、結構的地址
(1)數組中的資料在記憶體中是連續儲存的。 數組中每個元素的地址相差的值應為數組元素類型的大小。
(2)結構的地址:
結構的空間是連續的。
結構的起始地址與第一個成員變數的地址是一樣的。
4、儲存地址—
指標:儲存變數的地址
指標的類型由將要儲存的地址的變數類型決定
int*只能儲存int變數的地址
指標賦值一定要是同類型的指標才能相互賦值!
5、指標的運算
(1)指標和指標之間的運算
“+”,“*”,“/” 指標與指標間是不能做這些運算,沒有意義!
“-” 可以做減法運算,以“sizeof(指標類型)”作為計算單位的! 注意:要同類型的指標才能做此運算,不同的話,會對運算單位產生歧義。
(2)指標和數字之間的運算(加、減都可以)
int i = 100;
int * p = &i;
列印 p+1 -> 相當於在地址上加4,因為儲存的變數是int類型的
p+2 -> 相當於在地址上加8
6、通過指標訪問所指向的變數
*p 代表指標p所指向的變數 *p <=> i
指標在聲明的時候,即初始化
int * p = NULL; 表示沒有明確指向,不能 *p ,會出現 “段錯誤”的異常 -->null 指標
段錯誤原因 (1)null 指標
(2)數組越界
(3)遞迴的條件不正確
7、課堂練習
用指標列印出數組中個元素的值
#include <iostream> using namespace std; int main(){ int ai[6]={34,4,12,67,34,2}; int *p = &ai[0]; for(int i = 0 ; i < 6 ; i++){ cout <<"a[" << i << "]=" <<*(p+i) << endl; } return 0; }
int *p = ai ; 數組的本質就是用指標實現的,數組的名字就代表數組的首地址(起始地址) 數組的名字是指向數組首地址(a[0])的指標 ai 數組名,就是指向數組首地址的指標,可以用下標取元素,也可以把數組名當指標來訪問元素 *(ai+n) p 指標名,也是指向首地址的指標,也可以通過下標(像數組名一樣)訪問數組元素 p[n] <=> *(p+n)
8、結構指標
struct person{ int id; int age; } int main(){ person per = {1,20}; person* p = &per; cout << "per.id ="<<per.id<<endl; //通過結構名取成員變數 cout << "per.age=" << per.age <<endl; cout <<"======================"<<endl; cout << "(*P).id=" << (*P).id <<endl; //通過指標訪問結構的成員變數 cout << "(*P).age=" << (*P).age <<endl; // (*p).id <=> p->id 只有結構指標可以這樣使用 cout <<"======================"<<endl; cout << "p->id=" << p->id <<endl; cout << "p->age=" << p->age <<endl; return 0; }
9、指標的地址
指標變數在記憶體中佔4個位元組(與類型無關,因為儲存地址的指標只儲存地址)
儲存int型指標(int* p = &i)的地址用int**儲存(int** pp = &p)
#include <iostream> using namespace std; int main(){ int i = 0 ; int * p = &i ; int ** pp = & p ; cout<<"&i = " << &i << endl; cout<<"p = " << p << endl; cout<<"&p = " << &p << endl; cout<<"pp = " << pp << endl; cout<<"&pp = " << &pp << endl; cout<<"i = " <<i << endl; cout<<"*p = " << *p << endl; cout<<"*pp = " << *pp << endl; cout<<"**pp = " << **pp << endl; return 0 ; }
執行結果:
&i = 0xffbffbecp = 0xffbffbec&p = 0xffbfbe8pp = 0xffbfbe8&pp = 0xffbffbe4i = 0*p = 0*pp = 0xffbffbec**pp = 0
pp -> p -> i 指向關係
pp=&p p=&i
*pp=p *p=i **pp=*p=i