c++ 指针(一)
指針
每一個變量都有一個內存位置,每一個內存位置都定義了可使用連字號(&)運算符訪問的地址,它表示了在內存中的一個地址
#include <iostream>
using namespace std;
int main ()
{
int var1;
char var2[10];
cout << "var1 變量的地址: ";
cout << &var1 << endl;
cout << "var2 變量的地址: ";
cout << &var2 << endl;
return 0;
}
結果:
var1 變量的地址: 0xbfebd5c0 var2 變量的地址: 0xbfebd5b6
一、定義
指針是一個變量,其值為另一個變量的地址,即,內存位置的直接地址。就像其他變量或常量一樣,您必須在使用指針存儲其他變量地址之前,對其進行聲明。
type *var-name;
星號是用來指定一個變量是指針
int *ip; /* 一個整型的指針 */ double *dp; /* 一個 double 型的指針 */ float *fp; /* 一個浮點型的指針 */ char *ch; /* 一個字符型的指針 */
所有指針的值的實際數據類型,不管是整型、浮點型、字符型,還是其他的數據類型,都是一樣的,都是一個代表內存地址的長的十六進制數。
不同數據類型的指針之間唯一的不同是,指針所指向的變量或常量的數據類型不同
二、使用
使用指針時會頻繁進行以下幾個操作:定義一個指針變量、把變量地址賦值給指針、訪問指針變量中可用地址的值。這些是通過使用一元運算符 * 來返回位于操作數所指定地址的變量的值。
#include <iostream>
using namespace std;
int main ()
{
int var = 20; // 實際變量的聲明
int *ip; // 指針變量的聲明
ip = &var; // 在指針變量中存儲 var 的地址
cout << "Value of var variable: ";
cout << var << endl;
// 輸出在指針變量中存儲的地址
cout << "Address stored in ip variable: ";
cout << ip << endl;
// 訪問指針中地址的值
cout << "Value of *ip variable: ";
cout << *ip << endl;
return 0;
}
結果:
Value of var variable: 20 Address stored in ip variable: 0xbfc601ac Value of *ip variable: 20
三、指針詳解
| C++ Null 指針 | C++ 支持空指針。NULL 指針是一個定義在標準庫中的值為零的常量。 |
| C++ 指針的算術運算 | 可以對指針進行四種算術運算:++、--、+、- |
| C++ 指針 vs 數組 | 指針和數組之間有著密切的關系。 |
| C++ 指針數組 | 可以定義用來存儲指針的數組。 |
| C++ 指向指針的指針 | C++ 允許指向指針的指針。 |
| C++ 傳遞指針給函數 | 通過引用或地址傳遞參數,使傳遞的參數在調用函數中被改變。 |
| C++ 從函數返回指針 | C++ 允許函數返回指針到局部變量、靜態變量和動態內存分配。 |
(1)Null 指針
在變量聲明的時候,如果沒有確切的地址可以賦值,為指針變量賦一個 NULL 值是一個良好的編程習慣。賦為 NULL 值的指針被稱為空指針。
NULL 指針是一個定義在標準庫中的值為零的常量
#include <iostream>
using namespace std;
int main ()
{
int *ptr = NULL;
cout << "ptr 的值是 " << ptr ;
return 0;
}
ptr 的值是 0 // NULL = 0
在大多數的操作系統上,程序不允許訪問地址為 0 的內存,因為該內存是操作系統保留的。然而,內存地址 0 有特別重要的意義,它表明該指針不指向一個可訪問的內存位置。但按照慣例,如果指針包含空值(零值),則假定它不指向任何東西。
如需檢查一個空指針,您可以使用 if 語句
if(ptr) /* 如果 ptr 非空,則完成 */ if(!ptr) /* 如果 ptr 為空,則完成 *
如果所有未使用的指針都被賦予空值,同時避免使用空指針,就可以防止誤用一個未初始化的指針。很多時候,未初始化的變量存有一些垃圾值,導致程序難以調試。
(2)算術運算
指針是一個用數值表示的地址。因此,您可以對指針執行算術運算。可以對指針進行四種算術運算:++、--、+、-。
假設 ptr 是一個指向地址 1000 的整型指針,是一個 32 位的整數
ptr++
ptr 將指向位置 1004,因為 ptr 每增加一次,它都將指向下一個整數位置,即當前位置往后移 4 個字節。這個運算會在不影響內存位置中實際值的情況下,移動指針到下一個內存位置。如果 ptr 指向一個地址為 1000 的字符,上面的運算會導致指針指向位置 1001,因為下一個字符位置是在 1001。
A. 遞增一個指針
我們喜歡在程序中使用指針代替數組,因為變量指針可以遞增,而數組不能遞增,因為數組是一個常量指針。下面的程序遞增變量指針,以便順序訪問數組中的每一個元素:
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指針中的數組地址
ptr = var;
for (int i = 0; i < MAX; i++)
{
cout << "Address of var[" << i << "] = ";
cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 移動到下一個位置
ptr++;
}
return 0;
}
Address of var[0] = 0xbfa088b0 Value of var[0] = 10 Address of var[1] = 0xbfa088b4 Value of var[1] = 100 Address of var[2] = 0xbfa088b8 Value of var[2] = 200
B. 遞減一個指針
對指針進行遞減運算,即把值減去其數據類型的字節數
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指針中最后一個元素的地址
ptr = &var[MAX-1];
for (int i = MAX; i > 0; i--)
{
cout << "Address of var[" << i << "] = ";
cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 移動到下一個位置
ptr--;
}
return 0;
}
Address of var[3] = 0xbfdb70f8 Value of var[3] = 200 Address of var[2] = 0xbfdb70f4 Value of var[2] = 100 Address of var[1] = 0xbfdb70f0 Value of var[1] = 10
C. 指針的比較
可以用關系運算符進行比較,如 ==、< 和 >。如果 p1 和 p2 指向兩個相關的變量,比如同一個數組中的不同元素,則可對 p1 和 p2 進行大小比較
下面的程序修改了上面的實例,只要變量指針所指向的地址小于或等于數組的最后一個元素的地址 &var[MAX - 1],則把變量指針進行遞增:
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指針中第一個元素的地址
ptr = var;
int i = 0;
while ( ptr <= &var[MAX - 1] )
{
cout << "Address of var[" << i << "] = ";
cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 指向上一個位置
ptr++;
i++;
}
return 0;
}
Address of var[0] = 0xbfce42d0 Value of var[0] = 10 Address of var[1] = 0xbfce42d4 Value of var[1] = 100 Address of var[2] = 0xbfce42d8 Value of var[2] = 200
補充:
指針指向數組的時候,不可以加 &:
#include <iostream>
using namespace std;
int main()
{
int var[5] = {1,2,3,4,5}; // 實際變量的聲明
int *ip; // 指針變量的聲明
ip = &var; // 在指針變量中存儲 var 的地址
cout << "Value of var variable: ";
cout << var << endl;
// 輸出在指針變量中存儲的地址
cout << "Address stored in ip variable: ";
cout << ip << endl;
// 訪問指針中地址的值
cout << "Value of *ip variable: ";
*ip = 30;
cout << *ip << endl;
cout << var << endl;
system("pause");
return 0;
}
指針指向數組中某一元素時要用 &。
#include <iostream>
using namespace std;
int main()
{
int var[5] = {1,2,3,4,5}; // 實際變量的聲明
int *ip;
// 指針變量的聲明
int *ip_1;
//ip = &var;
//指針指向數組的時候不用 “&”取址符
//ip = &var[2]
//指針指向數組某一元素時要用 “&”取址符
ip = var;
// 在指針變量中存儲 var 的地址
ip_1 = &var[2];
// 在指針變量中存儲 var[2] 的地址
cout << "Value of var variable: ";
cout << var << endl;
// 輸出在指針變量中存儲的地址
cout << "Address stored in ip variable: ";
cout << ip << endl;
// 訪問指針中地址的值
cout << "Value of *ip variable: ";
*ip = 30;
cout << *ip << endl;
cout << " " << var << endl;
// 打印指針指向數組的某一元素的值
cout << "Value of *ip_1 variable:";
cout << *ip_1 << endl;
// system("pause");
return 0;
}
(3)指針和數組的關系
指針和數組在很多情況下是可以互換的。例如,一個指向數組開頭的指針,可以通過使用指針的算術運算或數組索引來訪問數組
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指針中的數組地址
ptr = var;
for (int i = 0; i < MAX; i++)
{
cout << "var[" << i << "]的內存地址為 ";
cout << ptr << endl;
cout << "var[" << i << "] 的值為 ";
cout << *ptr << endl;
// 移動到下一個位置
ptr++;
}
return 0;
}
var[0]的內存地址為 0x7fff59707adc var[0] 的值為 10 var[1]的內存地址為 0x7fff59707ae0 var[1] 的值為 100 var[2]的內存地址為 0x7fff59707ae4 var[2] 的值為 200
然而,指針和數組并不是完全互換的
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
for (int i = 0; i < MAX; i++)
{
*var = i; // 這是正確的語法
var++; // 這是不正確的
}
return 0;
}
把指針運算符 * 應用到 var 上是完全可以的,但修改 var 的值是非法的。這是因為 var 是一個指向數組開頭的常量,不能作為左值。
由于一個數組名對應一個指針常量,只要不改變數組的值,仍然可以用指針形式的表達式。
例如:把 var[2] 賦值為 500
*(var + 2) = 500;
#include <iostream>
using namespace std;
int main ()
{
int var[3] = {10,100,200};
int *p=var;
for (int i = 0; i < 3; i++)
{
cout << *(var++) << endl; //編譯錯誤,因為var是數組名(也是數組首元素地址),不是一個變量,不可修改其值
cout << *(var+i) << endl; //編譯正確,因為沒有對var進行賦值,只是通過與i相加訪問變量地址
cout<< *(p++)<<endl; ///編譯正確,p為指針變量可賦值
}
return 0;
}
00DBFD04 10 0 0 00DBFD04 00DBFD04 1 1 00DBFD08 00DBFD04 2 2 00DBFD0C 00DBFD04
經過實驗確實如此我在教程中的實例里發現, ptr=var; 這句話改為 ptr=&var[0]; 也可以,經過實驗確實如此
#include <iostream>
using namespace std;
const int MAX=3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr=NULL;
ptr=var; //這句話改為"ptr=&var[0];"也可以
for(int i=0; i<3; i++)
{
cout << "var[" << i << "]的值為:" << *ptr << ",內存地址為:" << ptr << endl;
ptr++; //移到下一個位置
}
system("pause");
return 0;
}
總結
- 上一篇: matlab神经网络多分类(模式识别神经
- 下一篇: 全球酷站秀:10个精美的国外购物网站设计