一.指針的概念
-
指針是一種數據類型,被稱爲"指針類型"。指針類型描述的是一個地址,這個地址指向內存中另外一個對象的位置。簡單的說,指針表示的是它所指向對象的地址。這些地址包括變量,數組或函數。
-
C++編譯系統在編譯時會爲不同數據類型的對象分配大小不同的存儲空間。每個儲存空間都有一個固定的編號。根據這個地址即可準確找到並訪問這些儲存單元。
-
定義整數型變量:
int a=5;
----------->如何取到整數變量a的地址? -
定義整數型指針變量:
int* pInt=&a;
-
定義如下指針:
char* p="hello";
數組內存分配結構如圖所示,此時指針變 量p存儲數組的首地址。
指針和指針變量的區別
A、指針是一種新的數據類型,這種數據類型專門用來存儲內存地址。
B、XXX型指針是一種具體指針數據類型,用於描述相應數據類型的內存地址。
C、指針變量是一個變量,用於存放對應數據類型的地址值,只佔用4個字節的 大小。
相關運算符(&,*)理解
#include <iostream>
using namespace std;
void main()
{
int a=5,*p=&a;//*表示類型說明
cout<<*p<<endl;//*p表示所指向的變量a的值
system("pause");
}
二 指針的定義和賦值
指針的定義
- 使用指針變量前必須先聲明。
- 使用指針數據類型定義的變量,稱爲指針變量。用符號*表示此變量是指針變 量。
- 指針變量只能用來存放內存地址。
- 指針變量內存所佔的大小是 4個字節。
- 指針變量的定義如下三種形式(常用第一種形式)
int* ptr1 = 0; //定義int型指針變量ptr1
char* ptr2 = 0; //定義char型指針變量ptr2
int *ip1,ip2; //聲明瞭1個指針變量ip1和1個普通變量ip2
int *ip3,*ip4; //聲明瞭兩個整數型指針變量ip3,ip4
-
一次定義多個指針變量,每個指針變量前必須加“”,否則,只有前面 加“”的才能被解釋成指針。
指針的賦值 -
任何一個指針變量,可以被賦值爲空,即指針變量的值賦爲
0
或NULL
或nullptr
; 指針變量的賦值運算有6種形式
(1)指針變量初始化賦值。如int* ptr1 = 0;
。
(2)把一個變量的地址賦值給相同數據類型的指針變量(地址運算符&—>& 變量)。
int *pa;
int a;
pa = &a; //把整型變量a的地址賦予整型指針變量pa
(3)把一個指針變量的值賦值給相同數據類型的另一個指針變量。
int *pa;
int a;
pa = &a;
int* pb = pa;//把pa的地址賦予指針變量pb
cout << pa <<"\n"<< pb;
(4)把數組的首地址賦值給指向數組的指針變量。
int a[5];
int* pa = a; //數組名錶示數組的首地址,指針變量pa指向數組首地址 pa=&a[0];
(5)把字符串的首地址賦值給指向字符類型的指針變量。
const char *pc;
pc = "c language";//把字符串的首地址賦予指針變量 char *pc="c language";
(6)把函數的入口地址賦值給指向函數的指針變量。
int (*pf)();
pf=f; //f爲函數名
//示例,方便測試理解
#include <iostream>
using namespace std;
int f(int a)
{
return a;
};
int main()
{
int(*pf)(int);
pf = f; //f爲函數名
f(12);
system("pause");
}
舉例說明
- 在代碼欄輸入以下代碼,編譯查看輸出結果,注意查看兩個內存地址是否一樣:
#include <iostream>
using namespace std;
void main()
{ int a = 10;
int *p = &a;
cout<<&a<<endl;
cout<<p<<endl;
}
給指針變量賦值時需要注意:
(1)未經賦值的指針變量不能使用。
(2)指針變量的賦值只能賦予地址, 不能賦予任何其它數據。
三 指針的運算
未經賦值的指針變量不能使用。
指針只能進行賦值運算、間接引用運算、算術運算、兩個指針的相減運算和兩個 指針的比較運算
(1)賦值運算
取地址運算符& 和間接引用運算符解引用操作符 *
指針變量在使用之前必須有確定的指向。
NULL是一個指針常量,表示空地址。當指針變量暫時無法確定其指向或暫時不 用時,可以將它指向空地址,以保證程序的正常運行。
int a=0;
int* ptr1 = &a;
(2)間接引用運算
符號*也稱爲間接引用運算符,其運算結果爲該指針所指對象的值。
int a=16,b=28;
int *pa=&a,*pb; //符號*表示pa、pb是指針變量
a*=b; //符號*表示進行乘法運算
*pa=123; //符號*表示間接引用pa所指向的對象a
(3)算術運算
- 與整數的加減運算和自增、自減運算。指針變量存儲的是數據的內存地址, 因此可以將指針視爲類似整型的變量。指針加上或減去一個整數,其結果是一個 新的地址值。
- 指針加上或減去一個整數n,表示指針從當前位置向後或向前移動n*sizeof< 數據類型>大小的地址空間。
int a=16;
int* pa=&a;
int *p1,*p2;
p1=pa+3;
p2=pa-2;
//變量a分配的首地址是0066FDF4,則p1=&a+3*sizeof(int)= 0066FDF4+3*4=0066FE00。同理p2=&a-2*sizeof(int)=0066FDF4- 2*4=0066FDEC。
如下圖所示:
- 指針的自增或自減表示指針從當前位置向後或向前移動sizeof(數據類型) 大小的地址空間。
(4)兩指針相減 - 當兩個指針指向同一數組時,兩個指針的相減纔有意義。兩個指針相減的結 果是一個整數,表示兩個指針之間數組元素的個數。
int a[10];
int* p1=&a[1]; //p1指向a[1]
int* p2=&a[6]; //p2指向a[6]
int b=p2-p1; // b=5
(5)兩個指針的比較運算
- 當兩個指針指向同一個數組時,兩個指針比較大小纔有意義。 兩指針變量可以進行關係運算。
#include <iostream>
using namespace std;
//pf1 == pf2 表示pf1和pf2指向同一數組元素;
//pf1 > pf2 表示pf1處於高地址位置;
//pf1 < pf2 表示pf1處於低地址位置。
#include <iostream>
using namespace std;
void main() {
int a[10];
int* p1 = &a[1]; //p1指向a[1]
int* p2=&a[6]; //p2指向a[6]
if (p1 == p2)
{
cout<<"=="<<endl;
}
else
{
cout << "!=" << endl;
}
system("pause");
}
- 指針變量還可以與0比較,判斷指針是否爲空指針。
- p==0:表明p是空指針,表示它不指向任何變量;
- p!=0:表示p不是空指針。
- 指針變量爲0和指針變量未賦值是不同的概念。
- 直接與0進行比較,判斷是否爲空指針,常用來內存是否分配成功以及 函數 入參檢測。