C++ 指針

2018-03-24 14:13 更新

學習C++ - C++指針

以下代碼使用&運算符來查找地址。


#include <iostream> 
using namespace std; 
int main() 
{ 
     int donuts = 6; 
     double cups = 4.5; 

     cout << "donuts value = " << donuts; 
     cout << " and donuts address = " << &donuts << endl; 

     cout << "cups value = " << cups; 
     cout << " and cups address = " << &cups << endl; 
     return 0; 
} 

上面的代碼生成以下結(jié)果。


例子

指針的名稱代表位置。

應(yīng)用*運算符在該位置產(chǎn)生值。


#include <iostream> 
int main() 
{ 
     using namespace std; 
     int updates = 6;        // declare a variable 
     int * p_updates;        // declare pointer to an int 
     p_updates = &updates;   // assign address of int to pointer 

     // express values two ways 
     cout << "Values: updates = " << updates; 
     cout << ", *p_updates = " << *p_updates << endl; 

     // express address two ways 
     cout << "Addresses: &updates = " << &updates; 
     cout << ", p_updates = " << p_updates << endl; 

     // use pointer to change value 
     *p_updates = *p_updates + 1; 
     cout << "Now updates = " << updates << endl; 
     return 0; 
} 

上面的代碼生成以下結(jié)果。

聲明和初始化指針

指針聲明必須指定指針指向什么類型的數(shù)據(jù)。

例如,前面的例子有這個聲明:

int * p_updates;

這表示組合* p_updates是int類型。

p_updates變量本身必須是一個指針。

p_updates指向類型int。

p_updates的類型是指向int的指針,更簡明地,int *。

p_updates是一個指針(地址),*p_updates是一個int而不是一個指針。

int*是一個類型,指向int。

以下聲明創(chuàng)建一個指針(p1)和一個普通的int(p2):

int* p1, p2;

每個指針變量名稱需要一個*。

以下代碼演示如何初始化指向地址的指針。


#include <iostream> 
using namespace std; 
int main() 
{ 
     int higgens = 5; 
     int * pt = &higgens; 

     cout << "Value of higgens = " << higgens 
           << "; Address of higgens = " << &higgens << endl; 
     cout << "Value of *pt = " << *pt 
           << "; Value of pt = " << pt << endl; 
     return 0; 
} 

上面的代碼生成以下結(jié)果。

用新的分配內(nèi)存

這是一種用于獲取和分配單個數(shù)據(jù)對象的內(nèi)存的一般形式,它可以是一個結(jié)構(gòu)以及一個基本類型,它是:

typeName * pointer_name = new typeName;

您使用數(shù)據(jù)類型兩次:一次指定所請求的內(nèi)存種類,一次聲明一個合適的指針。


#include <iostream> 
using namespace std; 
int main() 
{ 
     int nights = 1001; 
     int * pt = new int;         // allocate space for an int 
     *pt = 1001;                 // store a value there 

     cout << "nights value = "; 
     cout << nights << ": location " << &nights << endl; 
     cout << "int "; 
     cout << "value = " << *pt << ": location = " << pt << endl; 
     double * pd = new double;   // allocate space for a double 
     *pd = 10000001.0;           // store a double there 

     cout << "double "; 
     cout << "value = " << *pd << ": location = " << pd << endl; 
     cout << "location of pointer pd: " << &pd << endl; 
     cout << "size of pt = " << sizeof(pt); 
     cout << ": size of *pt = " << sizeof(*pt) << endl; 
     cout << "size of pd = " << sizeof pd; 
     cout << ": size of *pd = " << sizeof(*pd) << endl; 
     return 0; 
} 

上面的代碼生成以下結(jié)果。

通過刪除釋放內(nèi)存

刪除操作符使您能夠?qū)?nèi)存返回到內(nèi)存池。

你可以使用delete來跟蹤一個指向最初分配給新的內(nèi)存塊的指針:

int * ps = new int; // allocate memory with new 
. . .               // use the memory 
delete ps;          // free memory with delete when done 

這將刪除ps點的內(nèi)存。

它不會刪除指針ps本身。

您可以重用ps來指向另一個新的分配。

你不應(yīng)該嘗試釋放先前釋放的內(nèi)存塊。

使用new創(chuàng)建動態(tài)數(shù)組

在C++中創(chuàng)建動態(tài)數(shù)組很容易;你要告訴新數(shù)組元素的類型和你想要的元素數(shù)目。

語法要求您使用括號中的元素數(shù)量來遵循類型名稱。

例如,如果你需要一個10 int的數(shù)組,你可以使用:

int*psome = new int[10]; //獲取10個int的塊

new運算符返回塊的第一個元素的地址。

在此示例中,該值分配給指針psome。

使用新增括號創(chuàng)建數(shù)組時,需要在釋放數(shù)組時使用替代形式的delete:

delete [] psome;                  // free a dynamic array 

括號告訴C++釋放整個數(shù)組,而不僅僅是指針指向的元素。

這里舉個例子:

int * pt = new int; 
short * ps = new short [500]; 
delete [] pt;  // effect is undefined, don"t do it 
delete ps;     // effect is undefined, don"t do it 

不要使用delete來釋放新的沒有分配的內(nèi)存。

不要使用delete來連續(xù)釋放同一塊內(nèi)存兩次。

如果您使用new []來分配數(shù)組,請使用delete []。

如果您使用新的分配單個實體,請使用delete(無括號)。

分配和分配數(shù)組的內(nèi)存的一般形式是:

type_name * pointer_name = new type_name [num_elements]; 

例子


#include <iostream> 
using namespace std; 
int main() { 
     
     double * p3 = new double [3]; // space for 3 doubles 
     p3[0] = 0.2;                  // treat p3 like an array name 
     p3[1] = 0.5; 
     p3[2] = 0.8; 
     cout << "p3[1] is " << p3[1] << ".\n"; 
     p3 = p3 + 1;                  // increment the pointer 
     cout << "Now p3[0] is " << p3[0] << " and "; 
     cout << "p3[1] is " << p3[1] << ".\n"; 
     p3 = p3 - 1;                  // point back to beginning 
     delete [] p3;                 // free the memory 
     return 0; 
} 

上面的代碼生成以下結(jié)果。

指針,數(shù)組和指針算術(shù)

C++將數(shù)組名解釋為地址。


#include <iostream> 
using namespace std; 
int main() { 
     double wages[3] = {1.0, 2.0, 3.0}; 
     short stacks[3] = {3, 2, 1}; 

     // two ways to get the address of an array 
     double * pw = wages;     // name of an array = address 
     short * ps = &stacks[0]; // or use address operator 
     
     // with array element 
     cout << "pw = " << pw << ", *pw = " << *pw << endl; 
     pw = pw + 1; 
     //add 1 to the pw pointer 
     cout << "pw = " << pw << ", *pw = " << *pw << "\n\n"; 
     cout << "ps = " << ps << ", *ps = " << *ps << endl; 
     ps = ps + 1; 
     
     //add 1 to the ps pointer
     cout << "ps = " << ps << ", *ps = " << *ps << "\n\n"; 

     //access two elements with array notation
     cout << "stacks[0] = " << stacks[0] 
          << ", stacks[1] = " << stacks[1] << endl; 
     //access two elements with pointer notation
     cout << "*stacks = " << *stacks 
          << ", *(stacks + 1) =  " << *(stacks + 1) << endl; 

     cout << sizeof(wages) << " = size of wages array\n"; 
     cout << sizeof(pw) << " = size of pw pointer\n"; 
     return 0; 
} 

上面的代碼生成以下結(jié)果。

指針和字符串

數(shù)組和指針之間的特殊關(guān)系擴展到C風格的字符串。請考慮以下代碼:

char flower[10] = "rose"; 
cout << flower << "s are red\n"; 

數(shù)組的名稱是其第一個元素的地址。

以下代碼使用字符串庫中的兩個函數(shù)。

strlen()函數(shù)返回字符串的長度。

strcpy()函數(shù)將字符串從一個位置復制到另一個位置。


#include <iostream> 
#include <cstring>              // declare strlen(), strcpy() 
using namespace std; 

int main() { 
     char animal[20] = "C++";   // animal holds bear 
     const char * bird = "Java"; // bird holds address of string 
     char * ps;                  // uninitialized 

     cout << animal << " and ";  // display bear 
     cout << bird << "\n";       // display wren 

     cout << "Enter a kind of animal: "; 
     cin >> animal;              // ok if input < 20 chars 

     ps = animal;                // set ps to point to string 
     cout << ps << "!\n";       // ok, same as using animal 

     //Before using strcpy()
     cout << animal << " at " << (int *) animal << endl; 
     cout << ps << " at " << (int *) ps << endl; 

     ps = new char[strlen(animal) + 1];  // get new storage 
     strcpy(ps, animal);         // copy string to new storage 
     cout << "After using strcpy():\n"; 
     cout << animal << " at " << (int *) animal << endl; 
     cout << ps << " at " << (int *) ps << endl; 
     delete [] ps; 
     return 0; 
} 

上面的代碼生成以下結(jié)果。

例3

以下代碼使用new創(chuàng)建一個未命名的結(jié)構(gòu),并演示訪問結(jié)構(gòu)成員的兩個指針符號。


#include <iostream> 
using namespace std; 
struct Product   // structure definition 
{ 
     char name[20]; 
     float volume; 
     double price; 
}; 
int main() {      
     Product * ps = new Product; // allot memory for structure 
     cout << "Enter name of Product item: "; 
     cin.get(ps->name, 20);            // method 1 for member access 
     cout << "Enter volume in cubic feet: "; 
     cin >> (*ps).volume;              // method 2 for member access 
     cout << "Enter price: $"; 
     cin >> ps->price; 
     cout << "Name: " << (*ps).name << endl;              // method 2 
     cout << "Volume: " << ps->volume << " cubic feet\n"; // method 1 
     cout << "Price: $" << ps->price << endl;             // method 1 
     delete ps;                        // free memory used by structure 
     return 0; 
} 

上面的代碼生成以下結(jié)果。

例4

以下代碼顯示如何使用delete操作符。


#include <iostream> 
#include <cstring>      // or string.h 
using namespace std; 
char * getname(void);   // function prototype 
int main() { 
     char * name;        // create pointer but no storage 

     name = getname();   // assign address of string to name 
     cout << name << " at " << (int *) name << "\n"; 
     delete [] name;     // memory freed 

     name = getname();   // reuse freed memory 
     cout << name << " at " << (int *) name << "\n"; 
     delete [] name;     // memory freed again 
     return 0; 
} 
char * getname()        // return pointer to new string 
{ 
     char temp[80];      // temporary storage 
     cout << "Enter last name: "; 
     cin >> temp; 
     char * pn = new char[strlen(temp) + 1]; 
     strcpy(pn, temp);   // copy string into smaller space 

     return pn;          // temp lost when function ends 
} 

上面的代碼生成以下結(jié)果。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號